mirror of
https://github.com/ocornut/imgui.git
synced 2026-07-06 17:45:24 +00:00
Compare commits
995 Commits
v1.91.3-do
...
v1.92.2b-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f7f1f54af | ||
|
|
160e3683ab | ||
|
|
45acd5e0e8 | ||
|
|
774ddb58bd | ||
|
|
4dee11a089 | ||
|
|
43e3ac0dc6 | ||
|
|
02f654cbce | ||
|
|
e1baadba84 | ||
|
|
e2a662eed8 | ||
|
|
e1a93805db | ||
|
|
af920e1e6f | ||
|
|
863e989c25 | ||
|
|
031a18c417 | ||
|
|
2b24f5fa71 | ||
|
|
e10300ed3c | ||
|
|
104f58fc48 | ||
|
|
5a6fa33b88 | ||
|
|
8239a0e0c4 | ||
|
|
50115596dc | ||
|
|
1c57dc21c2 | ||
|
|
47c41483bd | ||
|
|
ea075ed973 | ||
|
|
b431114194 | ||
|
|
cbf9e3f554 | ||
|
|
b6614f6c7c | ||
|
|
9ee3d731b5 | ||
|
|
e7d0ad092c | ||
|
|
412daf7362 | ||
|
|
c22af8c346 | ||
|
|
1bf41a0762 | ||
|
|
284283615b | ||
|
|
d163e20f63 | ||
|
|
f7eae45ae9 | ||
|
|
ff2dfc8422 | ||
|
|
7e701c18c8 | ||
|
|
90025a62c7 | ||
|
|
902b8cc39a | ||
|
|
70cfc02811 | ||
|
|
250bd66b76 | ||
|
|
c14d83d4e0 | ||
|
|
7d5fef8642 | ||
|
|
22fe9fce4c | ||
|
|
eda70b4e1a | ||
|
|
23c9362550 | ||
|
|
320c94bfaa | ||
|
|
3ef6c8410a | ||
|
|
cc1fbcc9a9 | ||
|
|
78d11cd781 | ||
|
|
7278cda039 | ||
|
|
7bb9db501c | ||
|
|
046a8eae0f | ||
|
|
a0cdac48e0 | ||
|
|
2ab3946ecb | ||
|
|
63f00dae6b | ||
|
|
80d78fad7c | ||
|
|
34debc733f | ||
|
|
87d7f7744e | ||
|
|
10dc1882c8 | ||
|
|
c6c0c3be08 | ||
|
|
da6c97203e | ||
|
|
853a46e021 | ||
|
|
075ad676aa | ||
|
|
19d1ad04f4 | ||
|
|
b884533957 | ||
|
|
174f37bdaf | ||
|
|
4f00774006 | ||
|
|
8403c49484 | ||
|
|
15e3bfac9d | ||
|
|
6cecd1a15b | ||
|
|
08620b7ceb | ||
|
|
fe1cee0837 | ||
|
|
06ab541e2f | ||
|
|
7babc24ad4 | ||
|
|
c96e9c8273 | ||
|
|
4a51295c9e | ||
|
|
9c392896b7 | ||
|
|
ea613e181c | ||
|
|
ed5bd1f9ef | ||
|
|
3401dbde92 | ||
|
|
c9e0208de4 | ||
|
|
57a816ae60 | ||
|
|
643f0e3abf | ||
|
|
8744d10235 | ||
|
|
336d9212fc | ||
|
|
79d88e2d0b | ||
|
|
a0d3e405a3 | ||
|
|
0e6e876f23 | ||
|
|
c680f54e6c | ||
|
|
4d745bc602 | ||
|
|
44aa9a4b3a | ||
|
|
5d4126876b | ||
|
|
0ba02a4ed6 | ||
|
|
f39b138487 | ||
|
|
d9b758661f | ||
|
|
c99ac2451f | ||
|
|
ed7d965818 | ||
|
|
18dca11dd0 | ||
|
|
ee8fd5325a | ||
|
|
7c51c0e3de | ||
|
|
c0d02e5ae4 | ||
|
|
032e1397d9 | ||
|
|
c2d9b07533 | ||
|
|
4ef1145241 | ||
|
|
57a93e1a19 | ||
|
|
94c888ebda | ||
|
|
495d6f1e39 | ||
|
|
68971223aa | ||
|
|
4441aa8b60 | ||
|
|
497ebec01d | ||
|
|
be63037654 | ||
|
|
0448428322 | ||
|
|
92e2df5978 | ||
|
|
fd75bdccb0 | ||
|
|
51b3495ad8 | ||
|
|
b7e5d76c79 | ||
|
|
8ccfdf7ba0 | ||
|
|
8c61ee5498 | ||
|
|
d99ab9f903 | ||
|
|
de7625b8c2 | ||
|
|
bc051dcf91 | ||
|
|
3ec62dfeff | ||
|
|
0fe5166531 | ||
|
|
9fbe560218 | ||
|
|
fff47f1119 | ||
|
|
8e3aac5744 | ||
|
|
68046106dd | ||
|
|
47570d045d | ||
|
|
ec13fa436b | ||
|
|
22ad62c90c | ||
|
|
f18aea5246 | ||
|
|
5ee9c2ad1f | ||
|
|
3f0699cf02 | ||
|
|
4f4bc7cc8f | ||
|
|
85b2fe8486 | ||
|
|
adfa5364cd | ||
|
|
673eb7de96 | ||
|
|
da3c86925a | ||
|
|
2819ab32f8 | ||
|
|
6f21bed66d | ||
|
|
719a3fe98e | ||
|
|
5bc70c68e2 | ||
|
|
dcf14505e2 | ||
|
|
d8c6953710 | ||
|
|
e4bba0b53c | ||
|
|
89b5a2c3d5 | ||
|
|
97e0d59619 | ||
|
|
ca72eb0596 | ||
|
|
04a5b9c2cf | ||
|
|
776897d3c9 | ||
|
|
7cd567202e | ||
|
|
0218ddd575 | ||
|
|
6722d789e9 | ||
|
|
6e846c56b4 | ||
|
|
608dd96de6 | ||
|
|
a49ddaac89 | ||
|
|
613a6a964c | ||
|
|
0dc2885f3e | ||
|
|
efe2b21a5f | ||
|
|
e132b444a9 | ||
|
|
4fde473f38 | ||
|
|
afe20dc9b6 | ||
|
|
b580c11303 | ||
|
|
e97e55adbc | ||
|
|
2f9c518ca8 | ||
|
|
9a50c09172 | ||
|
|
3a964d18e0 | ||
|
|
8d6e66d38c | ||
|
|
f7dabede8b | ||
|
|
725d185a31 | ||
|
|
2a8c75f3e6 | ||
|
|
c2c38beec8 | ||
|
|
f633a60581 | ||
|
|
d290e583c5 | ||
|
|
c56e8b4964 | ||
|
|
344d5ff4b7 | ||
|
|
b2c73596ae | ||
|
|
12626b85c4 | ||
|
|
08bb348142 | ||
|
|
041abe8522 | ||
|
|
39a90ac4d6 | ||
|
|
f2e4e80391 | ||
|
|
fe048efeab | ||
|
|
24f7328e5f | ||
|
|
842837e35b | ||
|
|
6b3cbb10a2 | ||
|
|
d896eab166 | ||
|
|
4cf85ee543 | ||
|
|
cfa43e721a | ||
|
|
d8da97f756 | ||
|
|
ca3169310e | ||
|
|
1ec1510ef7 | ||
|
|
7ac99a4366 | ||
|
|
b7f13df130 | ||
|
|
571dae9664 | ||
|
|
b178fd4286 | ||
|
|
115a8e74c2 | ||
|
|
41f4acfb4f | ||
|
|
7b8e000133 | ||
|
|
1ce75e2bca | ||
|
|
e8f831deaa | ||
|
|
f6fc166584 | ||
|
|
a0b3eceec7 | ||
|
|
7d70c0ff9f | ||
|
|
7a42233d43 | ||
|
|
895bff6524 | ||
|
|
e43fd75378 | ||
|
|
df068ce11e | ||
|
|
e4055e763f | ||
|
|
1e130e045b | ||
|
|
65857236c7 | ||
|
|
6af6cec23f | ||
|
|
96be957315 | ||
|
|
4acce85656 | ||
|
|
cc3d4cab21 | ||
|
|
e1481a731d | ||
|
|
29fbf3c1ec | ||
|
|
0e769c5418 | ||
|
|
573f08135d | ||
|
|
2e67bd4de7 | ||
|
|
c18301f356 | ||
|
|
02f58b3207 | ||
|
|
bc394410a2 | ||
|
|
b98e92839c | ||
|
|
8269924c33 | ||
|
|
9da3e6696a | ||
|
|
d72e66cdee | ||
|
|
2d2b1cee6b | ||
|
|
3c27c643a9 | ||
|
|
d85e22d205 | ||
|
|
8766efcba6 | ||
|
|
80c08f2286 | ||
|
|
59a11363a5 | ||
|
|
402db2ef32 | ||
|
|
1e118ab891 | ||
|
|
b029be6b6c | ||
|
|
033cdc4133 | ||
|
|
69547bd4bd | ||
|
|
e3860aa6ac | ||
|
|
25f9c318e3 | ||
|
|
5926c877a1 | ||
|
|
9f8b4bdaf1 | ||
|
|
b2343d6247 | ||
|
|
83aad81279 | ||
|
|
f3780c7354 | ||
|
|
92ff153763 | ||
|
|
3d848a886a | ||
|
|
822903e56d | ||
|
|
5ee9845559 | ||
|
|
ea756ede16 | ||
|
|
1b51a88bba | ||
|
|
39f6c793b3 | ||
|
|
91ed6e67b4 | ||
|
|
fad5280d4c | ||
|
|
65e6039979 | ||
|
|
46fa9e8efb | ||
|
|
f6735c223c | ||
|
|
89e880dfd1 | ||
|
|
8523cbdf58 | ||
|
|
4dec946ae6 | ||
|
|
b32ef3c05d | ||
|
|
8140a9d8a6 | ||
|
|
42e7bb80b6 | ||
|
|
6a455e1281 | ||
|
|
5310f5fba3 | ||
|
|
2b0d49a905 | ||
|
|
e7efe94fd2 | ||
|
|
890fff92fd | ||
|
|
c4fa9bb61f | ||
|
|
bcd1a94b89 | ||
|
|
7840e453b5 | ||
|
|
eb650c468a | ||
|
|
c43b138a69 | ||
|
|
cdfa537adf | ||
|
|
ed2bb2cff0 | ||
|
|
0436fba13c | ||
|
|
e8035b94e5 | ||
|
|
d789263e08 | ||
|
|
12599da53d | ||
|
|
fb5c537080 | ||
|
|
526a5d0f8a | ||
|
|
1ea9ff3677 | ||
|
|
074bf39e40 | ||
|
|
23dc46c4f8 | ||
|
|
e9cf3de58f | ||
|
|
69d28f867c | ||
|
|
db30e1b5b6 | ||
|
|
f40274702d | ||
|
|
253dff7656 | ||
|
|
fc87081133 | ||
|
|
9324961cd2 | ||
|
|
44498825cd | ||
|
|
168b97c291 | ||
|
|
2de15dc64b | ||
|
|
5460903f96 | ||
|
|
cb4c03756a | ||
|
|
a548cd9934 | ||
|
|
0fff7ceda4 | ||
|
|
e41bf16ff1 | ||
|
|
8bd1fc4f04 | ||
|
|
cc65015e4e | ||
|
|
41517bca0c | ||
|
|
4048494aa1 | ||
|
|
f816b861fc | ||
|
|
85d0507580 | ||
|
|
b12c42e75d | ||
|
|
e76cfe5aad | ||
|
|
7ac1bff482 | ||
|
|
144f444217 | ||
|
|
52a6863771 | ||
|
|
8ea0ae454f | ||
|
|
735d31e54a | ||
|
|
41a0e991f0 | ||
|
|
40f988ce2a | ||
|
|
c98e3c0eff | ||
|
|
da51485e17 | ||
|
|
93410c47e1 | ||
|
|
dec8d3863a | ||
|
|
131f5c57ab | ||
|
|
0b71339122 | ||
|
|
161e222322 | ||
|
|
e98a314e06 | ||
|
|
2bf6879dae | ||
|
|
ef6beaeff6 | ||
|
|
d8a612f73b | ||
|
|
78a17038c2 | ||
|
|
18c8a93cca | ||
|
|
c06a7585a3 | ||
|
|
1cfc0de31d | ||
|
|
d59f10d7f5 | ||
|
|
76b252f80a | ||
|
|
92993e68c8 | ||
|
|
dc1320df64 | ||
|
|
8a8d8a7b38 | ||
|
|
eb79e3ab3d | ||
|
|
815553c4b4 | ||
|
|
96786a183b | ||
|
|
066b24d741 | ||
|
|
82b81fce68 | ||
|
|
6580590226 | ||
|
|
842c313db2 | ||
|
|
99f6b305c1 | ||
|
|
df694c89b0 | ||
|
|
57d345ff80 | ||
|
|
3ce753c489 | ||
|
|
be151977ca | ||
|
|
daaf0e4ef3 | ||
|
|
80404fae30 | ||
|
|
093d01269a | ||
|
|
7aba8da551 | ||
|
|
a2371ef90b | ||
|
|
fb69a09d6e | ||
|
|
c5653d5f34 | ||
|
|
b203ac1e0d | ||
|
|
722f6013ff | ||
|
|
bd19bc5085 | ||
|
|
2bf6552f2f | ||
|
|
ba62becb7d | ||
|
|
a509790a1c | ||
|
|
953ce90d27 | ||
|
|
288055180e | ||
|
|
8ed4e2dde7 | ||
|
|
2137b3448b | ||
|
|
14614f561b | ||
|
|
b06f3c6d1d | ||
|
|
4ff1631b31 | ||
|
|
a2bc3d81c2 | ||
|
|
cec3e945f0 | ||
|
|
df8450d928 | ||
|
|
4399599de9 | ||
|
|
ef1521b472 | ||
|
|
a51a26e2aa | ||
|
|
553b1c301d | ||
|
|
a6c7801926 | ||
|
|
076a1ab85c | ||
|
|
ac13683c26 | ||
|
|
43cc3fc8b1 | ||
|
|
4f27792ffe | ||
|
|
b670f799d5 | ||
|
|
0f553c57bd | ||
|
|
1269467fa0 | ||
|
|
08e1e7681e | ||
|
|
26c017d5ea | ||
|
|
ee8941e0de | ||
|
|
16fe666e36 | ||
|
|
e538883a20 | ||
|
|
9fa65cd190 | ||
|
|
abe294bfd0 | ||
|
|
0430c55b84 | ||
|
|
dbb91a574f | ||
|
|
eefe5d5aac | ||
|
|
2d2b1bc1cc | ||
|
|
75efba7ec7 | ||
|
|
372fd27e71 | ||
|
|
c20e160e0f | ||
|
|
208705368e | ||
|
|
a21a2e855b | ||
|
|
ee357aaddf | ||
|
|
2cde9125d6 | ||
|
|
0f0473bf1c | ||
|
|
191a728ecc | ||
|
|
e55415bfef | ||
|
|
b2f39318cb | ||
|
|
201899b611 | ||
|
|
eaac68ca2c | ||
|
|
c3d7ada9df | ||
|
|
91f72bbe1c | ||
|
|
9485aeb5c8 | ||
|
|
e877f78b0e | ||
|
|
ef503ab0c8 | ||
|
|
b7ab2b7523 | ||
|
|
a92b53df7b | ||
|
|
ac6b84a7d7 | ||
|
|
5e17c08010 | ||
|
|
69e1fb50ca | ||
|
|
e6913f58b9 | ||
|
|
c3a3a39e92 | ||
|
|
19289d587a | ||
|
|
c53c9a8644 | ||
|
|
87a6443c5b | ||
|
|
2bf57bbad4 | ||
|
|
77f1d3b317 | ||
|
|
407a0b972e | ||
|
|
346f5c6819 | ||
|
|
5f0acadf7d | ||
|
|
143924bbf3 | ||
|
|
1ffa7a40ac | ||
|
|
e11ad6b77e | ||
|
|
415dddf0fa | ||
|
|
10a0eb3e1c | ||
|
|
cdb5cbe6f8 | ||
|
|
d93d918eca | ||
|
|
6d939fcedc | ||
|
|
9361c35176 | ||
|
|
c008c7d494 | ||
|
|
c90ea1315a | ||
|
|
63554bcee5 | ||
|
|
b5a73033ab | ||
|
|
2df9e9b103 | ||
|
|
2fd474132d | ||
|
|
4e487cfa99 | ||
|
|
1387d356aa | ||
|
|
5c3ac93335 | ||
|
|
61242e2e6a | ||
|
|
08689c51a9 | ||
|
|
4a6ba95392 | ||
|
|
e33069ce56 | ||
|
|
b9ac32a0d5 | ||
|
|
f484af34c2 | ||
|
|
ba513ba804 | ||
|
|
0a222a3e2a | ||
|
|
bf68040dc5 | ||
|
|
37fba4bed4 | ||
|
|
1c8fad73f8 | ||
|
|
bbc89b6391 | ||
|
|
64a5e27486 | ||
|
|
d1dc2a3298 | ||
|
|
46235e91f6 | ||
|
|
afd3a36f69 | ||
|
|
c5e2bb7cd1 | ||
|
|
ef62aa7333 | ||
|
|
e3bfaab3f7 | ||
|
|
c0dfd65d67 | ||
|
|
20066a8964 | ||
|
|
3f8033324f | ||
|
|
75ddd9a6cd | ||
|
|
b3c96bde8c | ||
|
|
cbb8edb0b7 | ||
|
|
fcdaa32793 | ||
|
|
fe298cf984 | ||
|
|
75964a9860 | ||
|
|
b81991ac01 | ||
|
|
2a000ee091 | ||
|
|
f53de38e1f | ||
|
|
3563f4db32 | ||
|
|
f2ba3a937b | ||
|
|
0fc4967ebc | ||
|
|
aed1bcc12c | ||
|
|
839e3274e1 | ||
|
|
6a42d6b339 | ||
|
|
dcf0d8cab6 | ||
|
|
7c6ce12fa4 | ||
|
|
bf0f586b69 | ||
|
|
facf671eca | ||
|
|
af987eb117 | ||
|
|
87f12e56fe | ||
|
|
baffc4e8b8 | ||
|
|
0ddc36f543 | ||
|
|
88d2df24be | ||
|
|
69d572bb10 | ||
|
|
97d85338e8 | ||
|
|
e4a865177e | ||
|
|
faea193800 | ||
|
|
7ab4728a36 | ||
|
|
b23a216ecd | ||
|
|
d3bb3336f5 | ||
|
|
3ab50c334a | ||
|
|
f4d9359095 | ||
|
|
9943137d1e | ||
|
|
ee0d96ac0d | ||
|
|
8c977bf7b3 | ||
|
|
5311253468 | ||
|
|
ed50bb1676 | ||
|
|
bbb0f0ade4 | ||
|
|
06c2c9f456 | ||
|
|
43caca05c2 | ||
|
|
bcbbfdaad4 | ||
|
|
5e7174dec6 | ||
|
|
74e453cf15 | ||
|
|
b811c42034 | ||
|
|
789de09dda | ||
|
|
47d1ab192a | ||
|
|
39f34e1e58 | ||
|
|
e5b218e6d1 | ||
|
|
faa03031b4 | ||
|
|
974bf58a21 | ||
|
|
91652c317e | ||
|
|
9701810bc3 | ||
|
|
b4bd596a39 | ||
|
|
fcab22f80f | ||
|
|
8098d79ca2 | ||
|
|
9fdeb41e52 | ||
|
|
4bdb0ac685 | ||
|
|
b6786595a4 | ||
|
|
df5690d91a | ||
|
|
a26fcf58cc | ||
|
|
8bbdfefe05 | ||
|
|
187acb8609 | ||
|
|
5c9fb8f064 | ||
|
|
0c079e453b | ||
|
|
7674cbc9b2 | ||
|
|
dbd9ae287a | ||
|
|
702a67807b | ||
|
|
a806d2f9b8 | ||
|
|
ca3ba28768 | ||
|
|
f5003aff69 | ||
|
|
102f3f3a0d | ||
|
|
979c7d76ab | ||
|
|
790f2b9a7a | ||
|
|
d467950a5e | ||
|
|
0ecb2bbe74 | ||
|
|
ee48ffe021 | ||
|
|
5679de60c5 | ||
|
|
4806a1924f | ||
|
|
f5befd2d29 | ||
|
|
cfed7a3a54 | ||
|
|
93b446a962 | ||
|
|
a7dc184772 | ||
|
|
bfaef8ca17 | ||
|
|
2737dbb1e1 | ||
|
|
4d4f1fd364 | ||
|
|
d6493aab02 | ||
|
|
126d004f9e | ||
|
|
97428e8ac9 | ||
|
|
ea2a12112d | ||
|
|
aa97252f60 | ||
|
|
b758b8223f | ||
|
|
79bba34c5f | ||
|
|
d9dad2f4a1 | ||
|
|
6e30c42101 | ||
|
|
de4f77b0ac | ||
|
|
09654f4e8c | ||
|
|
557c77e455 | ||
|
|
2d403a1614 | ||
|
|
6da230636b | ||
|
|
51e4cba909 | ||
|
|
6972b6c380 | ||
|
|
39585aa90d | ||
|
|
a9e53829d2 | ||
|
|
bb8d2957ee | ||
|
|
88d4827b64 | ||
|
|
3c3d943fb1 | ||
|
|
806731e37a | ||
|
|
1ec99f4fd3 | ||
|
|
19d060cc26 | ||
|
|
377a387a42 | ||
|
|
9f49292b35 | ||
|
|
119dfbc627 | ||
|
|
fcec08f7ae | ||
|
|
324172fb1f | ||
|
|
a7657f2ed4 | ||
|
|
df31774327 | ||
|
|
935938bbd9 | ||
|
|
71b160cdbb | ||
|
|
7a919e80c9 | ||
|
|
0758594bd2 | ||
|
|
9b486e47fe | ||
|
|
caf3faa054 | ||
|
|
510a9a77d6 | ||
|
|
4d0c776a80 | ||
|
|
4450d61ac2 | ||
|
|
22baec494b | ||
|
|
94877a137d | ||
|
|
de3f68a233 | ||
|
|
b2c55c9db5 | ||
|
|
eefd2da0f6 | ||
|
|
ce13f6b73e | ||
|
|
4819eae867 | ||
|
|
c5ade6591e | ||
|
|
9c2876b9f8 | ||
|
|
15b96fd051 | ||
|
|
1aab00da85 | ||
|
|
482a1f50b6 | ||
|
|
494ea57b65 | ||
|
|
cdafefd4be | ||
|
|
8bd3e20c86 | ||
|
|
3fb14b50f8 | ||
|
|
aa83d5d455 | ||
|
|
aaacb01b8d | ||
|
|
9996a2d51b | ||
|
|
6aa0810de5 | ||
|
|
4f4fb1d220 | ||
|
|
242d856ede | ||
|
|
a86fcbd947 | ||
|
|
4c0604ec2e | ||
|
|
2db3e9d439 | ||
|
|
6e29450f76 | ||
|
|
9ab0b66f50 | ||
|
|
030746faff | ||
|
|
dac40d0487 | ||
|
|
ef969a53f5 | ||
|
|
5dce79e941 | ||
|
|
dd89bb1469 | ||
|
|
74afea04d6 | ||
|
|
edc66d79c7 | ||
|
|
3064e6d10c | ||
|
|
6acdce78d1 | ||
|
|
773060155f | ||
|
|
434b7710f3 | ||
|
|
1a7b5945c7 | ||
|
|
ea59440662 | ||
|
|
1e18a6cf60 | ||
|
|
a6bcbb173b | ||
|
|
6dc376f676 | ||
|
|
85c488ee12 | ||
|
|
05742f9b6f | ||
|
|
8b7b3ce03e | ||
|
|
eec097fe35 | ||
|
|
8a35386ba7 | ||
|
|
8f0411ff03 | ||
|
|
afd659bb92 | ||
|
|
c4a32a129d | ||
|
|
78ec1272e9 | ||
|
|
2860d7ba05 | ||
|
|
474305c476 | ||
|
|
ec4cd2cb8c | ||
|
|
a4ebe3d576 | ||
|
|
98c2f6b0c4 | ||
|
|
e1ae7db4cc | ||
|
|
12963f5231 | ||
|
|
890ead6a71 | ||
|
|
95c4111783 | ||
|
|
f94a5f0e8c | ||
|
|
b78cc37891 | ||
|
|
71d39a4634 | ||
|
|
a931fb7f51 | ||
|
|
7cd31c3557 | ||
|
|
7221f5e739 | ||
|
|
ef7ffaff74 | ||
|
|
3d900edba7 | ||
|
|
6916f935eb | ||
|
|
3b2f2602b4 | ||
|
|
4dc9df6aae | ||
|
|
88cda0cab6 | ||
|
|
a431e1277e | ||
|
|
a18622c369 | ||
|
|
2206e31e54 | ||
|
|
e8ad60cc4f | ||
|
|
50dbb086f2 | ||
|
|
e368015d79 | ||
|
|
e5668b8c73 | ||
|
|
8679cfa2d8 | ||
|
|
4982602f6f | ||
|
|
914fbcf2e5 | ||
|
|
4f1d3809c3 | ||
|
|
0625b37760 | ||
|
|
cfed18afc7 | ||
|
|
2d20e13746 | ||
|
|
d80347613a | ||
|
|
1a31e31ae9 | ||
|
|
de962e83d0 | ||
|
|
da0ba9e2fe | ||
|
|
5dd84082ab | ||
|
|
204cebc8fc | ||
|
|
6265339995 | ||
|
|
f820bf7cd4 | ||
|
|
e4db4e423d | ||
|
|
1820fe5f83 | ||
|
|
e2a99b5760 | ||
|
|
11b3a7c8ca | ||
|
|
dbb5eeaadf | ||
|
|
e6c5296f30 | ||
|
|
ae6cfd32a0 | ||
|
|
fa178f4235 | ||
|
|
c2dcc80660 | ||
|
|
1dc776208e | ||
|
|
c0308da665 | ||
|
|
082595200d | ||
|
|
dabc990189 | ||
|
|
a71191515a | ||
|
|
dfd1bc3c5b | ||
|
|
4230e98720 | ||
|
|
ea0da0bf47 | ||
|
|
75d99659c4 | ||
|
|
db4e541306 | ||
|
|
9c4948a4d1 | ||
|
|
a05d547ae8 | ||
|
|
134fbe1245 | ||
|
|
5a28f188ff | ||
|
|
81dab646ee | ||
|
|
96e3b147f0 | ||
|
|
afb6e9a879 | ||
|
|
355cb589e3 | ||
|
|
8a1613a382 | ||
|
|
4211fdc70b | ||
|
|
9eafb7bbfb | ||
|
|
53244aaac7 | ||
|
|
ed7551c1d4 | ||
|
|
bbf957875b | ||
|
|
9bc5b0406d | ||
|
|
10199341b1 | ||
|
|
71da34c48c | ||
|
|
64e738cae7 | ||
|
|
6906ac979e | ||
|
|
fdca6c08ad | ||
|
|
d17e9fc107 | ||
|
|
3e6bdc2242 | ||
|
|
a3802c84fd | ||
|
|
bf13442c7c | ||
|
|
2af26b75d1 | ||
|
|
7ae7c90790 | ||
|
|
6e94f6cefb | ||
|
|
e8779a67b1 | ||
|
|
4c2e7bb035 | ||
|
|
8b0af7fddc | ||
|
|
aa1b4ea861 | ||
|
|
aa23f3801b | ||
|
|
80c9cd1f6e | ||
|
|
d7454de80a | ||
|
|
dd89a3741b | ||
|
|
487d7f9a29 | ||
|
|
f2262eb81a | ||
|
|
b7c27c5333 | ||
|
|
4c64ba16c5 | ||
|
|
007735737a | ||
|
|
b4a5d1dc53 | ||
|
|
109dd2be5d | ||
|
|
507cdba44e | ||
|
|
015186aaf8 | ||
|
|
0f33d7185f | ||
|
|
b9badb597a | ||
|
|
8ebf22d3c1 | ||
|
|
6684984c49 | ||
|
|
0e21bde77b | ||
|
|
8a9de84cd0 | ||
|
|
100075f2be | ||
|
|
c59a2267d0 | ||
|
|
c0ae3258f9 | ||
|
|
5c1d2d1e4c | ||
|
|
9f8481a842 | ||
|
|
21902e2f53 | ||
|
|
c38c18c1a0 | ||
|
|
c5f60942bd | ||
|
|
290e402a02 | ||
|
|
6fb7d44255 | ||
|
|
32cea85331 | ||
|
|
00f12b9a09 | ||
|
|
d0d571e0d7 | ||
|
|
a604d4f717 | ||
|
|
a28ffa81c4 | ||
|
|
1d962820d8 | ||
|
|
0b8ff4b238 | ||
|
|
e7fb97208a | ||
|
|
2f91176011 | ||
|
|
596e09770d | ||
|
|
e799849272 | ||
|
|
8bbccf7a97 | ||
|
|
940d9540f3 | ||
|
|
c7983115e9 | ||
|
|
90094a871a | ||
|
|
1c67a3412e | ||
|
|
960a6f14bf | ||
|
|
2b8545684c | ||
|
|
bbbdc70f26 | ||
|
|
e6a7c7689f | ||
|
|
0514332474 | ||
|
|
63649e0359 | ||
|
|
3115ae0815 | ||
|
|
cec8ff1885 | ||
|
|
f04d3cbdaa | ||
|
|
af271e7330 | ||
|
|
3cdf3f9411 | ||
|
|
9cc0bf89bd | ||
|
|
93a93071a2 | ||
|
|
38e606a153 | ||
|
|
a2e21727c0 | ||
|
|
dbf76f62f9 | ||
|
|
e7e898ea17 | ||
|
|
d0021e1621 | ||
|
|
2f1194a296 | ||
|
|
80aafbc81b | ||
|
|
f169102c8e | ||
|
|
a0f907933d | ||
|
|
c147a59bb0 | ||
|
|
2d2c7d3f95 | ||
|
|
87f3109c1a | ||
|
|
eb642a9535 | ||
|
|
6982ce43f5 | ||
|
|
5413a9a6b4 | ||
|
|
18929bd6d6 | ||
|
|
2a600bddcb | ||
|
|
006721fbd6 | ||
|
|
7219fa65c0 | ||
|
|
61d4bf95dc | ||
|
|
d30e102f3a | ||
|
|
91e8f2b0fe | ||
|
|
eed9502795 | ||
|
|
fd93229770 | ||
|
|
9b0e61aaaa | ||
|
|
ae839620b9 | ||
|
|
457fae24e7 | ||
|
|
cd6c83cdcc | ||
|
|
edef72d497 | ||
|
|
32f11402f9 | ||
|
|
e900571ac2 | ||
|
|
f31d53093b | ||
|
|
13c4084362 | ||
|
|
f5f11e94be | ||
|
|
324d4bb140 | ||
|
|
8237ab450e | ||
|
|
4ad5496474 | ||
|
|
f9f4e22f6f | ||
|
|
4cc464eadc | ||
|
|
1d069cf435 | ||
|
|
e487eb9da0 | ||
|
|
f25665f360 | ||
|
|
947aa9c972 | ||
|
|
993fa34749 | ||
|
|
2ca83f0bc7 | ||
|
|
a9cd0f5e42 | ||
|
|
c3ffd4c53e | ||
|
|
d78e823449 | ||
|
|
d2645423de | ||
|
|
f3147f446a | ||
|
|
921c22f5ad | ||
|
|
6b348622bb | ||
|
|
fce07bb1cb | ||
|
|
53dd7552dc | ||
|
|
2671f68f7f | ||
|
|
3f3c62a3c9 | ||
|
|
18e5d769fd | ||
|
|
43fbd7ce84 | ||
|
|
566558b17c | ||
|
|
ff2d6815ef | ||
|
|
6f6ac84228 | ||
|
|
70b6ba4240 | ||
|
|
923ca4765a | ||
|
|
43c51eb12d | ||
|
|
ee2119d7cb | ||
|
|
19a1f2a5d2 | ||
|
|
9b26743c6b | ||
|
|
dda7672008 | ||
|
|
c1123fd8d0 | ||
|
|
90dd510df1 | ||
|
|
96877eb9c3 | ||
|
|
2d660108b2 | ||
|
|
326dc95f9c | ||
|
|
e6dd8f626a | ||
|
|
61ab94d553 | ||
|
|
14d213ca85 | ||
|
|
9b27329437 | ||
|
|
5b7feebfd8 | ||
|
|
dfbf1b4f6b | ||
|
|
dad1047b04 | ||
|
|
cdf21f6773 | ||
|
|
20360e00ce | ||
|
|
551b6c4d66 | ||
|
|
d0e870aad2 | ||
|
|
5ae3dd52a0 | ||
|
|
eb0ad66d88 | ||
|
|
d66f4e5890 | ||
|
|
142827f7d8 | ||
|
|
08400f5be7 | ||
|
|
40b2286d16 | ||
|
|
3260ea6954 | ||
|
|
8082a84903 | ||
|
|
8be0723fb7 | ||
|
|
e97b97467e | ||
|
|
3381ab423b | ||
|
|
368123ab06 | ||
|
|
f401021d5a | ||
|
|
31b967f098 | ||
|
|
01d27a4acd | ||
|
|
419a9ada16 | ||
|
|
17bd417a3d | ||
|
|
3b683927ee | ||
|
|
3543dfda95 | ||
|
|
d97bbf1904 | ||
|
|
d9f829dd71 | ||
|
|
83660e37e3 | ||
|
|
df0776e931 | ||
|
|
738d6db3e6 | ||
|
|
6f287dd16d | ||
|
|
fe2fa2d08e | ||
|
|
57ab2b4226 | ||
|
|
ec2f1d69c8 | ||
|
|
63234f8dd0 | ||
|
|
c347d6944b | ||
|
|
be2d006e2e | ||
|
|
88e232739b | ||
|
|
d4791f1bbe | ||
|
|
82d0584e7b | ||
|
|
75f83de52a | ||
|
|
f77d22837c | ||
|
|
a63220e3e0 | ||
|
|
71c77c081a | ||
|
|
772ca9e9a9 | ||
|
|
f37a9a27e5 | ||
|
|
a4fcc93f4a | ||
|
|
9a0dff1bc5 | ||
|
|
0bde57c25a | ||
|
|
ee1deccc08 | ||
|
|
9d6ec825cb | ||
|
|
3b8c7d0326 | ||
|
|
fedf45c77e | ||
|
|
d67e2eea1a | ||
|
|
81b689b969 | ||
|
|
81cfe09657 | ||
|
|
646df39003 | ||
|
|
942b64abfc | ||
|
|
ccb6646bae | ||
|
|
1039b7f543 | ||
|
|
a908d73c16 | ||
|
|
943e26b16b | ||
|
|
b4033b37ad | ||
|
|
a855bd8df3 | ||
|
|
06092a9756 | ||
|
|
062e580436 | ||
|
|
4994e75852 | ||
|
|
41f02825fc | ||
|
|
c71e4e8c7c | ||
|
|
99109c0b3b | ||
|
|
83b64b8be2 | ||
|
|
4e2126ee44 | ||
|
|
ab9ce2a927 | ||
|
|
3982cb35dc | ||
|
|
1ff9768aa3 | ||
|
|
634a7ed988 | ||
|
|
0bae2db77f | ||
|
|
0536ace2b6 | ||
|
|
23b655f8e3 | ||
|
|
7a56b41124 | ||
|
|
db26fe7ca8 | ||
|
|
604f2fa84a | ||
|
|
38617a5ad3 | ||
|
|
0f6a463fae | ||
|
|
e6b5cafe65 | ||
|
|
706438a43c | ||
|
|
04d9a04557 | ||
|
|
83ecc846dc | ||
|
|
67e5f3505d | ||
|
|
971d243a87 | ||
|
|
49a9eee33f | ||
|
|
b0185efd24 | ||
|
|
50de550ecd | ||
|
|
514a97a9b7 | ||
|
|
42f47590f9 | ||
|
|
fcdd58757a | ||
|
|
97da66209c | ||
|
|
462d167456 | ||
|
|
ad37b79bca | ||
|
|
626d358e55 | ||
|
|
b001038901 | ||
|
|
ba5161740e | ||
|
|
d885fe4dd0 | ||
|
|
349af8766c | ||
|
|
20ae8bd4c3 | ||
|
|
c4bc674482 | ||
|
|
98d52b7b26 | ||
|
|
f29e505d94 | ||
|
|
a0b811dd37 | ||
|
|
9fbc313459 | ||
|
|
661bba09ce | ||
|
|
22503bfe75 | ||
|
|
f3d242a90d | ||
|
|
c3629adbeb | ||
|
|
6b8accbfa1 | ||
|
|
92b94980c6 | ||
|
|
19b494df89 | ||
|
|
f890d85381 | ||
|
|
fa9277d12d | ||
|
|
42206b3d51 | ||
|
|
74dd38d27c | ||
|
|
e94f95d82b | ||
|
|
9bd5d8a240 | ||
|
|
1dde20ff4a |
6
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
6
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@@ -4,10 +4,12 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions)
|
FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions)
|
||||||
For anything else: we are happy to use 'GitHub Issues' for many types of open-ended questions. We are encouraging 'Issues' becoming a large, centralized and cross-referenced database of Dear ImGui contents.
|
For anything else: **we are happy to use 'GitHub Issues' for many types of open-ended questions**. We are encouraging 'Issues' becoming a large, centralized, tagged, cross-referenced database of Dear ImGui contents.
|
||||||
|
|
||||||
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
|
Be mindful that messages are being sent to the e-mail box of "Watching" users. Try to proof-read your messages before sending them. Edits are not seen by those users.
|
||||||
|
|
||||||
|
**If you are using Dear ImGui as part of a job that you are being well-paid for** and your company is not a sponsor. Please be mindful that this is a Free Software and you might be about to ask volunteers to help you doing your job. Please put extra effort describing your issue or question properly. If your company is wealthy, please read [Funding](https://github.com/ocornut/imgui/wiki/Funding) and consider getting in touch.
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
|
|||||||
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@@ -2,5 +2,7 @@
|
|||||||
|
|
||||||
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)
|
||||||
|
|
||||||
2. Clear this template before submitting your PR.
|
2. Make sure you're using a special branch just for this pull request. (Sometimes people unknowingly use a default branch, then later update that branch, which updates the pull request with the other changes if it hasn't been merged yet.)
|
||||||
|
|
||||||
|
3. Clear this template before submitting your PR.
|
||||||
|
|
||||||
|
|||||||
119
.github/workflows/build.yml
vendored
119
.github/workflows/build.yml
vendored
@@ -17,19 +17,23 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Windows:
|
Windows:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2025
|
||||||
env:
|
env:
|
||||||
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
|
VS_PATH: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\
|
||||||
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
|
MSBUILD_PATH: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
shell: powershell
|
shell: powershell
|
||||||
run: |
|
run: |
|
||||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.26.3-VC.zip" -OutFile "SDL2-devel-2.26.3-VC.zip"
|
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.32.8-VC.zip" -OutFile "SDL2-devel-2.32.8-VC.zip"
|
||||||
Expand-Archive -Path SDL2-devel-2.26.3-VC.zip
|
Expand-Archive -Path SDL2-devel-2.32.8-VC.zip
|
||||||
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.26.3-VC\SDL2-2.26.3\" >>${env:GITHUB_ENV}
|
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.32.8-VC\SDL2-2.32.8\" >>${env:GITHUB_ENV}
|
||||||
|
|
||||||
|
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL3-devel-3.2.18-VC.zip" -OutFile "SDL3-devel-3.2.18-VC.zip"
|
||||||
|
Expand-Archive -Path SDL3-devel-3.2.18-VC.zip
|
||||||
|
echo "SDL3_DIR=$(pwd)\SDL3-devel-3.2.18-VC\SDL3-3.2.18\" >>${env:GITHUB_ENV}
|
||||||
|
|
||||||
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
|
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
|
||||||
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
|
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
|
||||||
@@ -40,8 +44,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
# CI workers do not supporter older Visual Studio versions. Fix projects to target newer available version.
|
# CI workers do not supporter older Visual Studio versions. Fix projects to target newer available version.
|
||||||
gci -recurse -filter "*.vcxproj" | ForEach-Object {
|
gci -recurse -filter "*.vcxproj" | ForEach-Object {
|
||||||
(Get-Content $_.FullName) -Replace "<PlatformToolset>v\d{3}</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
|
(Get-Content $_.FullName) -Replace "<PlatformToolset>v\d{3}</PlatformToolset>","<PlatformToolset>v143</PlatformToolset>" | Set-Content -Path $_.FullName
|
||||||
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>[\d\.]+</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
|
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>[\d\.]+</WindowsTargetPlatformVersion>",'<WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>' | Set-Content -Path $_.FullName
|
||||||
}
|
}
|
||||||
|
|
||||||
# Not using matrix here because it would inflate job count too much. Check out and setup is done for every job and that makes build times way too long.
|
# Not using matrix here because it would inflate job count too much. Check out and setup is done for every job and that makes build times way too long.
|
||||||
@@ -51,15 +55,11 @@ jobs:
|
|||||||
- name: Build example_null (mingw 64-bit, as DLL)
|
- name: Build example_null (mingw 64-bit, as DLL)
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
echo '#ifdef _EXPORT' > example_single_file.cpp
|
echo '#define IMGUI_API __declspec(dllexport)' > example_single_file.cpp
|
||||||
echo '# define IMGUI_API __declspec(dllexport)' >> example_single_file.cpp
|
|
||||||
echo '#else' >> example_single_file.cpp
|
|
||||||
echo '# define IMGUI_API __declspec(dllimport)' >> example_single_file.cpp
|
|
||||||
echo '#endif' >> example_single_file.cpp
|
|
||||||
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
|
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
|
||||||
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
|
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
|
||||||
g++ -I. -Wall -Wformat -D_EXPORT -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32
|
g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32
|
||||||
g++ -I. -Wall -Wformat -o example_null.exe examples/example_null/main.cpp -L. -limgui
|
g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp -L. -limgui
|
||||||
rm -f example_null.exe libimgui.* example_single_file.*
|
rm -f example_null.exe libimgui.* example_single_file.*
|
||||||
|
|
||||||
- name: Build example_null (extra warnings, msvc 64-bit)
|
- name: Build example_null (extra warnings, msvc 64-bit)
|
||||||
@@ -99,20 +99,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
|
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
|
|
||||||
echo #ifdef _EXPORT > example_single_file.cpp
|
echo #define IMGUI_API __declspec(dllexport) > example_single_file.cpp
|
||||||
echo # define IMGUI_API __declspec(dllexport) >> example_single_file.cpp
|
|
||||||
echo #else >> example_single_file.cpp
|
|
||||||
echo # define IMGUI_API __declspec(dllimport) >> example_single_file.cpp
|
|
||||||
echo #endif >> example_single_file.cpp
|
|
||||||
echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp
|
echo #define IMGUI_IMPLEMENTATION >> example_single_file.cpp
|
||||||
echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp
|
echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp
|
||||||
|
|
||||||
cl.exe /D_USRDLL /D_WINDLL /D_EXPORT /I. example_single_file.cpp /LD /FeImGui.dll /link
|
cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link
|
||||||
cl.exe /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
|
cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
|
||||||
|
|
||||||
|
# Win64 examples are more frequently compilted than the Win32 examples.
|
||||||
|
# More of the Win32 examples requires 'workflow_run' to reduce waste.
|
||||||
- name: Build Win32 example_glfw_opengl2
|
- name: Build Win32 example_glfw_opengl2
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build Win32 example_glfw_opengl3
|
- name: Build Win32 example_glfw_opengl3
|
||||||
shell: cmd
|
shell: cmd
|
||||||
@@ -148,77 +147,116 @@ jobs:
|
|||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build Win32 example_sdl3_opengl3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
|
||||||
|
- name: Build Win32 example_sdl3_sdlgpu3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build Win32 example_sdl3_sdlrenderer3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build Win32 example_sdl3_vulkan
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build Win32 example_win32_directx9
|
- name: Build Win32 example_win32_directx9
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build Win32 example_win32_directx10
|
- name: Build Win32 example_win32_directx10
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build Win32 example_win32_directx11
|
- name: Build Win32 example_win32_directx11
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_glfw_opengl2
|
# Windows 64-bits
|
||||||
|
- name: Build Win64 example_glfw_opengl2
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_glfw_opengl3
|
- name: Build Win64 example_glfw_opengl3
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
- name: Build x64 example_glfw_vulkan
|
- name: Build Win64 example_glfw_vulkan
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
- name: Build x64 example_sdl2_sdlrenderer2
|
- name: Build Win64 example_sdl2_sdlrenderer2
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_sdl2_vulkan
|
- name: Build Win64 example_sdl2_vulkan
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_sdl2_opengl2
|
- name: Build Win64 example_sdl2_opengl2
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_sdl2_opengl3
|
- name: Build Win64 example_sdl2_opengl3
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_sdl2_directx11
|
- name: Build Win64 example_sdl2_directx11
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
- name: Build x64 example_win32_directx9
|
- name: Build Win64 example_sdl3_opengl3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build Win64 example_sdl3_sdlgpu3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
|
- name: Build Win64 example_sdl3_sdlrenderer3
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
|
- name: Build Win64 example_sdl3_vulkan
|
||||||
|
shell: cmd
|
||||||
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build Win64 example_win32_directx9
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_win32_directx10
|
- name: Build Win64 example_win32_directx10
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
- name: Build x64 example_win32_directx11
|
- name: Build Win64 example_win32_directx11
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
if: github.event_name == 'workflow_run'
|
|
||||||
|
|
||||||
- name: Build x64 example_win32_directx12
|
- name: Build Win64 example_win32_directx12
|
||||||
shell: cmd
|
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'
|
||||||
|
|
||||||
Linux:
|
Linux:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -441,7 +479,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run: |
|
||||||
brew install glfw3 sdl2
|
brew install glfw3 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
|
||||||
@@ -499,6 +537,9 @@ jobs:
|
|||||||
- name: Build example_sdl2_opengl3
|
- name: Build example_sdl2_opengl3
|
||||||
run: make -C examples/example_sdl2_opengl3
|
run: make -C examples/example_sdl2_opengl3
|
||||||
|
|
||||||
|
- name: Build example_sdl3_opengl3
|
||||||
|
run: make -C examples/example_sdl3_opengl3
|
||||||
|
|
||||||
- name: Build example_apple_metal
|
- name: Build example_apple_metal
|
||||||
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
|
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
|
||||||
|
|
||||||
@@ -516,7 +557,7 @@ jobs:
|
|||||||
xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_ios CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
|
xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_ios CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
|
||||||
|
|
||||||
Emscripten:
|
Emscripten:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
@@ -557,7 +598,7 @@ jobs:
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
Android:
|
Android:
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/static-analysis.yml
vendored
4
.github/workflows/static-analysis.yml
vendored
@@ -10,7 +10,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
PVS-Studio:
|
PVS-Studio:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@@ -42,5 +42,5 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
cd examples/example_null
|
cd examples/example_null
|
||||||
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
|
pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1
|
||||||
pvs-studio-analyzer analyze --disableLicenseExpirationCheck -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
|
pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log
|
||||||
plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log
|
plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log
|
||||||
|
|||||||
20
.gitignore
vendored
20
.gitignore
vendored
@@ -29,12 +29,14 @@ ipch
|
|||||||
## Getting files created in JSON/Schemas/Catalog/ from a VS2022 update
|
## Getting files created in JSON/Schemas/Catalog/ from a VS2022 update
|
||||||
JSON/
|
JSON/
|
||||||
|
|
||||||
## Commonly used CMake directories
|
## Commonly used CMake directories & CMake CPM cache
|
||||||
build*/
|
build*/
|
||||||
|
.cache
|
||||||
|
|
||||||
## Xcode artifacts
|
## Xcode & macOS artifacts
|
||||||
project.xcworkspace
|
project.xcworkspace
|
||||||
xcuserdata
|
xcuserdata
|
||||||
|
examples/*/*.dSYM
|
||||||
|
|
||||||
## Emscripten artifacts
|
## Emscripten artifacts
|
||||||
examples/*.o.tmp
|
examples/*.o.tmp
|
||||||
@@ -49,13 +51,25 @@ examples/example_sdl2_opengl3/web/*
|
|||||||
.idea
|
.idea
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
|
|
||||||
|
## VS code artifacts
|
||||||
|
.vscode
|
||||||
|
|
||||||
## Unix executables from our example Makefiles
|
## Unix executables from our example Makefiles
|
||||||
|
examples/example_apple_metal/example_apple_metal
|
||||||
|
examples/example_apple_opengl2/example_apple_opengl2
|
||||||
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
|
||||||
|
examples/example_glfw_vulkan/example_glfw_vulkan
|
||||||
examples/example_glut_opengl2/example_glut_opengl2
|
examples/example_glut_opengl2/example_glut_opengl2
|
||||||
examples/example_null/example_null
|
examples/example_null/example_null
|
||||||
examples/example_sdl2_metal/example_sdl2_metal
|
examples/example_sdl2_metal/example_sdl2_metal
|
||||||
examples/example_sdl2_opengl2/example_sdl2_opengl2
|
examples/example_sdl2_opengl2/example_sdl2_opengl2
|
||||||
examples/example_sdl2_opengl3/example_sdl2_opengl3
|
examples/example_sdl2_opengl3/example_sdl2_opengl3
|
||||||
examples/example_sdl2_sdlrenderer/example_sdl2_sdlrenderer
|
examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2
|
||||||
|
examples/example_sdl2_vulkan/example_sdl2_vulkan
|
||||||
|
examples/example_sdl3_metal/example_sdl3_metal
|
||||||
|
examples/example_sdl3_opengl3/example_sdl3_opengl3
|
||||||
|
examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3
|
||||||
|
examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3
|
||||||
|
examples/example_sdl3_vulkan/example_sdl3_vulkan
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2024 Omar Cornut
|
Copyright (c) 2014-2025 Omar Cornut
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [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 ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
// [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 ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||||
// Missing features:
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows)..
|
// Missing features or Issues:
|
||||||
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
|
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||||
// [ ] 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.
|
||||||
@@ -21,6 +22,12 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
|
// 2025-08-12: Inputs: fixed missing support for ImGuiKey_PrintScreen under Windows, as raw Allegro 5 does not receive it.
|
||||||
|
// 2025-08-12: Added ImGui_ImplAllegro5_SetDisplay() function to change current ALLEGRO_DISPLAY, as Allegro applications often need to do that.
|
||||||
|
// 2025-07-07: Fixed texture update broken on some platforms where ALLEGRO_LOCK_WRITEONLY needed all texels to be rewritten.
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
|
||||||
|
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
|
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
||||||
// 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
|
||||||
@@ -96,6 +103,7 @@ struct ImGui_ImplAllegro5_Data
|
|||||||
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
|
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
|
||||||
ALLEGRO_VERTEX_DECL* VertexDecl;
|
ALLEGRO_VERTEX_DECL* VertexDecl;
|
||||||
char* ClipboardTextData;
|
char* ClipboardTextData;
|
||||||
|
ImGuiMouseCursor LastCursor;
|
||||||
|
|
||||||
ImVector<ImDrawVertAllegro> BufVertices;
|
ImVector<ImDrawVertAllegro> BufVertices;
|
||||||
ImVector<int> BufIndices;
|
ImVector<int> BufIndices;
|
||||||
@@ -135,6 +143,13 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplAllegro5_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup Allegro state that will be modified
|
// Backup Allegro state that will be modified
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
|
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
|
||||||
@@ -148,16 +163,14 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
||||||
|
|
||||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||||
vertices.resize(cmd_list->VtxBuffer.Size);
|
vertices.resize(draw_list->VtxBuffer.Size);
|
||||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||||
{
|
{
|
||||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i];
|
const ImDrawVert* src_v = &draw_list->VtxBuffer[i];
|
||||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||||
}
|
}
|
||||||
@@ -167,21 +180,21 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// FIXME-OPT: Allegro doesn't support 16-bit indices.
|
// FIXME-OPT: Allegro doesn't support 16-bit indices.
|
||||||
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
||||||
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
|
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
|
||||||
bd->BufIndices.resize(cmd_list->IdxBuffer.Size);
|
bd->BufIndices.resize(draw_list->IdxBuffer.Size);
|
||||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
|
for (int i = 0; i < draw_list->IdxBuffer.Size; ++i)
|
||||||
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i];
|
bd->BufIndices[i] = (int)draw_list->IdxBuffer.Data[i];
|
||||||
indices = bd->BufIndices.Data;
|
indices = bd->BufIndices.Data;
|
||||||
}
|
}
|
||||||
else if (sizeof(ImDrawIdx) == 4)
|
else if (sizeof(ImDrawIdx) == 4)
|
||||||
{
|
{
|
||||||
indices = (const int*)cmd_list->IdxBuffer.Data;
|
indices = (const int*)draw_list->IdxBuffer.Data;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
|
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
|
||||||
vertices.resize(cmd_list->IdxBuffer.Size);
|
vertices.resize(draw_list->IdxBuffer.Size);
|
||||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
|
for (int i = 0; i < draw_list->IdxBuffer.Size; i++)
|
||||||
{
|
{
|
||||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
|
const ImDrawVert* src_v = &draw_list->VtxBuffer[draw_list->IdxBuffer[i]];
|
||||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||||
}
|
}
|
||||||
@@ -189,9 +202,9 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -199,7 +212,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -230,43 +243,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
|||||||
|
|
||||||
bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
||||||
|
|
||||||
// Create texture
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
int flags = al_get_new_bitmap_flags();
|
|
||||||
int fmt = al_get_new_bitmap_format();
|
|
||||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
|
||||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
|
||||||
ALLEGRO_BITMAP* img = al_create_bitmap(width, height);
|
|
||||||
al_set_new_bitmap_flags(flags);
|
|
||||||
al_set_new_bitmap_format(fmt);
|
|
||||||
if (!img)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ALLEGRO_LOCKED_REGION* locked_img = al_lock_bitmap(img, al_get_bitmap_format(img), ALLEGRO_LOCK_WRITEONLY);
|
|
||||||
if (!locked_img)
|
|
||||||
{
|
|
||||||
al_destroy_bitmap(img);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(locked_img->data, pixels, sizeof(int) * width * height);
|
|
||||||
al_unlock_bitmap(img);
|
|
||||||
|
|
||||||
// Convert software texture to hardware texture.
|
|
||||||
ALLEGRO_BITMAP* cloned_img = al_clone_bitmap(img);
|
|
||||||
al_destroy_bitmap(img);
|
|
||||||
if (!cloned_img)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)cloned_img);
|
|
||||||
bd->Texture = cloned_img;
|
|
||||||
|
|
||||||
// Create an invisible mouse cursor
|
// Create an invisible mouse cursor
|
||||||
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
|
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
|
||||||
@@ -277,16 +254,82 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
// (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();
|
||||||
|
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_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||||
|
ALLEGRO_BITMAP* cpu_bitmap = al_create_bitmap(tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(cpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Upload pixels
|
||||||
|
ALLEGRO_LOCKED_REGION* locked_region = al_lock_bitmap(cpu_bitmap, al_get_bitmap_format(cpu_bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||||
|
IM_ASSERT(locked_region != nullptr && "Backend failed to create texture!");
|
||||||
|
memcpy(locked_region->data, tex->GetPixels(), tex->GetSizeInBytes());
|
||||||
|
al_unlock_bitmap(cpu_bitmap);
|
||||||
|
|
||||||
|
// Convert software texture to hardware texture.
|
||||||
|
al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
|
||||||
|
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA);
|
||||||
|
ALLEGRO_BITMAP* gpu_bitmap = al_clone_bitmap(cpu_bitmap);
|
||||||
|
al_destroy_bitmap(cpu_bitmap);
|
||||||
|
IM_ASSERT(gpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
al_set_new_bitmap_flags(new_bitmap_flags);
|
||||||
|
al_set_new_bitmap_format(new_bitmap_format);
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)gpu_bitmap);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
ImTextureRect r = tex->UpdateRect; // Bounding box encompassing all individual updates
|
||||||
|
ALLEGRO_BITMAP* gpu_bitmap = (ALLEGRO_BITMAP*)(intptr_t)tex->TexID;
|
||||||
|
ALLEGRO_LOCKED_REGION* locked_region = al_lock_bitmap_region(gpu_bitmap, r.x, r.y, r.w, r.h, al_get_bitmap_format(gpu_bitmap), ALLEGRO_LOCK_WRITEONLY);
|
||||||
|
IM_ASSERT(locked_region && "Backend failed to update texture!");
|
||||||
|
for (int y = 0; y < r.h; y++)
|
||||||
|
memcpy((unsigned char*)locked_region->data + locked_region->pitch * y, tex->GetPixelsAt(r.x, r.y + y), r.w * tex->BytesPerPixel); // dst, src, block pitch
|
||||||
|
al_unlock_bitmap(gpu_bitmap);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
ALLEGRO_BITMAP* backend_tex = (ALLEGRO_BITMAP*)(intptr_t)tex->TexID;
|
||||||
|
if (backend_tex)
|
||||||
|
al_destroy_bitmap(backend_tex);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
if (bd->Texture)
|
|
||||||
{
|
// Destroy all textures
|
||||||
io.Fonts->SetTexID(0);
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
al_destroy_bitmap(bd->Texture);
|
if (tex->RefCount == 1)
|
||||||
bd->Texture = nullptr;
|
{
|
||||||
}
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplAllegro5_UpdateTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy mouse cursor
|
||||||
if (bd->MouseCursorInvisible)
|
if (bd->MouseCursorInvisible)
|
||||||
{
|
{
|
||||||
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
|
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
|
||||||
@@ -312,6 +355,7 @@ static void ImGui_ImplAllegro5_SetClipboardText(ImGuiContext*, const char* text)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code);
|
||||||
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||||
{
|
{
|
||||||
switch (key_code)
|
switch (key_code)
|
||||||
@@ -436,20 +480,11 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
|||||||
io.BackendPlatformUserData = (void*)bd;
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
|
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||||
|
|
||||||
bd->Display = display;
|
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
||||||
|
|
||||||
// Create custom vertex declaration.
|
ImGui_ImplAllegro5_SetDisplay(display);
|
||||||
// Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats.
|
|
||||||
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
|
|
||||||
ALLEGRO_VERTEX_ELEMENT elems[] =
|
|
||||||
{
|
|
||||||
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
|
|
||||||
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
|
|
||||||
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
|
||||||
|
|
||||||
#if ALLEGRO_HAS_CLIPBOARD
|
#if ALLEGRO_HAS_CLIPBOARD
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
@@ -474,10 +509,37 @@ void ImGui_ImplAllegro5_Shutdown()
|
|||||||
|
|
||||||
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors;
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_RendererHasTextures);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAllegro5_SetDisplay(ALLEGRO_DISPLAY* display)
|
||||||
|
{
|
||||||
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
|
bd->Display = display;
|
||||||
|
|
||||||
|
if (bd->VertexDecl)
|
||||||
|
{
|
||||||
|
al_destroy_vertex_decl(bd->VertexDecl);
|
||||||
|
bd->VertexDecl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bd->Display && !bd->VertexDecl)
|
||||||
|
{
|
||||||
|
// Create custom vertex declaration.
|
||||||
|
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
|
||||||
|
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
|
||||||
|
ALLEGRO_VERTEX_ELEMENT elems[] =
|
||||||
|
{
|
||||||
|
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
|
||||||
|
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
|
||||||
|
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
|
||||||
|
{ 0, 0, 0 }
|
||||||
|
};
|
||||||
|
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ev->keyboard.modifiers seems always zero so using that...
|
// ev->keyboard.modifiers seems always zero so using that...
|
||||||
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
|
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
|
||||||
{
|
{
|
||||||
@@ -568,9 +630,16 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
|||||||
|
|
||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
|
||||||
|
// Hide OS mouse cursor if imgui is drawing it
|
||||||
|
if (io.MouseDrawCursor)
|
||||||
|
imgui_cursor = ImGuiMouseCursor_None;
|
||||||
|
|
||||||
|
if (bd->LastCursor == imgui_cursor)
|
||||||
|
return;
|
||||||
|
bd->LastCursor = imgui_cursor;
|
||||||
|
if (imgui_cursor == ImGuiMouseCursor_None)
|
||||||
{
|
{
|
||||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
|
||||||
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
|
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -584,6 +653,8 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
|||||||
case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break;
|
case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break;
|
||||||
case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break;
|
case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break;
|
||||||
case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break;
|
case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break;
|
||||||
|
case ImGuiMouseCursor_Wait: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_BUSY; break;
|
||||||
|
case ImGuiMouseCursor_Progress: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_PROGRESS; break;
|
||||||
case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break;
|
case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break;
|
||||||
}
|
}
|
||||||
al_set_system_mouse_cursor(bd->Display, cursor_id);
|
al_set_system_mouse_cursor(bd->Display, cursor_id);
|
||||||
@@ -595,12 +666,11 @@ void ImGui_ImplAllegro5_NewFrame()
|
|||||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
||||||
|
|
||||||
if (!bd->Texture)
|
if (!bd->MouseCursorInvisible)
|
||||||
ImGui_ImplAllegro5_CreateDeviceObjects();
|
ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
int w, h;
|
int w, h;
|
||||||
w = al_get_display_width(bd->Display);
|
w = al_get_display_width(bd->Display);
|
||||||
h = al_get_display_height(bd->Display);
|
h = al_get_display_height(bd->Display);
|
||||||
@@ -611,6 +681,11 @@ void ImGui_ImplAllegro5_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;
|
||||||
|
|
||||||
|
// Allegro 5 doesn't receive PrintScreen under Windows
|
||||||
|
#ifdef _WIN32
|
||||||
|
io.AddKeyEvent(ImGuiKey_PrintScreen, (::GetAsyncKeyState(VK_SNAPSHOT) & 0x8000) != 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Setup mouse cursor shape
|
// Setup mouse cursor shape
|
||||||
ImGui_ImplAllegro5_UpdateMouseCursor();
|
ImGui_ImplAllegro5_UpdateMouseCursor();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
// (Info: Allegro 5 is a cross-platform general purpose library for handling windows, inputs, graphics, etc.)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [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 ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
// [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 ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||||
// Missing features:
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows)..
|
// Missing features or Issues:
|
||||||
// [ ] 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.
|
||||||
// [ ] 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.
|
||||||
@@ -32,9 +33,13 @@ IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
|
||||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data);
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
|
IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_SetDisplay(ALLEGRO_DISPLAY* display);
|
||||||
|
|
||||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [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 AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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 AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// Missing features:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Clipboard support.
|
// [ ] Platform: Clipboard support.
|
||||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [ ] Platform: Gamepad support.
|
||||||
// [ ] Platform: Mouse cursor shape and visibility. 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.
|
// [ ] 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.
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [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 AKEYCODE_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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 AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// Missing features:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Clipboard support.
|
// [ ] Platform: Clipboard support.
|
||||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [ ] Platform: Gamepad support.
|
||||||
// [ ] Platform: Mouse cursor shape and visibility. 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.
|
// [ ] 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.
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -16,7 +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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-11: DirectX10: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||||
|
// 2025-05-07: DirectX10: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||||
|
// 2025-01-06: DirectX10: Expose selected render state in ImGui_ImplDX10_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
|
// 2024-10-07: DirectX10: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 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-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
@@ -47,7 +52,19 @@
|
|||||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DirectX data
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DirectX10 data
|
||||||
|
struct ImGui_ImplDX10_Texture
|
||||||
|
{
|
||||||
|
ID3D10Texture2D* pTexture;
|
||||||
|
ID3D10ShaderResourceView* pTextureView;
|
||||||
|
};
|
||||||
|
|
||||||
struct ImGui_ImplDX10_Data
|
struct ImGui_ImplDX10_Data
|
||||||
{
|
{
|
||||||
ID3D10Device* pd3dDevice;
|
ID3D10Device* pd3dDevice;
|
||||||
@@ -59,7 +76,6 @@ struct ImGui_ImplDX10_Data
|
|||||||
ID3D10Buffer* pVertexConstantBuffer;
|
ID3D10Buffer* pVertexConstantBuffer;
|
||||||
ID3D10PixelShader* pPixelShader;
|
ID3D10PixelShader* pPixelShader;
|
||||||
ID3D10SamplerState* pFontSampler;
|
ID3D10SamplerState* pFontSampler;
|
||||||
ID3D10ShaderResourceView* pFontTextureView;
|
|
||||||
ID3D10RasterizerState* pRasterizerState;
|
ID3D10RasterizerState* pRasterizerState;
|
||||||
ID3D10BlendState* pBlendState;
|
ID3D10BlendState* pBlendState;
|
||||||
ID3D10DepthStencilState* pDepthStencilState;
|
ID3D10DepthStencilState* pDepthStencilState;
|
||||||
@@ -82,106 +98,28 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplDX10_InitPlatformInterface();
|
static void ImGui_ImplDX10_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplDX10_ShutdownPlatformInterface();
|
static void ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D10_VIEWPORT vp;
|
D3D10_VIEWPORT vp = {};
|
||||||
memset(&vp, 0, sizeof(D3D10_VIEWPORT));
|
vp.Width = (UINT)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||||
vp.Width = (UINT)draw_data->DisplaySize.x;
|
vp.Height = (UINT)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||||
vp.Height = (UINT)draw_data->DisplaySize.y;
|
|
||||||
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;
|
||||||
ctx->RSSetViewports(1, &vp);
|
device->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// Bind shader and vertex buffers
|
|
||||||
unsigned int stride = sizeof(ImDrawVert);
|
|
||||||
unsigned int offset = 0;
|
|
||||||
ctx->IASetInputLayout(bd->pInputLayout);
|
|
||||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
|
||||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
|
||||||
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
||||||
ctx->VSSetShader(bd->pVertexShader);
|
|
||||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
|
||||||
ctx->PSSetShader(bd->pPixelShader);
|
|
||||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
|
||||||
ctx->GSSetShader(nullptr);
|
|
||||||
|
|
||||||
// Setup render state
|
|
||||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
|
||||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
|
||||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
|
||||||
ctx->RSSetState(bd->pRasterizerState);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render function
|
|
||||||
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|
||||||
{
|
|
||||||
// Avoid rendering when minimized
|
|
||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
|
||||||
ID3D10Device* ctx = bd->pd3dDevice;
|
|
||||||
|
|
||||||
// Create and grow vertex/index buffers if needed
|
|
||||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
|
||||||
{
|
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
|
||||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
|
||||||
D3D10_BUFFER_DESC desc;
|
|
||||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
|
||||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
|
||||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
|
||||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
|
||||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
|
||||||
desc.MiscFlags = 0;
|
|
||||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
|
||||||
{
|
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
|
||||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
|
||||||
D3D10_BUFFER_DESC desc;
|
|
||||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
|
||||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
|
||||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
|
||||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
|
||||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
|
||||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy and convert all vertices into a single contiguous buffer
|
|
||||||
ImDrawVert* vtx_dst = nullptr;
|
|
||||||
ImDrawIdx* idx_dst = nullptr;
|
|
||||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
|
||||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
||||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
|
||||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
|
||||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
|
||||||
idx_dst += cmd_list->IdxBuffer.Size;
|
|
||||||
}
|
|
||||||
bd->pVB->Unmap();
|
|
||||||
bd->pIB->Unmap();
|
|
||||||
|
|
||||||
// Setup orthographic projection matrix into our constant buffer
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
// 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.
|
||||||
|
void* mapped_resource;
|
||||||
|
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||||
{
|
{
|
||||||
void* mapped_resource;
|
|
||||||
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
|
||||||
return;
|
|
||||||
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
|
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
|
||||||
float L = draw_data->DisplayPos.x;
|
float L = draw_data->DisplayPos.x;
|
||||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
@@ -198,6 +136,86 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||||||
bd->pVertexConstantBuffer->Unmap();
|
bd->pVertexConstantBuffer->Unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
device->IASetInputLayout(bd->pInputLayout);
|
||||||
|
device->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
|
device->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
device->VSSetShader(bd->pVertexShader);
|
||||||
|
device->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
|
device->PSSetShader(bd->pPixelShader);
|
||||||
|
device->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||||
|
device->GSSetShader(nullptr);
|
||||||
|
|
||||||
|
// Setup render state
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
device->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||||
|
device->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||||
|
device->RSSetState(bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
ID3D10Device* device = bd->pd3dDevice;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplDX10_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D10_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (device->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D10_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||||
|
if (device->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy and convert all vertices into a single contiguous buffer
|
||||||
|
ImDrawVert* vtx_dst = nullptr;
|
||||||
|
ImDrawIdx* idx_dst = nullptr;
|
||||||
|
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||||
|
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
bd->pVB->Unmap();
|
||||||
|
bd->pIB->Unmap();
|
||||||
|
|
||||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||||
struct BACKUP_DX10_STATE
|
struct BACKUP_DX10_STATE
|
||||||
{
|
{
|
||||||
@@ -223,100 +241,126 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
|||||||
};
|
};
|
||||||
BACKUP_DX10_STATE old = {};
|
BACKUP_DX10_STATE old = {};
|
||||||
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||||
ctx->RSGetState(&old.RS);
|
device->RSGetState(&old.RS);
|
||||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||||
ctx->PSGetShader(&old.PS);
|
device->PSGetShader(&old.PS);
|
||||||
ctx->VSGetShader(&old.VS);
|
device->VSGetShader(&old.VS);
|
||||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||||
ctx->GSGetShader(&old.GS);
|
device->GSGetShader(&old.GS);
|
||||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||||
ctx->IAGetInputLayout(&old.InputLayout);
|
device->IAGetInputLayout(&old.InputLayout);
|
||||||
|
|
||||||
// Setup desired DX state
|
// Setup desired DX state
|
||||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplDX10_RenderState render_state;
|
||||||
|
render_state.Device = bd->pd3dDevice;
|
||||||
|
render_state.SamplerDefault = bd->pFontSampler;
|
||||||
|
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
int global_vtx_offset = 0;
|
int global_vtx_offset = 0;
|
||||||
int global_idx_offset = 0;
|
int global_idx_offset = 0;
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
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;
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle
|
// Apply scissor/clipping rectangle
|
||||||
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
ctx->RSSetScissorRects(1, &r);
|
device->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
|
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
|
||||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
|
|
||||||
// Restore modified DX state
|
// Restore modified DX state
|
||||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||||
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
device->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||||
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
device->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||||
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
device->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX10_CreateFontsTexture()
|
static void ImGui_ImplDX10_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData;
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
if (backend_tex == nullptr)
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
return;
|
||||||
unsigned char* pixels;
|
IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
int width, height;
|
backend_tex->pTexture->Release();
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
backend_tex->pTextureView->Release();
|
||||||
|
IM_DELETE(backend_tex);
|
||||||
|
|
||||||
// Upload texture to graphics system
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
tex->BackendUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX10_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
{
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
unsigned int* pixels = (unsigned int*)tex->GetPixels();
|
||||||
|
ImGui_ImplDX10_Texture* backend_tex = IM_NEW(ImGui_ImplDX10_Texture)();
|
||||||
|
|
||||||
|
// Create texture
|
||||||
D3D10_TEXTURE2D_DESC desc;
|
D3D10_TEXTURE2D_DESC desc;
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
desc.Width = width;
|
desc.Width = (UINT)tex->Width;
|
||||||
desc.Height = height;
|
desc.Height = (UINT)tex->Height;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
@@ -325,13 +369,12 @@ static void ImGui_ImplDX10_CreateFontsTexture()
|
|||||||
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
|
||||||
desc.CPUAccessFlags = 0;
|
desc.CPUAccessFlags = 0;
|
||||||
|
|
||||||
ID3D10Texture2D* pTexture = nullptr;
|
|
||||||
D3D10_SUBRESOURCE_DATA subResource;
|
D3D10_SUBRESOURCE_DATA subResource;
|
||||||
subResource.pSysMem = pixels;
|
subResource.pSysMem = pixels;
|
||||||
subResource.SysMemPitch = desc.Width * 4;
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
subResource.SysMemSlicePitch = 0;
|
subResource.SysMemSlicePitch = 0;
|
||||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &backend_tex->pTexture);
|
||||||
IM_ASSERT(pTexture != nullptr);
|
IM_ASSERT(backend_tex->pTexture != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
// Create texture view
|
// Create texture view
|
||||||
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||||
@@ -340,28 +383,29 @@ static void ImGui_ImplDX10_CreateFontsTexture()
|
|||||||
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
|
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
|
||||||
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
srv_desc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srv_desc, &bd->pFontTextureView);
|
bd->pd3dDevice->CreateShaderResourceView(backend_tex->pTexture, &srv_desc, &backend_tex->pTextureView);
|
||||||
pTexture->Release();
|
IM_ASSERT(backend_tex->pTextureView != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)backend_tex->pTextureView);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
tex->BackendUserData = backend_tex;
|
||||||
}
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
|
||||||
|
|
||||||
// Create texture sampler
|
|
||||||
// (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;
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData;
|
||||||
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
|
IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
|
for (ImTextureRect& r : tex->Updates)
|
||||||
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
|
{
|
||||||
desc.MipLODBias = 0.f;
|
D3D10_BOX box = { (UINT)r.x, (UINT)r.y, (UINT)0, (UINT)(r.x + r.w), (UINT)(r.y + r.h), (UINT)1 };
|
||||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
bd->pd3dDevice->UpdateSubresource(backend_tex->pTexture, 0, &box, tex->GetPixelsAt(r.x, r.y), (UINT)tex->GetPitch(), 0);
|
||||||
desc.MinLOD = 0.f;
|
}
|
||||||
desc.MaxLOD = 0.f;
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
|
||||||
}
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
ImGui_ImplDX10_DestroyTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX10_CreateDeviceObjects()
|
bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||||
@@ -369,8 +413,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
|||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
if (!bd->pd3dDevice)
|
if (!bd->pd3dDevice)
|
||||||
return false;
|
return false;
|
||||||
if (bd->pFontSampler)
|
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
|
||||||
|
|
||||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
// If you would like to use this DX10 sample code but remove this dependency you can:
|
// If you would like to use this DX10 sample code but remove this dependency you can:
|
||||||
@@ -433,7 +476,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
|||||||
|
|
||||||
// Create the constant buffer
|
// Create the constant buffer
|
||||||
{
|
{
|
||||||
D3D10_BUFFER_DESC desc;
|
D3D10_BUFFER_DESC desc = {};
|
||||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX10);
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX10);
|
||||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||||
desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
|
desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
|
||||||
@@ -513,7 +556,21 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
|||||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui_ImplDX10_CreateFontsTexture();
|
// Create texture sampler
|
||||||
|
// (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;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.MipLODBias = 0.f;
|
||||||
|
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||||
|
desc.MinLOD = 0.f;
|
||||||
|
desc.MaxLOD = 0.f;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -524,8 +581,11 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
|
|||||||
if (!bd->pd3dDevice)
|
if (!bd->pd3dDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplDX10_DestroyTexture(tex);
|
||||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
@@ -548,8 +608,12 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
|
|
||||||
// Get factory from device
|
// Get factory from device
|
||||||
IDXGIDevice* pDXGIDevice = nullptr;
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
IDXGIAdapter* pDXGIAdapter = nullptr;
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
@@ -565,8 +629,8 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
|||||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||||
bd->pd3dDevice->AddRef();
|
bd->pd3dDevice->AddRef();
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
ImGui_ImplDX10_InitMultiViewportSupport();
|
||||||
ImGui_ImplDX10_InitPlatformInterface();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -576,13 +640,13 @@ void ImGui_ImplDX10_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplDX10_ShutdownPlatformInterface();
|
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_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,8 +655,9 @@ void ImGui_ImplDX10_NewFrame()
|
|||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?");
|
||||||
|
|
||||||
if (!bd->pFontSampler)
|
if (!bd->pVertexShader)
|
||||||
ImGui_ImplDX10_CreateDeviceObjects();
|
if (!ImGui_ImplDX10_CreateDeviceObjects())
|
||||||
|
IM_ASSERT(0 && "ImGui_ImplDX10_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
@@ -617,7 +682,7 @@ static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
|
|||||||
ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)();
|
ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)();
|
||||||
viewport->RendererUserData = vd;
|
viewport->RendererUserData = vd;
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
// 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.
|
// 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;
|
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||||
IM_ASSERT(hwnd != 0);
|
IM_ASSERT(hwnd != 0);
|
||||||
@@ -703,7 +768,7 @@ static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
|||||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplDX10_InitPlatformInterface()
|
void ImGui_ImplDX10_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
||||||
@@ -713,7 +778,7 @@ void ImGui_ImplDX10_InitPlatformInterface()
|
|||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplDX10_ShutdownPlatformInterface()
|
void ImGui_ImplDX10_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -19,6 +20,8 @@
|
|||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
struct ID3D10Device;
|
struct ID3D10Device;
|
||||||
|
struct ID3D10SamplerState;
|
||||||
|
struct ID3D10Buffer;
|
||||||
|
|
||||||
// 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_ImplDX10_Init(ID3D10Device* device);
|
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
||||||
@@ -27,7 +30,20 @@ IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
// 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 void ImGui_ImplDX10_InvalidateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX10_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX10_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplDX10_RenderState
|
||||||
|
{
|
||||||
|
ID3D10Device* Device;
|
||||||
|
ID3D10SamplerState* SamplerDefault;
|
||||||
|
ID3D10Buffer* VertexConstantBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -16,13 +18,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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-11: DirectX11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||||
|
// 2025-05-07: DirectX11: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||||
|
// 2025-02-24: [Docking] Added undocumented ImGui_ImplDX11_SetSwapChainDescs() to configure swap chain creation for secondary viewports.
|
||||||
|
// 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: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 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-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||||
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||||
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||||
@@ -47,7 +55,19 @@
|
|||||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
// DirectX11 data
|
// DirectX11 data
|
||||||
|
struct ImGui_ImplDX11_Texture
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* pTexture;
|
||||||
|
ID3D11ShaderResourceView* pTextureView;
|
||||||
|
};
|
||||||
|
|
||||||
struct ImGui_ImplDX11_Data
|
struct ImGui_ImplDX11_Data
|
||||||
{
|
{
|
||||||
ID3D11Device* pd3dDevice;
|
ID3D11Device* pd3dDevice;
|
||||||
@@ -60,12 +80,12 @@ struct ImGui_ImplDX11_Data
|
|||||||
ID3D11Buffer* pVertexConstantBuffer;
|
ID3D11Buffer* pVertexConstantBuffer;
|
||||||
ID3D11PixelShader* pPixelShader;
|
ID3D11PixelShader* pPixelShader;
|
||||||
ID3D11SamplerState* pFontSampler;
|
ID3D11SamplerState* pFontSampler;
|
||||||
ID3D11ShaderResourceView* pFontTextureView;
|
|
||||||
ID3D11RasterizerState* pRasterizerState;
|
ID3D11RasterizerState* pRasterizerState;
|
||||||
ID3D11BlendState* pBlendState;
|
ID3D11BlendState* pBlendState;
|
||||||
ID3D11DepthStencilState* pDepthStencilState;
|
ID3D11DepthStencilState* pDepthStencilState;
|
||||||
int VertexBufferSize;
|
int VertexBufferSize;
|
||||||
int IndexBufferSize;
|
int IndexBufferSize;
|
||||||
|
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; }
|
||||||
};
|
};
|
||||||
@@ -83,111 +103,28 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplDX11_InitPlatformInterface();
|
static void ImGui_ImplDX11_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplDX11_ShutdownPlatformInterface();
|
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D11_VIEWPORT vp;
|
D3D11_VIEWPORT vp = {};
|
||||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
||||||
vp.Width = draw_data->DisplaySize.x;
|
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
||||||
vp.Height = draw_data->DisplaySize.y;
|
|
||||||
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;
|
||||||
ctx->RSSetViewports(1, &vp);
|
device_ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// Setup shader and vertex buffers
|
|
||||||
unsigned int stride = sizeof(ImDrawVert);
|
|
||||||
unsigned int offset = 0;
|
|
||||||
ctx->IASetInputLayout(bd->pInputLayout);
|
|
||||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
|
||||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
|
||||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
|
||||||
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
|
||||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
|
||||||
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
|
||||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
|
||||||
ctx->GSSetShader(nullptr, nullptr, 0);
|
|
||||||
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
|
||||||
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
|
||||||
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
|
||||||
|
|
||||||
// Setup blend state
|
|
||||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
|
||||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
|
||||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
|
||||||
ctx->RSSetState(bd->pRasterizerState);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render function
|
|
||||||
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|
||||||
{
|
|
||||||
// Avoid rendering when minimized
|
|
||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
|
||||||
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
|
||||||
|
|
||||||
// Create and grow vertex/index buffers if needed
|
|
||||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
|
||||||
{
|
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
|
||||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
|
||||||
D3D11_BUFFER_DESC desc;
|
|
||||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
|
||||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
|
||||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
|
||||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
||||||
desc.MiscFlags = 0;
|
|
||||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
|
||||||
{
|
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
|
||||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
|
||||||
D3D11_BUFFER_DESC desc;
|
|
||||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
|
||||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
|
||||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
|
||||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
||||||
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload vertex/index data into a single contiguous GPU buffer
|
|
||||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
|
||||||
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
|
||||||
return;
|
|
||||||
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
|
||||||
return;
|
|
||||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
|
||||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
||||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
|
||||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
|
||||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
|
||||||
idx_dst += cmd_list->IdxBuffer.Size;
|
|
||||||
}
|
|
||||||
ctx->Unmap(bd->pVB, 0);
|
|
||||||
ctx->Unmap(bd->pIB, 0);
|
|
||||||
|
|
||||||
// Setup orthographic projection matrix into our constant buffer
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
// 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.
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||||
|
if (device_ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||||
{
|
{
|
||||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
|
||||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
|
||||||
return;
|
|
||||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||||
float L = draw_data->DisplayPos.x;
|
float L = draw_data->DisplayPos.x;
|
||||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
@@ -201,9 +138,94 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
};
|
};
|
||||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||||
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
device_ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
device_ctx->IASetInputLayout(bd->pInputLayout);
|
||||||
|
device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
|
device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||||
|
device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
|
device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||||
|
device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||||
|
device_ctx->GSSetShader(nullptr, nullptr, 0);
|
||||||
|
device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
|
||||||
|
// Setup render state
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||||
|
device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||||
|
device_ctx->RSSetState(bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ID3D11DeviceContext* device = bd->pd3dDeviceContext;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplDX11_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D11_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D11_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
|
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||||
|
if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||||
|
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
device->Unmap(bd->pVB, 0);
|
||||||
|
device->Unmap(bd->pIB, 0);
|
||||||
|
|
||||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||||
struct BACKUP_DX11_STATE
|
struct BACKUP_DX11_STATE
|
||||||
{
|
{
|
||||||
@@ -231,104 +253,132 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
|||||||
};
|
};
|
||||||
BACKUP_DX11_STATE old = {};
|
BACKUP_DX11_STATE old = {};
|
||||||
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||||
ctx->RSGetState(&old.RS);
|
device->RSGetState(&old.RS);
|
||||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||||
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||||
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||||
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||||
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||||
|
|
||||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||||
ctx->IAGetInputLayout(&old.InputLayout);
|
device->IAGetInputLayout(&old.InputLayout);
|
||||||
|
|
||||||
// Setup desired DX state
|
// Setup desired DX state
|
||||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||||
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplDX11_RenderState render_state;
|
||||||
|
render_state.Device = bd->pd3dDevice;
|
||||||
|
render_state.DeviceContext = bd->pd3dDeviceContext;
|
||||||
|
render_state.SamplerDefault = bd->pFontSampler;
|
||||||
|
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
int global_idx_offset = 0;
|
int global_idx_offset = 0;
|
||||||
int global_vtx_offset = 0;
|
int global_vtx_offset = 0;
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != nullptr)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
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;
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle
|
// Apply scissor/clipping rectangle
|
||||||
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
ctx->RSSetScissorRects(1, &r);
|
device->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
|
|
||||||
// Restore modified DX state
|
// Restore modified DX state
|
||||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||||
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||||
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||||
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||||
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||||
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX11_CreateFontsTexture()
|
static void ImGui_ImplDX11_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (backend_tex == nullptr)
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
return;
|
||||||
unsigned char* pixels;
|
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
int width, height;
|
backend_tex->pTextureView->Release();
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
backend_tex->pTexture->Release();
|
||||||
|
IM_DELETE(backend_tex);
|
||||||
|
|
||||||
// Upload texture to graphics system
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
tex->BackendUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
{
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
unsigned int* pixels = (unsigned int*)tex->GetPixels();
|
||||||
|
ImGui_ImplDX11_Texture* backend_tex = IM_NEW(ImGui_ImplDX11_Texture)();
|
||||||
|
|
||||||
|
// Create texture
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
desc.Width = width;
|
desc.Width = (UINT)tex->Width;
|
||||||
desc.Height = height;
|
desc.Height = (UINT)tex->Height;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.ArraySize = 1;
|
desc.ArraySize = 1;
|
||||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
@@ -336,14 +386,12 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
desc.CPUAccessFlags = 0;
|
desc.CPUAccessFlags = 0;
|
||||||
|
|
||||||
ID3D11Texture2D* pTexture = nullptr;
|
|
||||||
D3D11_SUBRESOURCE_DATA subResource;
|
D3D11_SUBRESOURCE_DATA subResource;
|
||||||
subResource.pSysMem = pixels;
|
subResource.pSysMem = pixels;
|
||||||
subResource.SysMemPitch = desc.Width * 4;
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
subResource.SysMemSlicePitch = 0;
|
subResource.SysMemSlicePitch = 0;
|
||||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &backend_tex->pTexture);
|
||||||
IM_ASSERT(pTexture != nullptr);
|
IM_ASSERT(backend_tex->pTexture != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
// Create texture view
|
// Create texture view
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
@@ -352,28 +400,29 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
|||||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
|
bd->pd3dDevice->CreateShaderResourceView(backend_tex->pTexture, &srvDesc, &backend_tex->pTextureView);
|
||||||
pTexture->Release();
|
IM_ASSERT(backend_tex->pTextureView != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)backend_tex->pTextureView);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
tex->BackendUserData = backend_tex;
|
||||||
}
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
|
||||||
|
|
||||||
// Create texture sampler
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
{
|
{
|
||||||
D3D11_SAMPLER_DESC desc;
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData;
|
||||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
for (ImTextureRect& r : tex->Updates)
|
||||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
{
|
||||||
desc.MipLODBias = 0.f;
|
D3D11_BOX box = { (UINT)r.x, (UINT)r.y, (UINT)0, (UINT)(r.x + r.w), (UINT)(r.y + r .h), (UINT)1 };
|
||||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
bd->pd3dDeviceContext->UpdateSubresource(backend_tex->pTexture, 0, &box, tex->GetPixelsAt(r.x, r.y), (UINT)tex->GetPitch(), 0);
|
||||||
desc.MinLOD = 0.f;
|
}
|
||||||
desc.MaxLOD = 0.f;
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
|
||||||
}
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
ImGui_ImplDX11_DestroyTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX11_CreateDeviceObjects()
|
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||||
@@ -381,8 +430,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
if (!bd->pd3dDevice)
|
if (!bd->pd3dDevice)
|
||||||
return false;
|
return false;
|
||||||
if (bd->pFontSampler)
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
|
||||||
|
|
||||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
// If you would like to use this DX11 sample code but remove this dependency you can:
|
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||||
@@ -445,7 +493,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
|
|
||||||
// Create the constant buffer
|
// Create the constant buffer
|
||||||
{
|
{
|
||||||
D3D11_BUFFER_DESC desc;
|
D3D11_BUFFER_DESC desc = {};
|
||||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
@@ -525,7 +573,21 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
|||||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui_ImplDX11_CreateFontsTexture();
|
// Create texture sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
{
|
||||||
|
D3D11_SAMPLER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.MipLODBias = 0.f;
|
||||||
|
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.MinLOD = 0.f;
|
||||||
|
desc.MaxLOD = 0.f;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -536,8 +598,12 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
|||||||
if (!bd->pd3dDevice)
|
if (!bd->pd3dDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplDX11_DestroyTexture(tex);
|
||||||
|
|
||||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
@@ -560,8 +626,12 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
|
|
||||||
// Get factory from device
|
// Get factory from device
|
||||||
IDXGIDevice* pDXGIDevice = nullptr;
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
IDXGIAdapter* pDXGIAdapter = nullptr;
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
@@ -580,8 +650,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
bd->pd3dDevice->AddRef();
|
bd->pd3dDevice->AddRef();
|
||||||
bd->pd3dDeviceContext->AddRef();
|
bd->pd3dDeviceContext->AddRef();
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
ImGui_ImplDX11_InitMultiViewportSupport();
|
||||||
ImGui_ImplDX11_InitPlatformInterface();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -592,14 +661,14 @@ void ImGui_ImplDX11_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplDX11_ShutdownPlatformInterface();
|
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(); }
|
||||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,8 +677,9 @@ void ImGui_ImplDX11_NewFrame()
|
|||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
|
||||||
|
|
||||||
if (!bd->pFontSampler)
|
if (!bd->pVertexShader)
|
||||||
ImGui_ImplDX11_CreateDeviceObjects();
|
if (!ImGui_ImplDX11_CreateDeviceObjects())
|
||||||
|
IM_ASSERT(0 && "ImGui_ImplDX11_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
@@ -628,37 +698,45 @@ struct ImGui_ImplDX11_ViewportData
|
|||||||
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(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)
|
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
||||||
viewport->RendererUserData = vd;
|
viewport->RendererUserData = vd;
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
// 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.
|
// 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;
|
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||||
IM_ASSERT(hwnd != 0);
|
IM_ASSERT(hwnd != 0);
|
||||||
|
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
||||||
|
|
||||||
// Create swap chain
|
// Create swap chain
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
HRESULT hr = DXGI_ERROR_UNSUPPORTED;
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
for (const DXGI_SWAP_CHAIN_DESC& sd_template : bd->SwapChainDescsForViewports)
|
||||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
{
|
||||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
IM_ASSERT(sd_template.BufferDesc.Width == 0 && sd_template.BufferDesc.Height == 0 && sd_template.OutputWindow == nullptr);
|
||||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
DXGI_SWAP_CHAIN_DESC sd = sd_template;
|
||||||
sd.SampleDesc.Count = 1;
|
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||||
sd.SampleDesc.Quality = 0;
|
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
sd.OutputWindow = hwnd;
|
||||||
sd.BufferCount = 1;
|
hr = bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||||
sd.OutputWindow = hwnd;
|
if (SUCCEEDED(hr))
|
||||||
sd.Windowed = TRUE;
|
break;
|
||||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
}
|
||||||
sd.Flags = 0;
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
|
||||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
|
||||||
|
|
||||||
// Create the render target
|
// Create the render target
|
||||||
if (vd->SwapChain)
|
if (vd->SwapChain != nullptr)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* pBackBuffer;
|
ID3D11Texture2D* pBackBuffer;
|
||||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||||
@@ -720,7 +798,7 @@ static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
|||||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX11_InitPlatformInterface()
|
static void ImGui_ImplDX11_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
||||||
@@ -728,9 +806,22 @@ static void ImGui_ImplDX11_InitPlatformInterface()
|
|||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
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_ShutdownPlatformInterface()
|
static void ImGui_ImplDX11_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -20,6 +22,8 @@
|
|||||||
|
|
||||||
struct ID3D11Device;
|
struct ID3D11Device;
|
||||||
struct ID3D11DeviceContext;
|
struct ID3D11DeviceContext;
|
||||||
|
struct ID3D11SamplerState;
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
|
||||||
// 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_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||||
@@ -28,7 +32,21 @@ IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
// 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 void ImGui_ImplDX11_InvalidateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplDX11_RenderState
|
||||||
|
{
|
||||||
|
ID3D11Device* Device;
|
||||||
|
ID3D11DeviceContext* DeviceContext;
|
||||||
|
ID3D11SamplerState* SamplerDefault;
|
||||||
|
ID3D11Buffer* VertexConstantBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -2,18 +2,15 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
// [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) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
||||||
|
|
||||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
// To build this on 32-bit systems:
|
|
||||||
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
|
||||||
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
|
||||||
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
|
||||||
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
|
||||||
|
|
||||||
// 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,7 +22,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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-19: Fixed build on MinGW. (#8702, #4594)
|
||||||
|
// 2025-06-11: DirectX12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||||
|
// 2025-05-07: DirectX12: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||||
|
// 2025-02-24: DirectX12: Fixed an issue where ImGui_ImplDX12_Init() signature change from 2024-11-15 combined with change from 2025-01-15 made legacy ImGui_ImplDX12_Init() crash. (#8429)
|
||||||
|
// 2025-01-15: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own.
|
||||||
|
// 2024-12-09: DirectX12: Let user specifies the DepthStencilView format by setting ImGui_ImplDX12_InitInfo::DSVFormat.
|
||||||
|
// 2024-11-15: DirectX12: *BREAKING CHANGE* Changed ImGui_ImplDX12_Init() signature to take a ImGui_ImplDX12_InitInfo struct. Legacy ImGui_ImplDX12_Init() signature is still supported (will obsolete).
|
||||||
|
// 2024-11-15: DirectX12: *BREAKING CHANGE* User is now required to pass function pointers to allocate/free SRV Descriptors. We provide convenience legacy fields to pass a single descriptor, matching the old API, but upcoming features will want multiple.
|
||||||
|
// 2024-10-23: DirectX12: Unmap() call specify written range. The range is informational and may be used by debug tools.
|
||||||
|
// 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
|
// 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
|
// 2024-10-07: DirectX12: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 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-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
@@ -56,18 +65,41 @@
|
|||||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// DirectX data
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// MinGW workaround, see #4594
|
||||||
|
typedef decltype(D3D12SerializeRootSignature) *_PFN_D3D12_SERIALIZE_ROOT_SIGNATURE;
|
||||||
|
|
||||||
|
// DirectX12 data
|
||||||
|
struct ImGui_ImplDX12_RenderBuffers;
|
||||||
|
|
||||||
|
struct ImGui_ImplDX12_Texture
|
||||||
|
{
|
||||||
|
ID3D12Resource* pTextureResource;
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||||
|
|
||||||
|
ImGui_ImplDX12_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
struct ImGui_ImplDX12_Data
|
struct ImGui_ImplDX12_Data
|
||||||
{
|
{
|
||||||
|
ImGui_ImplDX12_InitInfo InitInfo;
|
||||||
ID3D12Device* pd3dDevice;
|
ID3D12Device* pd3dDevice;
|
||||||
ID3D12RootSignature* pRootSignature;
|
ID3D12RootSignature* pRootSignature;
|
||||||
ID3D12PipelineState* pPipelineState;
|
ID3D12PipelineState* pPipelineState;
|
||||||
|
ID3D12CommandQueue* pCommandQueue;
|
||||||
|
bool commandQueueOwned;
|
||||||
DXGI_FORMAT RTVFormat;
|
DXGI_FORMAT RTVFormat;
|
||||||
ID3D12Resource* pFontTextureResource;
|
DXGI_FORMAT DSVFormat;
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
|
||||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||||
UINT numFramesInFlight;
|
UINT numFramesInFlight;
|
||||||
|
ImGui_ImplDX12_Texture FontTexture;
|
||||||
|
bool LegacySingleDescriptorUsed;
|
||||||
|
|
||||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@@ -171,7 +203,7 @@ static void ImGui_ImplDX12_InitPlatformInterface();
|
|||||||
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
|
||||||
{
|
{
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
|
||||||
@@ -194,38 +226,35 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D12_VIEWPORT vp;
|
D3D12_VIEWPORT vp = {};
|
||||||
memset(&vp, 0, sizeof(D3D12_VIEWPORT));
|
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
||||||
vp.Width = draw_data->DisplaySize.x;
|
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
||||||
vp.Height = draw_data->DisplaySize.y;
|
|
||||||
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;
|
||||||
ctx->RSSetViewports(1, &vp);
|
command_list->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
// Bind shader and vertex buffers
|
// Bind shader and vertex buffers
|
||||||
unsigned int stride = sizeof(ImDrawVert);
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
D3D12_VERTEX_BUFFER_VIEW vbv;
|
D3D12_VERTEX_BUFFER_VIEW vbv = {};
|
||||||
memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW));
|
|
||||||
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
||||||
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
||||||
vbv.StrideInBytes = stride;
|
vbv.StrideInBytes = stride;
|
||||||
ctx->IASetVertexBuffers(0, 1, &vbv);
|
command_list->IASetVertexBuffers(0, 1, &vbv);
|
||||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
D3D12_INDEX_BUFFER_VIEW ibv = {};
|
||||||
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
|
|
||||||
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
||||||
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||||
ctx->IASetIndexBuffer(&ibv);
|
command_list->IASetIndexBuffer(&ibv);
|
||||||
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
ctx->SetPipelineState(bd->pPipelineState);
|
command_list->SetPipelineState(bd->pPipelineState);
|
||||||
ctx->SetGraphicsRootSignature(bd->pRootSignature);
|
command_list->SetGraphicsRootSignature(bd->pRootSignature);
|
||||||
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
command_list->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||||
|
|
||||||
// Setup blend factor
|
// Setup blend factor
|
||||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
ctx->OMSetBlendFactor(blend_factor);
|
command_list->OMSetBlendFactor(blend_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -237,12 +266,20 @@ static inline void SafeRelease(T*& res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render function
|
// Render function
|
||||||
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
|
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized
|
// Avoid rendering when minimized
|
||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplDX12_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// 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;
|
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||||
vd->FrameIndex++;
|
vd->FrameIndex++;
|
||||||
@@ -253,13 +290,11 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||||||
{
|
{
|
||||||
SafeRelease(fr->VertexBuffer);
|
SafeRelease(fr->VertexBuffer);
|
||||||
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
D3D12_HEAP_PROPERTIES props;
|
D3D12_HEAP_PROPERTIES props = {};
|
||||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
|
||||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
D3D12_RESOURCE_DESC desc;
|
D3D12_RESOURCE_DESC desc = {};
|
||||||
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
|
desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
desc.Height = 1;
|
desc.Height = 1;
|
||||||
@@ -276,13 +311,11 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||||||
{
|
{
|
||||||
SafeRelease(fr->IndexBuffer);
|
SafeRelease(fr->IndexBuffer);
|
||||||
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
D3D12_HEAP_PROPERTIES props;
|
D3D12_HEAP_PROPERTIES props = {};
|
||||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
|
||||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
D3D12_RESOURCE_DESC desc;
|
D3D12_RESOURCE_DESC desc = {};
|
||||||
memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC));
|
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
desc.Height = 1;
|
desc.Height = 1;
|
||||||
@@ -297,84 +330,120 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upload vertex/index data into a single contiguous GPU buffer
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
|
// During Map() we specify a null read range (as per DX12 API, this is informational and for tooling only)
|
||||||
void* vtx_resource, *idx_resource;
|
void* vtx_resource, *idx_resource;
|
||||||
D3D12_RANGE range;
|
D3D12_RANGE range = { 0, 0 };
|
||||||
memset(&range, 0, sizeof(D3D12_RANGE));
|
|
||||||
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
|
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
|
||||||
return;
|
return;
|
||||||
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
|
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
|
||||||
return;
|
return;
|
||||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
|
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
|
||||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
idx_dst += cmd_list->IdxBuffer.Size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// During Unmap() we specify the written range (as per DX12 API, this is informational and for tooling only)
|
||||||
|
range.End = (SIZE_T)((intptr_t)vtx_dst - (intptr_t)vtx_resource);
|
||||||
|
IM_ASSERT(range.End == draw_data->TotalVtxCount * sizeof(ImDrawVert));
|
||||||
fr->VertexBuffer->Unmap(0, &range);
|
fr->VertexBuffer->Unmap(0, &range);
|
||||||
|
range.End = (SIZE_T)((intptr_t)idx_dst - (intptr_t)idx_resource);
|
||||||
|
IM_ASSERT(range.End == draw_data->TotalIdxCount * sizeof(ImDrawIdx));
|
||||||
fr->IndexBuffer->Unmap(0, &range);
|
fr->IndexBuffer->Unmap(0, &range);
|
||||||
|
|
||||||
// Setup desired DX state
|
// Setup desired DX state
|
||||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||||
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplDX12_RenderState render_state;
|
||||||
|
render_state.Device = bd->pd3dDevice;
|
||||||
|
render_state.CommandList = command_list;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
int global_vtx_offset = 0;
|
int global_vtx_offset = 0;
|
||||||
int global_idx_offset = 0;
|
int global_idx_offset = 0;
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != nullptr)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
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;
|
||||||
|
|
||||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
// Apply scissor/clipping rectangle
|
||||||
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
command_list->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
command_list->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||||
ctx->RSSetScissorRects(1, &r);
|
command_list->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX12_CreateFontsTexture()
|
static void ImGui_ImplDX12_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (backend_tex == nullptr)
|
||||||
|
return;
|
||||||
|
IM_ASSERT(backend_tex->hFontSrvGpuDescHandle.ptr == (UINT64)tex->TexID);
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
unsigned char* pixels;
|
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, backend_tex->hFontSrvCpuDescHandle, backend_tex->hFontSrvGpuDescHandle);
|
||||||
int width, height;
|
SafeRelease(backend_tex->pTextureResource);
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
backend_tex->hFontSrvCpuDescHandle.ptr = 0;
|
||||||
|
backend_tex->hFontSrvGpuDescHandle.ptr = 0;
|
||||||
|
IM_DELETE(backend_tex);
|
||||||
|
|
||||||
// Upload texture to graphics system
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
tex->BackendUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
bool need_barrier_before_copy = true; // Do we need a resource barrier before we copy new data in?
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
{
|
{
|
||||||
D3D12_HEAP_PROPERTIES props;
|
// Create and upload new texture to graphics system
|
||||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
ImGui_ImplDX12_Texture* backend_tex = IM_NEW(ImGui_ImplDX12_Texture)();
|
||||||
|
bd->InitInfo.SrvDescriptorAllocFn(&bd->InitInfo, &backend_tex->hFontSrvCpuDescHandle, &backend_tex->hFontSrvGpuDescHandle); // Allocate a desctriptor handle
|
||||||
|
|
||||||
|
D3D12_HEAP_PROPERTIES props = {};
|
||||||
props.Type = D3D12_HEAP_TYPE_DEFAULT;
|
props.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
@@ -383,8 +452,8 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||||||
ZeroMemory(&desc, sizeof(desc));
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
desc.Alignment = 0;
|
desc.Alignment = 0;
|
||||||
desc.Width = width;
|
desc.Width = tex->Width;
|
||||||
desc.Height = height;
|
desc.Height = tex->Height;
|
||||||
desc.DepthOrArraySize = 1;
|
desc.DepthOrArraySize = 1;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
@@ -397,11 +466,50 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||||||
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
||||||
|
|
||||||
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
// Create SRV
|
||||||
UINT uploadSize = height * uploadPitch;
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||||
|
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, backend_tex->hFontSrvCpuDescHandle);
|
||||||
|
SafeRelease(backend_tex->pTextureResource);
|
||||||
|
backend_tex->pTextureResource = pTexture;
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)backend_tex->hFontSrvGpuDescHandle.ptr);
|
||||||
|
tex->BackendUserData = backend_tex;
|
||||||
|
need_barrier_before_copy = false; // Because this is a newly-created texture it will be in D3D12_RESOURCE_STATE_COMMON and thus we don't need a barrier
|
||||||
|
// We don't set tex->Status to ImTextureStatus_OK to let the code fallthrough below.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData;
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// We could use the smaller rect on _WantCreate but using the full rect allows us to clear the texture.
|
||||||
|
// FIXME-OPT: Uploading single box even when using ImTextureStatus_WantUpdates. Could use tex->Updates[]
|
||||||
|
// - Copy all blocks contiguously in upload buffer.
|
||||||
|
// - Barrier before copy, submit all CopyTextureRegion(), barrier after copy.
|
||||||
|
const int upload_x = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.x;
|
||||||
|
const int upload_y = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.y;
|
||||||
|
const int upload_w = (tex->Status == ImTextureStatus_WantCreate) ? tex->Width : tex->UpdateRect.w;
|
||||||
|
const int upload_h = (tex->Status == ImTextureStatus_WantCreate) ? tex->Height : tex->UpdateRect.h;
|
||||||
|
|
||||||
|
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions.
|
||||||
|
UINT upload_pitch_src = upload_w * tex->BytesPerPixel;
|
||||||
|
UINT upload_pitch_dst = (upload_pitch_src + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||||
|
UINT upload_size = upload_pitch_dst * upload_h;
|
||||||
|
|
||||||
|
D3D12_RESOURCE_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
desc.Alignment = 0;
|
desc.Alignment = 0;
|
||||||
desc.Width = uploadSize;
|
desc.Width = upload_size;
|
||||||
desc.Height = 1;
|
desc.Height = 1;
|
||||||
desc.DepthOrArraySize = 1;
|
desc.DepthOrArraySize = 1;
|
||||||
desc.MipLevels = 1;
|
desc.MipLevels = 1;
|
||||||
@@ -411,112 +519,109 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
|||||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
|
D3D12_HEAP_PROPERTIES props;
|
||||||
|
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||||
|
|
||||||
|
// FIXME-OPT: Can upload buffer be reused?
|
||||||
ID3D12Resource* uploadBuffer = nullptr;
|
ID3D12Resource* uploadBuffer = nullptr;
|
||||||
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
void* mapped = nullptr;
|
// Create temporary command list and execute immediately
|
||||||
D3D12_RANGE range = { 0, uploadSize };
|
|
||||||
hr = uploadBuffer->Map(0, &range, &mapped);
|
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
|
||||||
for (int y = 0; y < height; y++)
|
|
||||||
memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4);
|
|
||||||
uploadBuffer->Unmap(0, &range);
|
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
|
||||||
srcLocation.pResource = uploadBuffer;
|
|
||||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
|
||||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
srcLocation.PlacedFootprint.Footprint.Width = width;
|
|
||||||
srcLocation.PlacedFootprint.Footprint.Height = height;
|
|
||||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
|
||||||
srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
|
|
||||||
|
|
||||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
|
||||||
dstLocation.pResource = pTexture;
|
|
||||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
|
||||||
dstLocation.SubresourceIndex = 0;
|
|
||||||
|
|
||||||
D3D12_RESOURCE_BARRIER barrier = {};
|
|
||||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
|
||||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
|
||||||
barrier.Transition.pResource = pTexture;
|
|
||||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
|
||||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
|
||||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
|
||||||
|
|
||||||
ID3D12Fence* fence = nullptr;
|
ID3D12Fence* fence = nullptr;
|
||||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
HANDLE event = CreateEvent(0, 0, 0, 0);
|
HANDLE event = ::CreateEvent(0, 0, 0, 0);
|
||||||
IM_ASSERT(event != nullptr);
|
IM_ASSERT(event != nullptr);
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
// FIXME-OPT: Create once and reuse?
|
||||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
|
||||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
|
||||||
queueDesc.NodeMask = 1;
|
|
||||||
|
|
||||||
ID3D12CommandQueue* cmdQueue = nullptr;
|
|
||||||
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
|
||||||
|
|
||||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// FIXME-OPT: Can be use the one from user? (pass ID3D12GraphicsCommandList* to ImGui_ImplDX12_UpdateTextures)
|
||||||
ID3D12GraphicsCommandList* cmdList = nullptr;
|
ID3D12GraphicsCommandList* cmdList = nullptr;
|
||||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, nullptr);
|
// Copy to upload buffer
|
||||||
cmdList->ResourceBarrier(1, &barrier);
|
void* mapped = nullptr;
|
||||||
|
D3D12_RANGE range = { 0, upload_size };
|
||||||
|
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
for (int y = 0; y < upload_h; y++)
|
||||||
|
memcpy((void*)((uintptr_t)mapped + y * upload_pitch_dst), tex->GetPixelsAt(upload_x, upload_y + y), upload_pitch_src);
|
||||||
|
uploadBuffer->Unmap(0, &range);
|
||||||
|
|
||||||
|
if (need_barrier_before_copy)
|
||||||
|
{
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = {};
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||||
|
barrier.Transition.pResource = backend_tex->pTextureResource;
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
|
cmdList->ResourceBarrier(1, &barrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||||
|
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||||
|
{
|
||||||
|
srcLocation.pResource = uploadBuffer;
|
||||||
|
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Width = upload_w;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Height = upload_h;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||||
|
srcLocation.PlacedFootprint.Footprint.RowPitch = upload_pitch_dst;
|
||||||
|
dstLocation.pResource = backend_tex->pTextureResource;
|
||||||
|
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||||
|
dstLocation.SubresourceIndex = 0;
|
||||||
|
}
|
||||||
|
cmdList->CopyTextureRegion(&dstLocation, upload_x, upload_y, 0, &srcLocation, nullptr);
|
||||||
|
|
||||||
|
{
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = {};
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||||
|
barrier.Transition.pResource = backend_tex->pTextureResource;
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
|
||||||
|
cmdList->ResourceBarrier(1, &barrier);
|
||||||
|
}
|
||||||
|
|
||||||
hr = cmdList->Close();
|
hr = cmdList->Close();
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
ID3D12CommandQueue* cmdQueue = bd->pCommandQueue;
|
||||||
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
||||||
hr = cmdQueue->Signal(fence, 1);
|
hr = cmdQueue->Signal(fence, 1);
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
|
||||||
|
// FIXME-OPT: Suboptimal?
|
||||||
|
// - To remove this may need to create NumFramesInFlight x ImGui_ImplDX12_FrameContext in backend data (mimick docking version)
|
||||||
|
// - Store per-frame in flight: upload buffer?
|
||||||
|
// - Where do cmdList and cmdAlloc fit?
|
||||||
fence->SetEventOnCompletion(1, event);
|
fence->SetEventOnCompletion(1, event);
|
||||||
WaitForSingleObject(event, INFINITE);
|
::WaitForSingleObject(event, INFINITE);
|
||||||
|
|
||||||
cmdList->Release();
|
cmdList->Release();
|
||||||
cmdAlloc->Release();
|
cmdAlloc->Release();
|
||||||
cmdQueue->Release();
|
::CloseHandle(event);
|
||||||
CloseHandle(event);
|
|
||||||
fence->Release();
|
fence->Release();
|
||||||
uploadBuffer->Release();
|
uploadBuffer->Release();
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
// Create texture view
|
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
|
||||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
|
||||||
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
|
|
||||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
|
||||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
|
||||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
|
||||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
|
|
||||||
SafeRelease(bd->pFontTextureResource);
|
|
||||||
bd->pFontTextureResource = pTexture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store our identifier
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames >= (int)bd->numFramesInFlight)
|
||||||
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
|
ImGui_ImplDX12_DestroyTexture(tex);
|
||||||
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
|
||||||
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
|
||||||
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
|
||||||
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
|
||||||
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
|
||||||
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
|
||||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
|
||||||
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX12_CreateDeviceObjects()
|
bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||||
@@ -552,15 +657,15 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
// 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 by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||||
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
||||||
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
staticSampler.MipLODBias = 0.f;
|
staticSampler.MipLODBias = 0.f;
|
||||||
staticSampler.MaxAnisotropy = 0;
|
staticSampler.MaxAnisotropy = 0;
|
||||||
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||||
staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
|
staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
|
||||||
staticSampler.MinLOD = 0.f;
|
staticSampler.MinLOD = 0.f;
|
||||||
staticSampler.MaxLOD = 0.f;
|
staticSampler.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
staticSampler.ShaderRegister = 0;
|
staticSampler.ShaderRegister = 0;
|
||||||
staticSampler.RegisterSpace = 0;
|
staticSampler.RegisterSpace = 0;
|
||||||
staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||||
@@ -598,7 +703,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
|
_PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFn = (_PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)(void*)::GetProcAddress(d3d12_dll, "D3D12SerializeRootSignature");
|
||||||
if (D3D12SerializeRootSignatureFn == nullptr)
|
if (D3D12SerializeRootSignatureFn == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -616,14 +721,14 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
|
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
|
||||||
memset(&psoDesc, 0, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
|
|
||||||
psoDesc.NodeMask = 1;
|
psoDesc.NodeMask = 1;
|
||||||
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
|
||||||
psoDesc.pRootSignature = bd->pRootSignature;
|
psoDesc.pRootSignature = bd->pRootSignature;
|
||||||
psoDesc.SampleMask = UINT_MAX;
|
psoDesc.SampleMask = UINT_MAX;
|
||||||
psoDesc.NumRenderTargets = 1;
|
psoDesc.NumRenderTargets = 1;
|
||||||
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
||||||
|
psoDesc.DSVFormat = bd->DSVFormat;
|
||||||
psoDesc.SampleDesc.Count = 1;
|
psoDesc.SampleDesc.Count = 1;
|
||||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||||
|
|
||||||
@@ -748,8 +853,6 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
if (result_pipeline_state != S_OK)
|
if (result_pipeline_state != S_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGui_ImplDX12_CreateFontsTexture();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,15 +869,41 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
|||||||
if (!bd || !bd->pd3dDevice)
|
if (!bd || !bd->pd3dDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (bd->commandQueueOwned)
|
||||||
|
SafeRelease(bd->pCommandQueue);
|
||||||
|
bd->commandQueueOwned = false;
|
||||||
SafeRelease(bd->pRootSignature);
|
SafeRelease(bd->pRootSignature);
|
||||||
SafeRelease(bd->pPipelineState);
|
SafeRelease(bd->pPipelineState);
|
||||||
SafeRelease(bd->pFontTextureResource);
|
|
||||||
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplDX12_DestroyTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
static void ImGui_ImplDX12_InitLegacySingleDescriptorMode(ImGui_ImplDX12_InitInfo* init_info)
|
||||||
|
{
|
||||||
|
// Wrap legacy behavior of passing space for a single descriptor
|
||||||
|
IM_ASSERT(init_info->LegacySingleSrvCpuDescriptor.ptr != 0 && init_info->LegacySingleSrvGpuDescriptor.ptr != 0);
|
||||||
|
init_info->SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
IM_ASSERT(bd->LegacySingleDescriptorUsed == false && "Only 1 simultaneous texture allowed with legacy ImGui_ImplDX12_Init() signature!");
|
||||||
|
*out_cpu_handle = bd->InitInfo.LegacySingleSrvCpuDescriptor;
|
||||||
|
*out_gpu_handle = bd->InitInfo.LegacySingleSrvGpuDescriptor;
|
||||||
|
bd->LegacySingleDescriptorUsed = true;
|
||||||
|
};
|
||||||
|
init_info->SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
|
IM_ASSERT(bd->LegacySingleDescriptorUsed == true);
|
||||||
|
bd->LegacySingleDescriptorUsed = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
@@ -782,28 +911,70 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
|||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
||||||
|
bd->InitInfo = *init_info; // Deep copy
|
||||||
|
init_info = &bd->InitInfo;
|
||||||
|
|
||||||
|
bd->pd3dDevice = init_info->Device;
|
||||||
|
IM_ASSERT(init_info->CommandQueue != NULL);
|
||||||
|
bd->pCommandQueue = init_info->CommandQueue;
|
||||||
|
bd->RTVFormat = init_info->RTVFormat;
|
||||||
|
bd->DSVFormat = init_info->DSVFormat;
|
||||||
|
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||||
|
bd->pd3dSrvDescHeap = init_info->SrvDescriptorHeap;
|
||||||
|
|
||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
ImGui_ImplDX12_InitPlatformInterface();
|
ImGui_ImplDX12_InitPlatformInterface();
|
||||||
|
|
||||||
bd->pd3dDevice = device;
|
|
||||||
bd->RTVFormat = rtv_format;
|
|
||||||
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
|
||||||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
|
||||||
bd->numFramesInFlight = num_frames_in_flight;
|
|
||||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
|
||||||
|
|
||||||
// Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
// 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.
|
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||||
|
|
||||||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
if (init_info->SrvDescriptorAllocFn == nullptr)
|
||||||
|
ImGui_ImplDX12_InitLegacySingleDescriptorMode(init_info);
|
||||||
|
#endif
|
||||||
|
IM_ASSERT(init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr);
|
||||||
|
|
||||||
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();
|
||||||
@@ -827,7 +998,7 @@ void ImGui_ImplDX12_Shutdown()
|
|||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,7 +1008,8 @@ void ImGui_ImplDX12_NewFrame()
|
|||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX12_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX12_Init()?");
|
||||||
|
|
||||||
if (!bd->pPipelineState)
|
if (!bd->pPipelineState)
|
||||||
ImGui_ImplDX12_CreateDeviceObjects();
|
if (!ImGui_ImplDX12_CreateDeviceObjects())
|
||||||
|
IM_ASSERT(0 && "ImGui_ImplDX12_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
@@ -852,7 +1024,7 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
|||||||
ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||||
viewport->RendererUserData = vd;
|
viewport->RendererUserData = vd;
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
// 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.
|
// 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;
|
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||||
IM_ASSERT(hwnd != 0);
|
IM_ASSERT(hwnd != 0);
|
||||||
@@ -1041,7 +1213,7 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
|||||||
cmd_list->ResourceBarrier(1, &barrier);
|
cmd_list->ResourceBarrier(1, &barrier);
|
||||||
cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, nullptr);
|
cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, nullptr);
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||||
cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (float*)&clear_color, 0, nullptr);
|
cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (const float*)&clear_color, 0, nullptr);
|
||||||
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
||||||
|
|
||||||
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
// [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) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||||
// See imgui_impl_dx12.cpp file for details.
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -21,27 +23,58 @@
|
|||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
#include <dxgiformat.h> // DXGI_FORMAT
|
#include <dxgiformat.h> // DXGI_FORMAT
|
||||||
|
#include <d3d12.h> // D3D12_CPU_DESCRIPTOR_HANDLE
|
||||||
|
|
||||||
struct ID3D12Device;
|
// Initialization data, for ImGui_ImplDX12_Init()
|
||||||
struct ID3D12DescriptorHeap;
|
struct ImGui_ImplDX12_InitInfo
|
||||||
struct ID3D12GraphicsCommandList;
|
{
|
||||||
struct D3D12_CPU_DESCRIPTOR_HANDLE;
|
ID3D12Device* Device;
|
||||||
struct D3D12_GPU_DESCRIPTOR_HANDLE;
|
ID3D12CommandQueue* CommandQueue; // Command queue used for queuing texture uploads.
|
||||||
|
int NumFramesInFlight;
|
||||||
|
DXGI_FORMAT RTVFormat; // RenderTarget format.
|
||||||
|
DXGI_FORMAT DSVFormat; // DepthStencilView format.
|
||||||
|
void* UserData;
|
||||||
|
|
||||||
|
// Allocating SRV descriptors for textures is up to the application, so we provide callbacks.
|
||||||
|
// (current version of the backend will only allocate one descriptor, from 1.92 the backend will need to allocate more)
|
||||||
|
ID3D12DescriptorHeap* SrvDescriptorHeap;
|
||||||
|
void (*SrvDescriptorAllocFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle);
|
||||||
|
void (*SrvDescriptorFreeFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_desc_handle);
|
||||||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE LegacySingleSrvCpuDescriptor; // To facilitate transition from single descriptor to allocator callback, you may use those.
|
||||||
|
D3D12_GPU_DESCRIPTOR_HANDLE LegacySingleSrvGpuDescriptor;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ImGui_ImplDX12_InitInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
|
};
|
||||||
|
|
||||||
// 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_ImplDX12_Init(ImGui_ImplDX12_InitInfo* info);
|
||||||
// cmd_list is the command list that the implementation will use to render imgui draw lists.
|
|
||||||
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
|
|
||||||
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
|
|
||||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
|
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 void ImGui_ImplDX12_InvalidateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX12_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplDX12_RenderState
|
||||||
|
{
|
||||||
|
ID3D12Device* Device;
|
||||||
|
ID3D12GraphicsCommandList* CommandList;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: 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'.
|
// [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.
|
||||||
@@ -16,7 +18,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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-11: DirectX9: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||||
|
// 2024-10-07: DirectX9: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 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).
|
||||||
@@ -44,15 +48,21 @@
|
|||||||
// DirectX
|
// DirectX
|
||||||
#include <d3d9.h>
|
#include <d3d9.h>
|
||||||
|
|
||||||
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
// DirectX data
|
// DirectX data
|
||||||
struct ImGui_ImplDX9_Data
|
struct ImGui_ImplDX9_Data
|
||||||
{
|
{
|
||||||
LPDIRECT3DDEVICE9 pd3dDevice;
|
LPDIRECT3DDEVICE9 pd3dDevice;
|
||||||
LPDIRECT3DVERTEXBUFFER9 pVB;
|
LPDIRECT3DVERTEXBUFFER9 pVB;
|
||||||
LPDIRECT3DINDEXBUFFER9 pIB;
|
LPDIRECT3DINDEXBUFFER9 pIB;
|
||||||
LPDIRECT3DTEXTURE9 FontTexture;
|
|
||||||
int VertexBufferSize;
|
int VertexBufferSize;
|
||||||
int IndexBufferSize;
|
int IndexBufferSize;
|
||||||
|
bool HasRgbaSupport;
|
||||||
|
|
||||||
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
};
|
};
|
||||||
@@ -79,8 +89,8 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplDX9_InitPlatformInterface();
|
static void ImGui_ImplDX9_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplDX9_ShutdownPlatformInterface();
|
static void ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
||||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||||
|
|
||||||
@@ -96,41 +106,45 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
|||||||
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||||
vp.MinZ = 0.0f;
|
vp.MinZ = 0.0f;
|
||||||
vp.MaxZ = 1.0f;
|
vp.MaxZ = 1.0f;
|
||||||
bd->pd3dDevice->SetViewport(&vp);
|
|
||||||
|
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||||
|
device->SetViewport(&vp);
|
||||||
|
|
||||||
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
||||||
bd->pd3dDevice->SetPixelShader(nullptr);
|
device->SetPixelShader(nullptr);
|
||||||
bd->pd3dDevice->SetVertexShader(nullptr);
|
device->SetVertexShader(nullptr);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
device->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
device->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
|
device->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||||
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
device->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||||
|
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||||
|
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||||
|
|
||||||
// Setup orthographic projection matrix
|
// Setup 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.
|
||||||
@@ -148,9 +162,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
|||||||
0.0f, 0.0f, 0.5f, 0.0f,
|
0.0f, 0.0f, 0.5f, 0.0f,
|
||||||
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||||
} } };
|
} } };
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
device->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
device->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
device->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,51 +175,60 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create and grow buffers if needed
|
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplDX9_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// Create and grow buffers if needed
|
||||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
{
|
{
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
if (device->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
{
|
{
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
if (device->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup the DX9 state
|
// Backup the DX9 state
|
||||||
IDirect3DStateBlock9* d3d9_state_block = nullptr;
|
IDirect3DStateBlock9* state_block = nullptr;
|
||||||
if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
if (device->CreateStateBlock(D3DSBT_ALL, &state_block) < 0)
|
||||||
return;
|
return;
|
||||||
if (d3d9_state_block->Capture() < 0)
|
if (state_block->Capture() < 0)
|
||||||
{
|
{
|
||||||
d3d9_state_block->Release();
|
state_block->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
||||||
D3DMATRIX last_world, last_view, last_projection;
|
D3DMATRIX last_world, last_view, last_projection;
|
||||||
bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
|
device->GetTransform(D3DTS_WORLD, &last_world);
|
||||||
bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
|
device->GetTransform(D3DTS_VIEW, &last_view);
|
||||||
bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
|
device->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||||
|
|
||||||
// Allocate buffers
|
// Allocate buffers
|
||||||
CUSTOMVERTEX* vtx_dst;
|
CUSTOMVERTEX* vtx_dst;
|
||||||
ImDrawIdx* idx_dst;
|
ImDrawIdx* idx_dst;
|
||||||
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||||
{
|
{
|
||||||
d3d9_state_block->Release();
|
state_block->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||||
{
|
{
|
||||||
bd->pVB->Unlock();
|
bd->pVB->Unlock();
|
||||||
d3d9_state_block->Release();
|
state_block->Release();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,11 +236,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
||||||
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
|
||||||
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
|
||||||
{
|
{
|
||||||
vtx_dst->pos[0] = vtx_src->pos.x;
|
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||||
vtx_dst->pos[1] = vtx_src->pos.y;
|
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||||
@@ -228,14 +250,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
vtx_dst++;
|
vtx_dst++;
|
||||||
vtx_src++;
|
vtx_src++;
|
||||||
}
|
}
|
||||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
idx_dst += cmd_list->IdxBuffer.Size;
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
}
|
}
|
||||||
bd->pVB->Unlock();
|
bd->pVB->Unlock();
|
||||||
bd->pIB->Unlock();
|
bd->pIB->Unlock();
|
||||||
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
device->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||||
bd->pd3dDevice->SetIndices(bd->pIB);
|
device->SetIndices(bd->pIB);
|
||||||
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
device->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||||
|
|
||||||
// Setup desired DX state
|
// Setup desired DX state
|
||||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||||
@@ -245,12 +267,11 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
int global_vtx_offset = 0;
|
int global_vtx_offset = 0;
|
||||||
int global_idx_offset = 0;
|
int global_idx_offset = 0;
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != nullptr)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -258,7 +279,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -268,16 +289,18 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
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;
|
||||||
|
|
||||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
// Apply scissor/clipping rectangle
|
||||||
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
device->SetScissorRect(&r);
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||||
bd->pd3dDevice->SetTexture(0, texture);
|
device->SetTexture(0, texture);
|
||||||
bd->pd3dDevice->SetScissorRect(&r);
|
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)draw_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
global_vtx_offset += cmd_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
|
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
|
||||||
@@ -286,55 +309,18 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
// Restore the DX9 transform
|
// Restore the DX9 transform
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
device->SetTransform(D3DTS_WORLD, &last_world);
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
device->SetTransform(D3DTS_VIEW, &last_view);
|
||||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
|
device->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||||
|
|
||||||
// Restore the DX9 state
|
// Restore the DX9 state
|
||||||
d3d9_state_block->Apply();
|
state_block->Apply();
|
||||||
d3d9_state_block->Release();
|
state_block->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
static bool ImGui_ImplDX9_CheckFormatSupport(LPDIRECT3DDEVICE9 pDevice, D3DFORMAT format)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
LPDIRECT3D9 pd3d = nullptr;
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
|
||||||
ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)();
|
|
||||||
io.BackendRendererUserData = (void*)bd;
|
|
||||||
io.BackendRendererName = "imgui_impl_dx9";
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
|
||||||
|
|
||||||
bd->pd3dDevice = device;
|
|
||||||
bd->pd3dDevice->AddRef();
|
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
ImGui_ImplDX9_InitPlatformInterface();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX9_Shutdown()
|
|
||||||
{
|
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
|
||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
ImGui_ImplDX9_ShutdownPlatformInterface();
|
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
|
||||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
|
||||||
io.BackendRendererName = nullptr;
|
|
||||||
io.BackendRendererUserData = nullptr;
|
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
|
||||||
IM_DELETE(bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMAT format)
|
|
||||||
{
|
|
||||||
IDirect3D9* pd3d = nullptr;
|
|
||||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||||
return false;
|
return false;
|
||||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||||
@@ -350,58 +336,131 @@ static bool ImGui_ImplDX9_CheckFormatSupport(IDirect3DDevice9* pDevice, D3DFORMA
|
|||||||
return support;
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
IMGUI_CHECKVERSION();
|
||||||
unsigned char* pixels;
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
int width, height, bytes_per_pixel;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
|
||||||
|
|
||||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
// Setup backend capabilities flags
|
||||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)();
|
||||||
const bool rgba_support = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
io.BackendRendererUserData = (void*)bd;
|
||||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
io.BackendRendererName = "imgui_impl_dx9";
|
||||||
{
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||||
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
|
||||||
pixels = (unsigned char*)dst_start;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
const bool rgba_support = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
bd->FontTexture = nullptr;
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = 4096;
|
||||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, rgba_support ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
|
||||||
return false;
|
|
||||||
D3DLOCKED_RECT tex_locked_rect;
|
|
||||||
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
|
||||||
return false;
|
|
||||||
for (int y = 0; y < height; y++)
|
|
||||||
memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
|
|
||||||
bd->FontTexture->UnlockRect(0);
|
|
||||||
|
|
||||||
// Store our identifier
|
bd->pd3dDevice = device;
|
||||||
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
bd->pd3dDevice->AddRef();
|
||||||
|
bd->HasRgbaSupport = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||||
|
|
||||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
ImGui_ImplDX9_InitMultiViewportSupport();
|
||||||
if (!rgba_support && io.Fonts->TexPixelsUseColors)
|
|
||||||
ImGui::MemFree(pixels);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX9_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
||||||
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||||
|
static void ImGui_ImplDX9_CopyTextureRegion(bool tex_use_colors, const ImU32* src, int src_pitch, ImU32* dst, int dst_pitch, int w, int h)
|
||||||
|
{
|
||||||
|
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
const bool convert_rgba_to_bgra = (!bd->HasRgbaSupport && tex_use_colors);
|
||||||
|
#else
|
||||||
|
const bool convert_rgba_to_bgra = false;
|
||||||
|
IM_UNUSED(tex_use_colors);
|
||||||
|
#endif
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
const ImU32* src_p = (const ImU32*)(const void*)((const unsigned char*)src + src_pitch * y);
|
||||||
|
ImU32* dst_p = (ImU32*)(void*)((unsigned char*)dst + dst_pitch * y);
|
||||||
|
if (convert_rgba_to_bgra)
|
||||||
|
for (int x = w; x > 0; x--, src_p++, dst_p++) // Convert copy
|
||||||
|
*dst_p = IMGUI_COL_TO_DX9_ARGB(*src_p);
|
||||||
|
else
|
||||||
|
memcpy(dst_p, src_p, w * 4); // Raw copy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX9_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
LPDIRECT3DTEXTURE9 dx_tex = nullptr;
|
||||||
|
HRESULT hr = bd->pd3dDevice->CreateTexture(tex->Width, tex->Height, 1, D3DUSAGE_DYNAMIC, bd->HasRgbaSupport ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dx_tex, nullptr);
|
||||||
|
if (hr < 0)
|
||||||
|
{
|
||||||
|
IM_ASSERT(hr >= 0 && "Backend failed to create texture!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DLOCKED_RECT locked_rect;
|
||||||
|
if (dx_tex->LockRect(0, &locked_rect, nullptr, 0) == D3D_OK)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX9_CopyTextureRegion(tex->UseColors, (ImU32*)tex->GetPixels(), tex->Width * 4, (ImU32*)locked_rect.pBits, (ImU32)locked_rect.Pitch, tex->Width, tex->Height);
|
||||||
|
dx_tex->UnlockRect(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)dx_tex);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)(intptr_t)tex->TexID;
|
||||||
|
RECT update_rect = { (LONG)tex->UpdateRect.x, (LONG)tex->UpdateRect.y, (LONG)(tex->UpdateRect.x + tex->UpdateRect.w), (LONG)(tex->UpdateRect.y + tex->UpdateRect.h) };
|
||||||
|
D3DLOCKED_RECT locked_rect;
|
||||||
|
if (backend_tex->LockRect(0, &locked_rect, &update_rect, 0) == D3D_OK)
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
ImGui_ImplDX9_CopyTextureRegion(tex->UseColors, (ImU32*)tex->GetPixelsAt(r.x, r.y), tex->Width * 4,
|
||||||
|
(ImU32*)locked_rect.pBits + (r.x - update_rect.left) + (r.y - update_rect.top) * (locked_rect.Pitch / 4), (int)locked_rect.Pitch, r.w, r.h);
|
||||||
|
backend_tex->UnlockRect(0);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)tex->TexID;
|
||||||
|
if (backend_tex == nullptr)
|
||||||
|
return;
|
||||||
|
IM_ASSERT(tex->TexID == (ImTextureID)(intptr_t)backend_tex);
|
||||||
|
backend_tex->Release();
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui_ImplDX9_CreateDeviceObjects()
|
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;
|
||||||
if (!ImGui_ImplDX9_CreateFontsTexture())
|
|
||||||
return false;
|
|
||||||
ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -411,9 +470,16 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
|
|||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
if (!bd || !bd->pd3dDevice)
|
if (!bd || !bd->pd3dDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
{
|
||||||
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplDX9_UpdateTexture(tex);
|
||||||
|
}
|
||||||
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; }
|
||||||
if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,9 +487,7 @@ void ImGui_ImplDX9_NewFrame()
|
|||||||
{
|
{
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX9_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX9_Init()?");
|
||||||
|
IM_UNUSED(bd);
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplDX9_CreateDeviceObjects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
@@ -448,7 +512,7 @@ static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport)
|
|||||||
ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)();
|
ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)();
|
||||||
viewport->RendererUserData = vd;
|
viewport->RendererUserData = vd;
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
// 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.
|
// 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;
|
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||||
IM_ASSERT(hwnd != 0);
|
IM_ASSERT(hwnd != 0);
|
||||||
@@ -537,7 +601,7 @@ static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
|
|||||||
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
|
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX9_InitPlatformInterface()
|
static void ImGui_ImplDX9_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
||||||
@@ -547,7 +611,7 @@ static void ImGui_ImplDX9_InitPlatformInterface()
|
|||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX9_ShutdownPlatformInterface()
|
static void ImGui_ImplDX9_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: 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'.
|
// [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.
|
||||||
@@ -30,4 +32,7 @@ IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
|
|||||||
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX9_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). 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] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
// Issues:
|
// [X] Multiple Dear ImGui contexts support.
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// Missing features or Issues:
|
||||||
|
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||||
|
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||||
|
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -28,8 +31,17 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
// 2025-07-08: Made ImGui_ImplGlfw_GetContentScaleForWindow(), ImGui_ImplGlfw_GetContentScaleForMonitor() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
|
||||||
|
// 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069)
|
||||||
|
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
|
||||||
|
// 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-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:
|
||||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||||
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
||||||
@@ -96,6 +108,8 @@
|
|||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GLFW
|
// GLFW
|
||||||
@@ -117,6 +131,7 @@
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h> // for usleep()
|
#include <unistd.h> // for usleep()
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdio.h> // for snprintf()
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
@@ -156,6 +171,17 @@
|
|||||||
#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()
|
||||||
|
#define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform()
|
||||||
|
|
||||||
|
// Map GLFWWindow* to ImGuiContext*.
|
||||||
|
// - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource.
|
||||||
|
// - Would be simpler if we could use e.g. std::map<> as well. But we don't.
|
||||||
|
// - This is not particularly optimized as we expect size to be small and queries to be rare.
|
||||||
|
struct ImGui_ImplGlfw_WindowToContext { GLFWwindow* Window; ImGuiContext* Context; };
|
||||||
|
static ImVector<ImGui_ImplGlfw_WindowToContext> g_ContextMap;
|
||||||
|
static void ImGui_ImplGlfw_ContextMap_Add(GLFWwindow* window, ImGuiContext* ctx) { g_ContextMap.push_back(ImGui_ImplGlfw_WindowToContext{ window, ctx }); }
|
||||||
|
static void ImGui_ImplGlfw_ContextMap_Remove(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) { g_ContextMap.erase_unsorted(&entry); return; } }
|
||||||
|
static ImGuiContext* ImGui_ImplGlfw_ContextMap_Get(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) return entry.Context; return nullptr; }
|
||||||
|
|
||||||
// GLFW data
|
// GLFW data
|
||||||
enum GlfwClientApi
|
enum GlfwClientApi
|
||||||
@@ -167,16 +193,19 @@ enum GlfwClientApi
|
|||||||
|
|
||||||
struct ImGui_ImplGlfw_Data
|
struct ImGui_ImplGlfw_Data
|
||||||
{
|
{
|
||||||
|
ImGuiContext* Context;
|
||||||
GLFWwindow* Window;
|
GLFWwindow* Window;
|
||||||
GlfwClientApi ClientApi;
|
GlfwClientApi ClientApi;
|
||||||
double Time;
|
double Time;
|
||||||
GLFWwindow* MouseWindow;
|
GLFWwindow* MouseWindow;
|
||||||
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||||
|
bool MouseIgnoreButtonUpWaitForFocusLoss;
|
||||||
|
bool MouseIgnoreButtonUp;
|
||||||
ImVec2 LastValidMousePos;
|
ImVec2 LastValidMousePos;
|
||||||
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
||||||
bool InstalledCallbacks;
|
bool InstalledCallbacks;
|
||||||
bool CallbacksChainForAllWindows;
|
bool CallbacksChainForAllWindows;
|
||||||
bool WantUpdateMonitors;
|
char BackendPlatformName[32];
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
const char* CanvasSelector;
|
const char* CanvasSelector;
|
||||||
#endif
|
#endif
|
||||||
@@ -204,19 +233,28 @@ struct ImGui_ImplGlfw_Data
|
|||||||
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
|
// (passing install_callbacks=false in ImGui_ImplGlfw_InitXXX functions), set the current dear imgui context and then call our callbacks.
|
||||||
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
|
// - Otherwise we may need to store a GLFWWindow* -> ImGuiContext* map and handle this in the backend, adding a little bit of extra complexity to it.
|
||||||
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
||||||
|
namespace ImGui { extern ImGuiIO& GetIO(ImGuiContext*); }
|
||||||
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
||||||
{
|
{
|
||||||
|
// Get data for current context
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplGlfw_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window)
|
||||||
|
{
|
||||||
|
// Get data for a given GLFW window, regardless of current context (since GLFW events are sent together)
|
||||||
|
ImGuiContext* ctx = ImGui_ImplGlfw_ContextMap_Get(window);
|
||||||
|
return (ImGui_ImplGlfw_Data*)ImGui::GetIO(ctx).BackendPlatformUserData;
|
||||||
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplGlfw_UpdateMonitors();
|
static void ImGui_ImplGlfw_UpdateMonitors();
|
||||||
static void ImGui_ImplGlfw_InitPlatformInterface();
|
static void ImGui_ImplGlfw_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface();
|
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode);
|
||||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
||||||
{
|
{
|
||||||
IM_UNUSED(scancode);
|
IM_UNUSED(scancode);
|
||||||
@@ -246,6 +284,8 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
|||||||
case GLFW_KEY_EQUAL: return ImGuiKey_Equal;
|
case GLFW_KEY_EQUAL: return ImGuiKey_Equal;
|
||||||
case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||||
case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash;
|
case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash;
|
||||||
|
case GLFW_KEY_WORLD_1: return ImGuiKey_Oem102;
|
||||||
|
case GLFW_KEY_WORLD_2: return ImGuiKey_Oem102;
|
||||||
case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||||
case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
|
case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
|
||||||
case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock;
|
case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||||
@@ -345,38 +385,39 @@ ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
|||||||
|
|
||||||
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
|
// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
|
||||||
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
|
// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
|
||||||
static void ImGui_ImplGlfw_UpdateKeyModifiers(GLFWwindow* window)
|
static void ImGui_ImplGlfw_UpdateKeyModifiers(ImGuiIO& io, GLFWwindow* window)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
|
io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
|
||||||
io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
|
io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
|
||||||
io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
|
io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
|
||||||
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
|
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplGlfw_ShouldChainCallback(GLFWwindow* window)
|
static bool ImGui_ImplGlfw_ShouldChainCallback(ImGui_ImplGlfw_Data* bd, GLFWwindow* window)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
return bd->CallbacksChainForAllWindows ? true : (window == bd->Window);
|
return bd->CallbacksChainForAllWindows ? true : (window == bd->Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
||||||
|
|
||||||
ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
// 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();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
|
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
||||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||||
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
|
io.AddMouseButtonEvent(button, action == GLFW_PRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
@@ -384,7 +425,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,21 +465,21 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods)
|
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, int action, int mods)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackKey != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackKey != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackKey(window, keycode, scancode, action, mods);
|
bd->PrevUserCallbackKey(window, keycode, scancode, action, mods);
|
||||||
|
|
||||||
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
if (action != GLFW_PRESS && action != GLFW_RELEASE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
|
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
||||||
|
|
||||||
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
|
||||||
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
||||||
|
|
||||||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
||||||
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
||||||
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
||||||
@@ -446,21 +487,25 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackWindowFocus(window, focused);
|
bd->PrevUserCallbackWindowFocus(window, focused);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
// 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);
|
||||||
io.AddFocusEvent(focused != 0);
|
io.AddFocusEvent(focused != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
int window_x, window_y;
|
int window_x, window_y;
|
||||||
@@ -476,11 +521,11 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|||||||
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
|
// so we back it up and restore on Leave/Enter (see https://github.com/ocornut/imgui/issues/4984)
|
||||||
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackCursorEnter(window, entered);
|
bd->PrevUserCallbackCursorEnter(window, entered);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
if (entered)
|
if (entered)
|
||||||
{
|
{
|
||||||
bd->MouseWindow = window;
|
bd->MouseWindow = window;
|
||||||
@@ -496,32 +541,32 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
if (bd->PrevUserCallbackChar != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
if (bd->PrevUserCallbackChar != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackChar(window, c);
|
bd->PrevUserCallbackChar(window, c);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
io.AddInputCharacter(c);
|
io.AddInputCharacter(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
// This function is technically part of the API even if we stopped using the callback, so leaving it around.
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void*)
|
static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void* user_data)
|
||||||
{
|
{
|
||||||
// Mimic Emscripten_HandleWheel() in SDL.
|
// Mimic Emscripten_HandleWheel() in SDL.
|
||||||
// Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096
|
// Corresponding equivalent in GLFW JS emulation layer has incorrect quantizing preventing small values. See #6096
|
||||||
|
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||||
float multiplier = 0.0f;
|
float multiplier = 0.0f;
|
||||||
if (ev->deltaMode == DOM_DELTA_PIXEL) { multiplier = 1.0f / 100.0f; } // 100 pixels make up a step.
|
if (ev->deltaMode == DOM_DELTA_PIXEL) { multiplier = 1.0f / 100.0f; } // 100 pixels make up a step.
|
||||||
else if (ev->deltaMode == DOM_DELTA_LINE) { multiplier = 1.0f / 3.0f; } // 3 lines make up a step.
|
else if (ev->deltaMode == DOM_DELTA_LINE) { multiplier = 1.0f / 3.0f; } // 3 lines make up a step.
|
||||||
else if (ev->deltaMode == DOM_DELTA_PAGE) { multiplier = 80.0f; } // A page makes up 80 steps.
|
else if (ev->deltaMode == DOM_DELTA_PAGE) { multiplier = 80.0f; } // A page makes up 80 steps.
|
||||||
float wheel_x = ev->deltaX * -multiplier;
|
float wheel_x = ev->deltaX * -multiplier;
|
||||||
float wheel_y = ev->deltaY * -multiplier;
|
float wheel_y = ev->deltaY * -multiplier;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
||||||
//IMGUI_DEBUG_LOG("[Emsc] mode %d dx: %.2f, dy: %.2f, dz: %.2f --> feed %.2f %.2f\n", (int)ev->deltaMode, ev->deltaX, ev->deltaY, ev->deltaZ, wheel_x, wheel_y);
|
//IMGUI_DEBUG_LOG("[Emsc] mode %d dx: %.2f, dy: %.2f, dz: %.2f --> feed %.2f %.2f\n", (int)ev->deltaMode, ev->deltaX, ev->deltaY, ev->deltaZ, wheel_x, wheel_y);
|
||||||
return EM_TRUE;
|
return EM_TRUE;
|
||||||
@@ -534,7 +579,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
IM_ASSERT(bd->InstalledCallbacks == false && "Callbacks already installed!");
|
||||||
IM_ASSERT(bd->Window == window);
|
IM_ASSERT(bd->Window == window);
|
||||||
|
|
||||||
@@ -551,7 +596,7 @@ void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||||
IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
IM_ASSERT(bd->InstalledCallbacks == true && "Callbacks not installed!");
|
||||||
IM_ASSERT(bd->Window == window);
|
IM_ASSERT(bd->Window == window);
|
||||||
|
|
||||||
@@ -601,24 +646,40 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)();
|
ImGui_ImplGlfw_Data* bd = IM_NEW(ImGui_ImplGlfw_Data)();
|
||||||
|
snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_glfw (%d)", GLFW_VERSION_COMBINED);
|
||||||
io.BackendPlatformUserData = (void*)bd;
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
io.BackendPlatformName = "imgui_impl_glfw";
|
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)
|
||||||
|
|
||||||
|
bool has_viewports = false;
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
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
|
#endif
|
||||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bd->Context = ImGui::GetCurrentContext();
|
||||||
bd->Window = window;
|
bd->Window = window;
|
||||||
bd->Time = 0.0;
|
bd->Time = 0.0;
|
||||||
bd->WantUpdateMonitors = true;
|
ImGui_ImplGlfw_ContextMap_Add(window, bd->Context);
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(NULL, text); };
|
#if GLFW_VERSION_COMBINED < 3300
|
||||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(NULL); };
|
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window, text); };
|
||||||
|
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window); };
|
||||||
|
#else
|
||||||
|
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); };
|
||||||
|
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); };
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; };
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; };
|
||||||
#endif
|
#endif
|
||||||
@@ -668,12 +729,14 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
#else
|
#else
|
||||||
IM_UNUSED(main_viewport);
|
IM_UNUSED(main_viewport);
|
||||||
#endif
|
#endif
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (has_viewports)
|
||||||
ImGui_ImplGlfw_InitPlatformInterface();
|
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
|
||||||
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
HWND hwnd = (HWND)main_viewport->PlatformHandleRaw;
|
||||||
|
::SetPropA(hwnd, "IMGUI_BACKEND_DATA", bd);
|
||||||
|
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
||||||
IM_ASSERT(bd->PrevWndProc != nullptr);
|
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||||
::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
|
||||||
@@ -684,7 +747,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
||||||
if (emscripten::glfw3::IsRuntimePlatformApple())
|
if (emscripten::glfw3::IsRuntimePlatformApple())
|
||||||
{
|
{
|
||||||
ImGui::GetIO().ConfigMacOSXBehaviors = true;
|
io.ConfigMacOSXBehaviors = true;
|
||||||
|
|
||||||
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
||||||
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
||||||
@@ -720,7 +783,7 @@ void ImGui_ImplGlfw_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplGlfw_ShutdownPlatformInterface();
|
ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
if (bd->InstalledCallbacks)
|
if (bd->InstalledCallbacks)
|
||||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||||
@@ -735,6 +798,7 @@ void ImGui_ImplGlfw_Shutdown()
|
|||||||
// Windows: restore our WndProc hook
|
// Windows: restore our WndProc hook
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
|
::SetPropA((HWND)main_viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", nullptr);
|
||||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||||
bd->PrevWndProc = nullptr;
|
bd->PrevWndProc = nullptr;
|
||||||
#endif
|
#endif
|
||||||
@@ -742,6 +806,7 @@ void ImGui_ImplGlfw_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 | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||||
|
ImGui_ImplGlfw_ContextMap_Remove(bd->Window);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -765,7 +830,7 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
|||||||
#endif
|
#endif
|
||||||
if (is_window_focused)
|
if (is_window_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos 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.
|
// 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)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
|
||||||
@@ -848,7 +913,7 @@ static inline float Saturate(float v) { return v < 0.0f ? 0.0f : v > 1.0f ? 1.0
|
|||||||
static void ImGui_ImplGlfw_UpdateGamepads()
|
static void ImGui_ImplGlfw_UpdateGamepads()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs, but see #8075
|
||||||
return;
|
return;
|
||||||
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||||
@@ -898,9 +963,7 @@ static void ImGui_ImplGlfw_UpdateGamepads()
|
|||||||
|
|
||||||
static void ImGui_ImplGlfw_UpdateMonitors()
|
static void ImGui_ImplGlfw_UpdateMonitors()
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
bd->WantUpdateMonitors = false;
|
|
||||||
|
|
||||||
int monitors_count = 0;
|
int monitors_count = 0;
|
||||||
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
||||||
@@ -927,35 +990,63 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
|||||||
monitor.WorkSize = ImVec2((float)w, (float)h);
|
monitor.WorkSize = ImVec2((float)w, (float)h);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if GLFW_HAS_PER_MONITOR_DPI
|
float scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfw_monitors[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.
|
if (scale == 0.0f)
|
||||||
float x_scale, y_scale;
|
|
||||||
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
|
|
||||||
if (x_scale == 0.0f)
|
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
||||||
monitor.DpiScale = x_scale;
|
monitor.DpiScale = scale;
|
||||||
#endif
|
|
||||||
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
||||||
platform_io.Monitors.push_back(monitor);
|
platform_io.Monitors.push_back(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - On Windows the process needs to be marked DPI-aware!! SDL2 doesn't do it by default. You can call ::SetProcessDPIAware() or call ImGui_ImplWin32_EnableDpiAwareness() from Win32 backend.
|
||||||
|
// - Apple platforms use FramebufferScale so we always return 1.0f.
|
||||||
|
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
|
||||||
|
float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
|
||||||
|
{
|
||||||
|
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
|
||||||
|
float x_scale, y_scale;
|
||||||
|
glfwGetWindowContentScale(window, &x_scale, &y_scale);
|
||||||
|
return x_scale;
|
||||||
|
#else
|
||||||
|
IM_UNUSED(window);
|
||||||
|
return 1.0f;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
|
||||||
|
float x_scale, y_scale;
|
||||||
|
glfwGetMonitorContentScale(monitor, &x_scale, &y_scale);
|
||||||
|
return x_scale;
|
||||||
|
#else
|
||||||
|
IM_UNUSED(monitor);
|
||||||
|
return 1.0f;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
int display_w, display_h;
|
||||||
|
glfwGetWindowSize(window, &w, &h);
|
||||||
|
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||||
|
if (out_size != nullptr)
|
||||||
|
*out_size = ImVec2((float)w, (float)h);
|
||||||
|
if (out_framebuffer_scale != nullptr)
|
||||||
|
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / (float)w, (float)display_h / (float)h) : ImVec2(1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplGlfw_NewFrame()
|
void ImGui_ImplGlfw_NewFrame()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
int w, h;
|
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
int display_w, display_h;
|
ImGui_ImplGlfw_UpdateMonitors();
|
||||||
glfwGetWindowSize(bd->Window, &w, &h);
|
|
||||||
glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
|
|
||||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
|
||||||
if (w > 0 && h > 0)
|
|
||||||
io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h);
|
|
||||||
if (bd->WantUpdateMonitors)
|
|
||||||
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)
|
||||||
@@ -965,6 +1056,7 @@ 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();
|
||||||
|
|
||||||
@@ -1019,7 +1111,7 @@ void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow*, const char* canvas_s
|
|||||||
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
||||||
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
||||||
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
||||||
emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
emscripten_set_wheel_callback(bd->CanvasSelector, bd, false, ImGui_ImplEmscripten_WheelCallback);
|
||||||
}
|
}
|
||||||
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
||||||
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
||||||
@@ -1041,10 +1133,10 @@ void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* c
|
|||||||
// 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..
|
// 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.
|
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
struct ImGui_ImplGlfw_ViewportData
|
struct ImGui_ImplGlfw_ViewportData
|
||||||
{
|
{
|
||||||
GLFWwindow* Window;
|
GLFWwindow* Window; // Stored in ImGuiViewport::PlatformHandle
|
||||||
bool WindowOwned;
|
bool WindowOwned;
|
||||||
int IgnoreWindowPosEventFrame;
|
int IgnoreWindowPosEventFrame;
|
||||||
int IgnoreWindowSizeEventFrame;
|
int IgnoreWindowSizeEventFrame;
|
||||||
@@ -1052,7 +1144,7 @@ struct ImGui_ImplGlfw_ViewportData
|
|||||||
WNDPROC PrevWndProc;
|
WNDPROC PrevWndProc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui_ImplGlfw_ViewportData() { memset(this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
ImGui_ImplGlfw_ViewportData() { memset((void*)this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||||
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1104,6 +1196,11 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
|||||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
||||||
viewport->PlatformUserData = vd;
|
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
|
// 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
|
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
||||||
glfwWindowHint(GLFW_VISIBLE, false);
|
glfwWindowHint(GLFW_VISIBLE, false);
|
||||||
@@ -1118,9 +1215,11 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
|||||||
GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : nullptr;
|
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->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", nullptr, share_window);
|
||||||
vd->WindowOwned = true;
|
vd->WindowOwned = true;
|
||||||
|
ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context);
|
||||||
viewport->PlatformHandle = (void*)vd->Window;
|
viewport->PlatformHandle = (void*)vd->Window;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
|
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
|
||||||
|
::SetPropA((HWND)viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", bd);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
|
viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
|
||||||
#endif
|
#endif
|
||||||
@@ -1162,6 +1261,7 @@ static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
|||||||
if (bd->KeyOwnerWindows[i] == vd->Window)
|
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_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);
|
glfwDestroyWindow(vd->Window);
|
||||||
}
|
}
|
||||||
vd->Window = nullptr;
|
vd->Window = nullptr;
|
||||||
@@ -1185,12 +1285,10 @@ static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
|||||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLFW hack: install hook for WM_NCHITTEST message handler
|
// GLFW hack: install WndProc for mouse source event and WM_NCHITTEST message handler.
|
||||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
|
||||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
||||||
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
||||||
::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !GLFW_HAS_FOCUS_ON_SHOW
|
#if !GLFW_HAS_FOCUS_ON_SHOW
|
||||||
// GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
|
// GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
|
||||||
@@ -1234,7 +1332,7 @@ static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
|
|||||||
static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||||
#if __APPLE__ && !GLFW_HAS_OSX_WINDOW_POS_FIX
|
#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
|
// 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
|
// 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
|
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
|
||||||
@@ -1248,6 +1346,14 @@ static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|||||||
glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
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)
|
static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
||||||
@@ -1334,7 +1440,7 @@ static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
|
|||||||
}
|
}
|
||||||
#endif // GLFW_HAS_VULKAN
|
#endif // GLFW_HAS_VULKAN
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_InitPlatformInterface()
|
static void ImGui_ImplGlfw_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
// Register platform interface (will be coupled with a renderer interface)
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
@@ -1346,6 +1452,7 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
|
|||||||
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
|
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
|
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
|
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
|
||||||
|
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplGlfw_GetWindowFramebufferScale;
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
|
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
|
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
|
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
|
||||||
@@ -1369,7 +1476,7 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
|
|||||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
@@ -1389,7 +1496,9 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|||||||
}
|
}
|
||||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)::GetPropA(hWnd, "IMGUI_BACKEND_DATA");
|
||||||
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
|
|
||||||
WNDPROC prev_wndproc = bd->PrevWndProc;
|
WNDPROC prev_wndproc = bd->PrevWndProc;
|
||||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||||
if (viewport != NULL)
|
if (viewport != NULL)
|
||||||
@@ -1405,7 +1514,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|||||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
io.AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||||
@@ -1422,6 +1531,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam);
|
return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,15 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). 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] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
// Issues:
|
// [X] Multiple Dear ImGui contexts support.
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// Missing features or Issues:
|
||||||
|
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||||
|
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||||
|
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -63,5 +66,8 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int
|
|||||||
|
|
||||||
// GLFW helpers
|
// GLFW helpers
|
||||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
|
IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window);
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Partial 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 GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Platform: Partial 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 GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// Missing features:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||||
// [ ] 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.
|
||||||
@@ -50,7 +51,7 @@
|
|||||||
|
|
||||||
static int g_Time = 0; // Current time, in milliseconds
|
static int g_Time = 0; // Current time, in milliseconds
|
||||||
|
|
||||||
// Glut has 1 function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above.
|
// Glut has one function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above.
|
||||||
static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
|
static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Partial 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 GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [X] Platform: Partial 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 GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// Missing features:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||||
// [ ] 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.
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. OSX)
|
// This needs to be used along with a Platform Backend (e.g. OSX)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -14,6 +15,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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
@@ -35,11 +37,12 @@ IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData,
|
|||||||
id<MTLRenderCommandEncoder> commandEncoder);
|
id<MTLRenderCommandEncoder> commandEncoder);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device);
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device);
|
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device);
|
||||||
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -62,11 +65,12 @@ IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data,
|
|||||||
MTL::RenderCommandEncoder* commandEncoder);
|
MTL::RenderCommandEncoder* commandEncoder);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateFontsTexture(MTL::Device* device);
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device);
|
IMGUI_IMPL_API bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device);
|
||||||
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplMetal_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. OSX)
|
// This needs to be used along with a Platform Backend (e.g. OSX)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [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.
|
||||||
@@ -16,7 +17,10 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplMetal_CreateFontsTexture() and ImGui_ImplMetal_DestroyFontsTexture().
|
||||||
|
// 2025-02-03: Metal: Crash fix. (#8367)
|
||||||
|
// 2025-01-08: Metal: Fixed memory leaks when using metal-cpp (#8276, #8166) or when using multiple contexts (#7419).
|
||||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||||
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
||||||
@@ -41,8 +45,8 @@
|
|||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplMetal_InitPlatformInterface();
|
static void ImGui_ImplMetal_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplMetal_ShutdownPlatformInterface();
|
static void ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
||||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||||
|
|
||||||
@@ -65,6 +69,11 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|||||||
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor;
|
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface MetalTexture : NSObject
|
||||||
|
@property (nonatomic, strong) id<MTLTexture> metalTexture;
|
||||||
|
- (instancetype)initWithTexture:(id<MTLTexture>)metalTexture;
|
||||||
|
@end
|
||||||
|
|
||||||
// A singleton that stores long-lived objects that are needed by the Metal
|
// A singleton that stores long-lived objects that are needed by the Metal
|
||||||
// renderer backend. Stores the render pipeline state cache and the default
|
// renderer backend. Stores the render pipeline state cache and the default
|
||||||
// font texture, and manages the reusable buffer cache.
|
// font texture, and manages the reusable buffer cache.
|
||||||
@@ -73,7 +82,6 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|||||||
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
@property (nonatomic, strong) id<MTLDepthStencilState> depthStencilState;
|
||||||
@property (nonatomic, strong) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
@property (nonatomic, strong) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient
|
||||||
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors
|
||||||
@property (nonatomic, strong, nullable) id<MTLTexture> fontTexture;
|
|
||||||
@property (nonatomic, strong) NSMutableArray<MetalBuffer*>* bufferCache;
|
@property (nonatomic, strong) NSMutableArray<MetalBuffer*>* bufferCache;
|
||||||
@property (nonatomic, assign) double lastBufferCachePurge;
|
@property (nonatomic, assign) double lastBufferCachePurge;
|
||||||
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
||||||
@@ -84,7 +92,7 @@ struct ImGui_ImplMetal_Data
|
|||||||
{
|
{
|
||||||
MetalContext* SharedMetalContext;
|
MetalContext* SharedMetalContext;
|
||||||
|
|
||||||
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
|
ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
|
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
|
||||||
@@ -116,11 +124,6 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateFontsTexture(MTL::Device* device)
|
|
||||||
{
|
|
||||||
return ImGui_ImplMetal_CreateFontsTexture((__bridge id<MTLDevice>)(device));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
|
bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
|
||||||
{
|
{
|
||||||
return ImGui_ImplMetal_CreateDeviceObjects((__bridge id<MTLDevice>)(device));
|
return ImGui_ImplMetal_CreateDeviceObjects((__bridge id<MTLDevice>)(device));
|
||||||
@@ -140,13 +143,13 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
bd->SharedMetalContext = [[MetalContext alloc] init];
|
bd->SharedMetalContext = [[MetalContext alloc] init];
|
||||||
bd->SharedMetalContext.device = device;
|
bd->SharedMetalContext.device = device;
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
ImGui_ImplMetal_InitMultiViewportSupport();
|
||||||
ImGui_ImplMetal_InitPlatformInterface();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -154,28 +157,32 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
void ImGui_ImplMetal_Shutdown()
|
void ImGui_ImplMetal_Shutdown()
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
|
IM_UNUSED(bd);
|
||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGui_ImplMetal_ShutdownPlatformInterface();
|
ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
||||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
ImGui_ImplMetal_DestroyBackendData();
|
ImGui_ImplMetal_DestroyBackendData();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal_Init()?");
|
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal_Init()?");
|
||||||
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
|
bd->SharedMetalContext.framebufferDescriptor = [[[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]autorelease];
|
||||||
|
#else
|
||||||
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
||||||
|
#endif
|
||||||
if (bd->SharedMetalContext.depthStencilState == nil)
|
if (bd->SharedMetalContext.depthStencilState == nil)
|
||||||
ImGui_ImplMetal_CreateDeviceObjects(bd->SharedMetalContext.device);
|
ImGui_ImplMetal_CreateDeviceObjects(bd->SharedMetalContext.device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplMetal_SetupRenderState(ImDrawData* drawData, id<MTLCommandBuffer> commandBuffer,
|
static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer,
|
||||||
id<MTLRenderCommandEncoder> commandEncoder, id<MTLRenderPipelineState> renderPipelineState,
|
id<MTLRenderCommandEncoder> commandEncoder, id<MTLRenderPipelineState> renderPipelineState,
|
||||||
MetalBuffer* vertexBuffer, size_t vertexBufferOffset)
|
MetalBuffer* vertexBuffer, size_t vertexBufferOffset)
|
||||||
{
|
{
|
||||||
@@ -191,17 +198,17 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* drawData, id<MTLCommand
|
|||||||
{
|
{
|
||||||
.originX = 0.0,
|
.originX = 0.0,
|
||||||
.originY = 0.0,
|
.originY = 0.0,
|
||||||
.width = (double)(drawData->DisplaySize.x * drawData->FramebufferScale.x),
|
.width = (double)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x),
|
||||||
.height = (double)(drawData->DisplaySize.y * drawData->FramebufferScale.y),
|
.height = (double)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y),
|
||||||
.znear = 0.0,
|
.znear = 0.0,
|
||||||
.zfar = 1.0
|
.zfar = 1.0
|
||||||
};
|
};
|
||||||
[commandEncoder setViewport:viewport];
|
[commandEncoder setViewport:viewport];
|
||||||
|
|
||||||
float L = drawData->DisplayPos.x;
|
float L = draw_data->DisplayPos.x;
|
||||||
float R = drawData->DisplayPos.x + drawData->DisplaySize.x;
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
float T = drawData->DisplayPos.y;
|
float T = draw_data->DisplayPos.y;
|
||||||
float B = drawData->DisplayPos.y + drawData->DisplaySize.y;
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
float N = (float)viewport.znear;
|
float N = (float)viewport.znear;
|
||||||
float F = (float)viewport.zfar;
|
float F = (float)viewport.zfar;
|
||||||
const float ortho_projection[4][4] =
|
const float ortho_projection[4][4] =
|
||||||
@@ -220,17 +227,24 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* drawData, id<MTLCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Metal Render function.
|
// Metal Render function.
|
||||||
void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer> commandBuffer, id<MTLRenderCommandEncoder> commandEncoder)
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
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)(drawData->DisplaySize.x * drawData->FramebufferScale.x);
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||||
int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplMetal_UpdateTexture(tex);
|
||||||
|
|
||||||
// Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame
|
// Try to retrieve a render pipeline state that is compatible with the framebuffer config for this frame
|
||||||
// The hit rate for this cache should be very near 100%.
|
// The hit rate for this cache should be very near 100%.
|
||||||
id<MTLRenderPipelineState> renderPipelineState = ctx.renderPipelineStateCache[ctx.framebufferDescriptor];
|
id<MTLRenderPipelineState> renderPipelineState = ctx.renderPipelineStateCache[ctx.framebufferDescriptor];
|
||||||
@@ -243,38 +257,36 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||||||
ctx.renderPipelineStateCache[ctx.framebufferDescriptor] = renderPipelineState;
|
ctx.renderPipelineStateCache[ctx.framebufferDescriptor] = renderPipelineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t vertexBufferLength = (size_t)drawData->TotalVtxCount * sizeof(ImDrawVert);
|
size_t vertexBufferLength = (size_t)draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||||
size_t indexBufferLength = (size_t)drawData->TotalIdxCount * sizeof(ImDrawIdx);
|
size_t indexBufferLength = (size_t)draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||||
MetalBuffer* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
|
MetalBuffer* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device];
|
||||||
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
||||||
|
|
||||||
ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_off = drawData->DisplayPos; // (0,0) unless using multi-viewports
|
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||||
ImVec2 clip_scale = drawData->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)
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
size_t vertexBufferOffset = 0;
|
size_t vertexBufferOffset = 0;
|
||||||
size_t indexBufferOffset = 0;
|
size_t indexBufferOffset = 0;
|
||||||
for (int n = 0; n < drawData->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
|
||||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset);
|
ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -304,7 +316,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(void*)(intptr_t)(tex_id) atIndex:0];
|
||||||
|
|
||||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
@@ -315,62 +327,88 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
vertexBufferOffset += (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||||
indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
indexBufferOffset += (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetalContext* sharedMetalContext = bd->SharedMetalContext;
|
||||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
|
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
|
||||||
{
|
{
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
@synchronized(sharedMetalContext.bufferCache)
|
||||||
if (bd != nullptr)
|
|
||||||
{
|
{
|
||||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
[sharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||||
{
|
[sharedMetalContext.bufferCache addObject:indexBuffer];
|
||||||
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
|
|
||||||
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
MetalTexture* backend_tex = (__bridge_transfer MetalTexture*)(tex->BackendUserData);
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (backend_tex == nullptr)
|
||||||
|
return;
|
||||||
|
IM_ASSERT(backend_tex.metalTexture == (__bridge id<MTLTexture>)(void*)(intptr_t)tex->TexID);
|
||||||
|
backend_tex.metalTexture = nil;
|
||||||
|
|
||||||
// We are retrieving and uploading the font atlas as a 4-channels RGBA texture here.
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
// In theory we could call GetTexDataAsAlpha8() and upload a 1-channel texture to save on memory access bandwidth.
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
// However, using a shader designed for 1-channel texture would make it less obvious to use the ImTextureID facility to render users own textures.
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
// You can make that change in your implementation.
|
tex->BackendUserData = nullptr;
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
|
||||||
MTLTextureDescriptor* textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
|
|
||||||
width:(NSUInteger)width
|
|
||||||
height:(NSUInteger)height
|
|
||||||
mipmapped:NO];
|
|
||||||
textureDescriptor.usage = MTLTextureUsageShaderRead;
|
|
||||||
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
|
||||||
textureDescriptor.storageMode = MTLStorageModeManaged;
|
|
||||||
#else
|
|
||||||
textureDescriptor.storageMode = MTLStorageModeShared;
|
|
||||||
#endif
|
|
||||||
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
|
|
||||||
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4];
|
|
||||||
bd->SharedMetalContext.fontTexture = texture;
|
|
||||||
io.Fonts->SetTexID((__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == void*
|
|
||||||
|
|
||||||
return (bd->SharedMetalContext.fontTexture != nil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplMetal_DestroyFontsTexture()
|
void ImGui_ImplMetal_UpdateTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
bd->SharedMetalContext.fontTexture = nil;
|
{
|
||||||
io.Fonts->SetTexID(0);
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// We are retrieving and uploading the font atlas as a 4-channels RGBA texture here.
|
||||||
|
// In theory we could call GetTexDataAsAlpha8() and upload a 1-channel texture to save on memory access bandwidth.
|
||||||
|
// However, using a shader designed for 1-channel texture would make it less obvious to use the ImTextureID facility to render users own textures.
|
||||||
|
// You can make that change in your implementation.
|
||||||
|
MTLTextureDescriptor* textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
|
||||||
|
width:(NSUInteger)tex->Width
|
||||||
|
height:(NSUInteger)tex->Height
|
||||||
|
mipmapped:NO];
|
||||||
|
textureDescriptor.usage = MTLTextureUsageShaderRead;
|
||||||
|
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
|
||||||
|
textureDescriptor.storageMode = MTLStorageModeManaged;
|
||||||
|
#else
|
||||||
|
textureDescriptor.storageMode = MTLStorageModeShared;
|
||||||
|
#endif
|
||||||
|
id <MTLTexture> texture = [bd->SharedMetalContext.device newTextureWithDescriptor:textureDescriptor];
|
||||||
|
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)tex->Width, (NSUInteger)tex->Height) mipmapLevel:0 withBytes:tex->Pixels bytesPerRow:(NSUInteger)tex->Width * 4];
|
||||||
|
MetalTexture* backend_tex = [[MetalTexture alloc] initWithTexture:texture];
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)texture);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
tex->BackendUserData = (__bridge_retained void*)(backend_tex);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
MetalTexture* backend_tex = (__bridge MetalTexture*)(tex->BackendUserData);
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
[backend_tex.metalTexture replaceRegion:MTLRegionMake2D((NSUInteger)r.x, (NSUInteger)r.y, (NSUInteger)r.w, (NSUInteger)r.h)
|
||||||
|
mipmapLevel:0
|
||||||
|
withBytes:tex->GetPixelsAt(r.x, r.y)
|
||||||
|
bytesPerRow:(NSUInteger)tex->Width * 4];
|
||||||
|
}
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
{
|
||||||
|
ImGui_ImplMetal_DestroyTexture(tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
||||||
@@ -381,7 +419,9 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||||
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
||||||
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||||
ImGui_ImplMetal_CreateFontsTexture(device);
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
|
[depthStencilDescriptor release];
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -389,7 +429,12 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
void ImGui_ImplMetal_DestroyDeviceObjects()
|
void ImGui_ImplMetal_DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||||
ImGui_ImplMetal_DestroyFontsTexture();
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplMetal_DestroyTexture(tex);
|
||||||
|
|
||||||
ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
||||||
}
|
}
|
||||||
@@ -481,13 +526,12 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
|||||||
}
|
}
|
||||||
data->FirstFrame = false;
|
data->FirstFrame = false;
|
||||||
|
|
||||||
viewport->DpiScale = (float)window.backingScaleFactor;
|
float fb_scale = (float)window.backingScaleFactor;
|
||||||
if (data->MetalLayer.contentsScale != viewport->DpiScale)
|
if (data->MetalLayer.contentsScale != fb_scale)
|
||||||
{
|
{
|
||||||
data->MetalLayer.contentsScale = viewport->DpiScale;
|
data->MetalLayer.contentsScale = fb_scale;
|
||||||
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, viewport->DpiScale);
|
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, fb_scale);
|
||||||
}
|
}
|
||||||
viewport->DrawData->FramebufferScale = ImVec2(viewport->DpiScale, viewport->DpiScale);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];
|
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];
|
||||||
@@ -509,7 +553,7 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
|||||||
[commandBuffer commit];
|
[commandBuffer commit];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplMetal_InitPlatformInterface()
|
static void ImGui_ImplMetal_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
||||||
@@ -518,7 +562,7 @@ static void ImGui_ImplMetal_InitPlatformInterface()
|
|||||||
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplMetal_ShutdownPlatformInterface()
|
static void ImGui_ImplMetal_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
@@ -601,6 +645,18 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#pragma mark - MetalTexture implementation
|
||||||
|
|
||||||
|
@implementation MetalTexture
|
||||||
|
- (instancetype)initWithTexture:(id<MTLTexture>)metalTexture
|
||||||
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
self.metalTexture = metalTexture;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
#pragma mark - MetalContext implementation
|
#pragma mark - MetalContext implementation
|
||||||
|
|
||||||
@implementation MetalContext
|
@implementation MetalContext
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
// [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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
|
||||||
// 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,7 +26,10 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures. (#8802)
|
||||||
|
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL2_CreateFontsTexture() and ImGui_ImplOpenGL2_DestroyFontsTexture().
|
||||||
|
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||||
@@ -68,10 +74,18 @@
|
|||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// [Debugging]
|
||||||
|
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||||
|
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
||||||
|
#else
|
||||||
|
#define GL_CALL(_CALL) _CALL // Call without error check
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// OpenGL data
|
||||||
struct ImGui_ImplOpenGL2_Data
|
struct ImGui_ImplOpenGL2_Data
|
||||||
{
|
{
|
||||||
GLuint FontTexture;
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,8 +97,8 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplOpenGL2_InitPlatformInterface();
|
static void ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
bool ImGui_ImplOpenGL2_Init()
|
bool ImGui_ImplOpenGL2_Init()
|
||||||
@@ -97,10 +111,10 @@ bool ImGui_ImplOpenGL2_Init()
|
|||||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
io.BackendRendererName = "imgui_impl_opengl2";
|
io.BackendRendererName = "imgui_impl_opengl2";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
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_ImplOpenGL2_InitMultiViewportSupport();
|
||||||
ImGui_ImplOpenGL2_InitPlatformInterface();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -111,11 +125,11 @@ void ImGui_ImplOpenGL2_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
||||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasViewports;
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +137,7 @@ void ImGui_ImplOpenGL2_NewFrame()
|
|||||||
{
|
{
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
||||||
|
IM_UNUSED(bd);
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
||||||
@@ -164,7 +174,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
|||||||
|
|
||||||
// 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.
|
||||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -185,6 +195,13 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (fb_width == 0 || fb_height == 0)
|
if (fb_width == 0 || fb_height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplOpenGL2_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup GL state
|
// Backup GL state
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||||
@@ -202,18 +219,17 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
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)
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
|
||||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -221,7 +237,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -258,55 +274,79 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
glGenTextures(1, &bd->FontTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &bd->FontTexture);
|
// Create and upload new texture to graphics system
|
||||||
io.Fonts->SetTexID(0);
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
bd->FontTexture = 0;
|
IM_ASSERT(tex->TexID == 0 && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
const void* pixels = tex->GetPixels();
|
||||||
|
GLuint gl_texture_id = 0;
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
GLint last_texture;
|
||||||
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
|
GL_CALL(glGenTextures(1, &gl_texture_id));
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_texture_id));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||||
|
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)gl_texture_id);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture));
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
GLint last_texture;
|
||||||
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
|
|
||||||
|
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture)); // Restore state
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||||
|
glDeleteTextures(1, &gl_tex_id);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
return ImGui_ImplOpenGL2_CreateFontsTexture();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
{
|
||||||
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplOpenGL2_UpdateTexture(tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,13 +367,13 @@ static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
|||||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_InitPlatformInterface()
|
static void ImGui_ImplOpenGL2_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
|
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
// [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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -32,9 +35,10 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
// [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) with 16-bit indices (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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
// About WebGL/ES:
|
// About WebGL/ES:
|
||||||
@@ -23,7 +24,13 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-07-22: OpenGL: Add and call embedded loader shutdown during ImGui_ImplOpenGL3_Shutdown() to facilitate multiple init/shutdown cycles in same process. (#8792)
|
||||||
|
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures (#8802) + restore non-WebGL/ES update path that doesn't require a CPU-side copy.
|
||||||
|
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL3_CreateFontsTexture() and ImGui_ImplOpenGL3_DestroyFontsTexture().
|
||||||
|
// 2025-06-04: OpenGL: Made GLES 3.20 contexts not access GL_CONTEXT_PROFILE_MASK nor GL_PRIMITIVE_RESTART. (#8664)
|
||||||
|
// 2025-02-18: OpenGL: Lazily reinitialize embedded GL loader for when calling backend from e.g. other DLL boundaries. (#8406)
|
||||||
|
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
|
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
|
||||||
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
|
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
|
||||||
// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447)
|
// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447)
|
||||||
@@ -54,7 +61,7 @@
|
|||||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
|
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
|
||||||
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
|
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
|
||||||
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
|
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
|
||||||
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
|
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre-3.3 context which have the defines set by a loader.
|
||||||
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
|
||||||
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
// 2020-05-08: OpenGL: Made default GLSL version 150 (instead of 130) on OSX.
|
||||||
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
// 2020-04-21: OpenGL: Fixed handling of glClipControl(GL_UPPER_LEFT) by inverting projection matrix.
|
||||||
@@ -138,6 +145,7 @@
|
|||||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||||
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
|
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
|
||||||
#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)
|
||||||
|
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// GL includes
|
// GL includes
|
||||||
@@ -165,9 +173,11 @@
|
|||||||
// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
|
// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
|
||||||
// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
|
// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
|
||||||
// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
|
// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
|
||||||
|
// Typically you would run: python3 ./gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||||
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
||||||
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
||||||
#define IMGL3W_IMPL
|
#define IMGL3W_IMPL
|
||||||
|
#define IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||||
#include "imgui_impl_opengl3_loader.h"
|
#include "imgui_impl_opengl3_loader.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -227,7 +237,7 @@ struct ImGui_ImplOpenGL3_Data
|
|||||||
bool GlProfileIsES3;
|
bool GlProfileIsES3;
|
||||||
bool GlProfileIsCompat;
|
bool GlProfileIsCompat;
|
||||||
GLint GlProfileMask;
|
GLint GlProfileMask;
|
||||||
GLuint FontTexture;
|
GLint MaxTextureSize;
|
||||||
GLuint ShaderHandle;
|
GLuint ShaderHandle;
|
||||||
GLint AttribLocationTex; // Uniforms location
|
GLint AttribLocationTex; // Uniforms location
|
||||||
GLint AttribLocationProjMtx;
|
GLint AttribLocationProjMtx;
|
||||||
@@ -240,6 +250,7 @@ struct ImGui_ImplOpenGL3_Data
|
|||||||
bool HasPolygonMode;
|
bool HasPolygonMode;
|
||||||
bool HasClipOrigin;
|
bool HasClipOrigin;
|
||||||
bool UseBufferSubData;
|
bool UseBufferSubData;
|
||||||
|
ImVector<char> TempBuffer;
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplOpenGL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@@ -252,8 +263,8 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplOpenGL3_InitPlatformInterface();
|
static void ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// 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
|
||||||
@@ -279,6 +290,21 @@ struct ImGui_ImplOpenGL3_VtxAttribState
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
bool ImGui_ImplOpenGL3_InitLoader();
|
||||||
|
bool ImGui_ImplOpenGL3_InitLoader()
|
||||||
|
{
|
||||||
|
// Initialize our loader
|
||||||
|
#ifdef IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||||
|
if (glGetIntegerv == nullptr && imgl3wInit() != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||||
{
|
{
|
||||||
@@ -286,14 +312,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
// Initialize our loader
|
// Initialize loader
|
||||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
if (!ImGui_ImplOpenGL3_InitLoader())
|
||||||
if (imgl3wInit() != 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
|
ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
|
||||||
@@ -301,13 +322,14 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
io.BackendRendererName = "imgui_impl_opengl3";
|
io.BackendRendererName = "imgui_impl_opengl3";
|
||||||
|
|
||||||
// Query for GL version (e.g. 320 for GL 3.2)
|
// Query for GL version (e.g. 320 for GL 3.2)
|
||||||
|
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
// GLES 2
|
// GLES 2
|
||||||
bd->GlVersion = 200;
|
bd->GlVersion = 200;
|
||||||
bd->GlProfileIsES2 = true;
|
bd->GlProfileIsES2 = true;
|
||||||
|
IM_UNUSED(gl_version_str);
|
||||||
#else
|
#else
|
||||||
// Desktop or GLES 3
|
// Desktop or GLES 3
|
||||||
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
|
|
||||||
GLint major = 0;
|
GLint major = 0;
|
||||||
GLint minor = 0;
|
GLint minor = 0;
|
||||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||||
@@ -315,11 +337,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
if (major == 0 && minor == 0)
|
if (major == 0 && minor == 0)
|
||||||
sscanf(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
sscanf(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
||||||
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
||||||
#if defined(GL_CONTEXT_PROFILE_MASK)
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &bd->MaxTextureSize);
|
||||||
if (bd->GlVersion >= 320)
|
|
||||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
|
|
||||||
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES3)
|
#if defined(IMGUI_IMPL_OPENGL_ES3)
|
||||||
bd->GlProfileIsES3 = true;
|
bd->GlProfileIsES3 = true;
|
||||||
@@ -328,6 +346,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
bd->GlProfileIsES3 = true;
|
bd->GlProfileIsES3 = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(GL_CONTEXT_PROFILE_MASK)
|
||||||
|
if (!bd->GlProfileIsES3 && bd->GlVersion >= 320)
|
||||||
|
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
|
||||||
|
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
bd->UseBufferSubData = false;
|
bd->UseBufferSubData = false;
|
||||||
/*
|
/*
|
||||||
// Query vendor to enable glBufferSubData kludge
|
// Query vendor to enable glBufferSubData kludge
|
||||||
@@ -340,14 +364,18 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||||
printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2/IsEs3 = %d/%d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||||
if (bd->GlVersion >= 320)
|
if (bd->GlVersion >= 320)
|
||||||
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
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();
|
||||||
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = (int)bd->MaxTextureSize;
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -388,8 +416,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
||||||
ImGui_ImplOpenGL3_InitPlatformInterface();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -400,12 +427,16 @@ void ImGui_ImplOpenGL3_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
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_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
|
|
||||||
|
#ifdef IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||||
|
imgl3wShutdown();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplOpenGL3_NewFrame()
|
void ImGui_ImplOpenGL3_NewFrame()
|
||||||
@@ -413,10 +444,11 @@ void ImGui_ImplOpenGL3_NewFrame()
|
|||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL3_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL3_Init()?");
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_InitLoader(); // Lazily init loader if not already done for e.g. DLL boundaries.
|
||||||
|
|
||||||
if (!bd->ShaderHandle)
|
if (!bd->ShaderHandle)
|
||||||
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
if (!ImGui_ImplOpenGL3_CreateDeviceObjects())
|
||||||
if (!bd->FontTexture)
|
IM_ASSERT(0 && "ImGui_ImplOpenGL3_CreateDeviceObjects() failed!");
|
||||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||||
@@ -432,7 +464,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
|||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||||
if (bd->GlVersion >= 310)
|
if (!bd->GlProfileIsES3 && bd->GlVersion >= 310)
|
||||||
glDisable(GL_PRIMITIVE_RESTART);
|
glDisable(GL_PRIMITIVE_RESTART);
|
||||||
#endif
|
#endif
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||||
@@ -504,8 +536,17 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (fb_width <= 0 || fb_height <= 0)
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_InitLoader(); // Lazily init loader if not already done for e.g. DLL boundaries.
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplOpenGL3_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup GL state
|
// Backup GL state
|
||||||
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -542,7 +583,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
|
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
|
||||||
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||||
GLboolean last_enable_primitive_restart = (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
|
||||||
|
|
||||||
// Setup desired GL state
|
// Setup desired GL state
|
||||||
@@ -559,10 +600,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
||||||
|
|
||||||
// Upload vertex/index buffers
|
// Upload vertex/index buffers
|
||||||
// - OpenGL drivers are in a very sorry state nowadays....
|
// - OpenGL drivers are in a very sorry state nowadays....
|
||||||
// During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
|
// During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
|
||||||
@@ -571,8 +610,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
|
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
|
||||||
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
|
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
|
||||||
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
|
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
|
||||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)draw_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
const GLsizeiptr idx_buffer_size = (GLsizeiptr)draw_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||||
if (bd->UseBufferSubData)
|
if (bd->UseBufferSubData)
|
||||||
{
|
{
|
||||||
if (bd->VertexBufferSize < vtx_buffer_size)
|
if (bd->VertexBufferSize < vtx_buffer_size)
|
||||||
@@ -585,18 +624,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
bd->IndexBufferSize = idx_buffer_size;
|
bd->IndexBufferSize = idx_buffer_size;
|
||||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
|
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
|
||||||
}
|
}
|
||||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data));
|
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data));
|
||||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data));
|
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != nullptr)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -604,7 +643,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -661,7 +700,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
|
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
|
||||||
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||||
if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
if (!bd->GlProfileIsES3 && bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||||
@@ -674,48 +713,90 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
(void)bd; // Not all compilation paths use this
|
(void)bd; // Not all compilation paths use this
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
static void ImGui_ImplOpenGL3_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
glDeleteTextures(1, &gl_tex_id);
|
||||||
|
|
||||||
// Build texture atlas
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
unsigned char* pixels;
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
int width, height;
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
|
||||||
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
|
||||||
GL_CALL(glGenTextures(1, &bd->FontTexture));
|
|
||||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
|
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
|
||||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
|
||||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
|
||||||
#endif
|
|
||||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplOpenGL3_DestroyFontsTexture()
|
void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
// FIXME: Consider backing up and restoring
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &bd->FontTexture);
|
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||||
io.Fonts->SetTexID(0);
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||||
bd->FontTexture = 0;
|
#endif
|
||||||
|
#ifdef GL_UNPACK_ALIGNMENT
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == 0 && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
const void* pixels = tex->GetPixels();
|
||||||
|
GLuint gl_texture_id = 0;
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
GLint last_texture;
|
||||||
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
|
GL_CALL(glGenTextures(1, &gl_texture_id));
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_texture_id));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||||
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||||
|
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)gl_texture_id);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture));
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
GLint last_texture;
|
||||||
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
|
|
||||||
|
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||||
|
#if GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||||
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||||
|
#else
|
||||||
|
// GL ES doesn't have GL_UNPACK_ROW_LENGTH, so we need to (A) copy to a contiguous buffer or (B) upload line by line.
|
||||||
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
const int src_pitch = r.w * tex->BytesPerPixel;
|
||||||
|
bd->TempBuffer.resize(r.h * src_pitch);
|
||||||
|
char* out_p = bd->TempBuffer.Data;
|
||||||
|
for (int y = 0; y < r.h; y++, out_p += src_pitch)
|
||||||
|
memcpy(out_p, tex->GetPixelsAt(r.x, r.y + y), src_pitch);
|
||||||
|
IM_ASSERT(out_p == bd->TempBuffer.end());
|
||||||
|
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, bd->TempBuffer.Data));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, last_texture)); // Restore state
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
ImGui_ImplOpenGL3_DestroyTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file.
|
// If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file.
|
||||||
@@ -903,23 +984,28 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
|||||||
|
|
||||||
// Create shaders
|
// Create shaders
|
||||||
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
|
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
|
||||||
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
GLuint vert_handle;
|
||||||
|
GL_CALL(vert_handle = glCreateShader(GL_VERTEX_SHADER));
|
||||||
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
|
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
|
||||||
glCompileShader(vert_handle);
|
glCompileShader(vert_handle);
|
||||||
CheckShader(vert_handle, "vertex shader");
|
if (!CheckShader(vert_handle, "vertex shader"))
|
||||||
|
return false;
|
||||||
|
|
||||||
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
|
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
|
||||||
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
GLuint frag_handle;
|
||||||
|
GL_CALL(frag_handle = glCreateShader(GL_FRAGMENT_SHADER));
|
||||||
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
|
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
|
||||||
glCompileShader(frag_handle);
|
glCompileShader(frag_handle);
|
||||||
CheckShader(frag_handle, "fragment shader");
|
if (!CheckShader(frag_handle, "fragment shader"))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Link
|
// Link
|
||||||
bd->ShaderHandle = glCreateProgram();
|
bd->ShaderHandle = glCreateProgram();
|
||||||
glAttachShader(bd->ShaderHandle, vert_handle);
|
glAttachShader(bd->ShaderHandle, vert_handle);
|
||||||
glAttachShader(bd->ShaderHandle, frag_handle);
|
glAttachShader(bd->ShaderHandle, frag_handle);
|
||||||
glLinkProgram(bd->ShaderHandle);
|
glLinkProgram(bd->ShaderHandle);
|
||||||
CheckProgram(bd->ShaderHandle, "shader program");
|
if (!CheckProgram(bd->ShaderHandle, "shader program"))
|
||||||
|
return false;
|
||||||
|
|
||||||
glDetachShader(bd->ShaderHandle, vert_handle);
|
glDetachShader(bd->ShaderHandle, vert_handle);
|
||||||
glDetachShader(bd->ShaderHandle, frag_handle);
|
glDetachShader(bd->ShaderHandle, frag_handle);
|
||||||
@@ -936,8 +1022,6 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
|||||||
glGenBuffers(1, &bd->VboHandle);
|
glGenBuffers(1, &bd->VboHandle);
|
||||||
glGenBuffers(1, &bd->ElementsHandle);
|
glGenBuffers(1, &bd->ElementsHandle);
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
|
||||||
|
|
||||||
// Restore modified GL state
|
// Restore modified GL state
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||||
@@ -957,7 +1041,11 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
|||||||
if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
|
if (bd->VboHandle) { glDeleteBuffers(1, &bd->VboHandle); bd->VboHandle = 0; }
|
||||||
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
|
if (bd->ElementsHandle) { glDeleteBuffers(1, &bd->ElementsHandle); bd->ElementsHandle = 0; }
|
||||||
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
||||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplOpenGL3_DestroyTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
@@ -977,13 +1065,13 @@ static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
|
|||||||
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_InitPlatformInterface()
|
static void ImGui_ImplOpenGL3_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
// [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) with 16-bit indices (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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
// About WebGL/ES:
|
// About WebGL/ES:
|
||||||
@@ -37,11 +38,12 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
// (Optional) Called by Init/NewFrame/Shutdown
|
// (Optional) Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
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 = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
// 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)
|
||||||
|
|||||||
@@ -166,7 +166,9 @@ typedef khronos_uint8_t GLubyte;
|
|||||||
#define GL_SCISSOR_BOX 0x0C10
|
#define GL_SCISSOR_BOX 0x0C10
|
||||||
#define GL_SCISSOR_TEST 0x0C11
|
#define GL_SCISSOR_TEST 0x0C11
|
||||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||||
|
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||||
#define GL_PACK_ALIGNMENT 0x0D05
|
#define GL_PACK_ALIGNMENT 0x0D05
|
||||||
|
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||||
#define GL_TEXTURE_2D 0x0DE1
|
#define GL_TEXTURE_2D 0x0DE1
|
||||||
#define GL_UNSIGNED_BYTE 0x1401
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
#define GL_UNSIGNED_SHORT 0x1403
|
#define GL_UNSIGNED_SHORT 0x1403
|
||||||
@@ -181,6 +183,9 @@ typedef khronos_uint8_t GLubyte;
|
|||||||
#define GL_LINEAR 0x2601
|
#define GL_LINEAR 0x2601
|
||||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||||
|
#define GL_TEXTURE_WRAP_S 0x2802
|
||||||
|
#define GL_TEXTURE_WRAP_T 0x2803
|
||||||
|
#define GL_REPEAT 0x2901
|
||||||
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||||
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||||
@@ -221,16 +226,21 @@ typedef khronos_float_t GLclampf;
|
|||||||
typedef double GLclampd;
|
typedef double GLclampd;
|
||||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||||
|
typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||||
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||||
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
||||||
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
||||||
#ifdef GL_GLEXT_PROTOTYPES
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||||
|
GLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||||
GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);
|
GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);
|
||||||
GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
||||||
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||||
#endif
|
#endif
|
||||||
#endif /* GL_VERSION_1_1 */
|
#endif /* GL_VERSION_1_1 */
|
||||||
|
#ifndef GL_VERSION_1_2
|
||||||
|
#define GL_CLAMP_TO_EDGE 0x812F
|
||||||
|
#endif /* GL_VERSION_1_2 */
|
||||||
#ifndef GL_VERSION_1_3
|
#ifndef GL_VERSION_1_3
|
||||||
#define GL_TEXTURE0 0x84C0
|
#define GL_TEXTURE0 0x84C0
|
||||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||||
@@ -467,12 +477,13 @@ typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
|
|||||||
/* gl3w api */
|
/* gl3w api */
|
||||||
GL3W_API int imgl3wInit(void);
|
GL3W_API int imgl3wInit(void);
|
||||||
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
||||||
|
GL3W_API void imgl3wShutdown(void);
|
||||||
GL3W_API int imgl3wIsSupported(int major, int minor);
|
GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||||
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||||
|
|
||||||
/* gl3w internal state */
|
/* gl3w internal state */
|
||||||
union ImGL3WProcs {
|
union ImGL3WProcs {
|
||||||
GL3WglProc ptr[59];
|
GL3WglProc ptr[60];
|
||||||
struct {
|
struct {
|
||||||
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||||
PFNGLATTACHSHADERPROC AttachShader;
|
PFNGLATTACHSHADERPROC AttachShader;
|
||||||
@@ -528,6 +539,7 @@ union ImGL3WProcs {
|
|||||||
PFNGLSHADERSOURCEPROC ShaderSource;
|
PFNGLSHADERSOURCEPROC ShaderSource;
|
||||||
PFNGLTEXIMAGE2DPROC TexImage2D;
|
PFNGLTEXIMAGE2DPROC TexImage2D;
|
||||||
PFNGLTEXPARAMETERIPROC TexParameteri;
|
PFNGLTEXPARAMETERIPROC TexParameteri;
|
||||||
|
PFNGLTEXSUBIMAGE2DPROC TexSubImage2D;
|
||||||
PFNGLUNIFORM1IPROC Uniform1i;
|
PFNGLUNIFORM1IPROC Uniform1i;
|
||||||
PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
|
PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
|
||||||
PFNGLUSEPROGRAMPROC UseProgram;
|
PFNGLUSEPROGRAMPROC UseProgram;
|
||||||
@@ -593,6 +605,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
|||||||
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
||||||
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
||||||
#define glTexParameteri imgl3wProcs.gl.TexParameteri
|
#define glTexParameteri imgl3wProcs.gl.TexParameteri
|
||||||
|
#define glTexSubImage2D imgl3wProcs.gl.TexSubImage2D
|
||||||
#define glUniform1i imgl3wProcs.gl.Uniform1i
|
#define glUniform1i imgl3wProcs.gl.Uniform1i
|
||||||
#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
|
#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
|
||||||
#define glUseProgram imgl3wProcs.gl.UseProgram
|
#define glUseProgram imgl3wProcs.gl.UseProgram
|
||||||
@@ -620,7 +633,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
static HMODULE libgl;
|
static HMODULE libgl = NULL;
|
||||||
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
||||||
static GL3WglGetProcAddr wgl_get_proc_address;
|
static GL3WglGetProcAddr wgl_get_proc_address;
|
||||||
|
|
||||||
@@ -633,7 +646,7 @@ static int open_libgl(void)
|
|||||||
return GL3W_OK;
|
return GL3W_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_libgl(void) { FreeLibrary(libgl); }
|
static void close_libgl(void) { FreeLibrary(libgl); libgl = NULL; }
|
||||||
static GL3WglProc get_proc(const char *proc)
|
static GL3WglProc get_proc(const char *proc)
|
||||||
{
|
{
|
||||||
GL3WglProc res;
|
GL3WglProc res;
|
||||||
@@ -645,7 +658,7 @@ static GL3WglProc get_proc(const char *proc)
|
|||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
static void *libgl;
|
static void *libgl = NULL;
|
||||||
static int open_libgl(void)
|
static int open_libgl(void)
|
||||||
{
|
{
|
||||||
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
||||||
@@ -654,7 +667,7 @@ static int open_libgl(void)
|
|||||||
return GL3W_OK;
|
return GL3W_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void close_libgl(void) { dlclose(libgl); }
|
static void close_libgl(void) { dlclose(libgl); libgl = NULL; }
|
||||||
|
|
||||||
static GL3WglProc get_proc(const char *proc)
|
static GL3WglProc get_proc(const char *proc)
|
||||||
{
|
{
|
||||||
@@ -822,6 +835,11 @@ int imgl3wInit2(GL3WGetProcAddressProc proc)
|
|||||||
return parse_version();
|
return parse_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imgl3wShutdown(void)
|
||||||
|
{
|
||||||
|
close_libgl();
|
||||||
|
}
|
||||||
|
|
||||||
int imgl3wIsSupported(int major, int minor)
|
int imgl3wIsSupported(int major, int minor)
|
||||||
{
|
{
|
||||||
if (major < 2)
|
if (major < 2)
|
||||||
@@ -888,6 +906,7 @@ static const char *proc_names[] = {
|
|||||||
"glShaderSource",
|
"glShaderSource",
|
||||||
"glTexImage2D",
|
"glTexImage2D",
|
||||||
"glTexParameteri",
|
"glTexParameteri",
|
||||||
|
"glTexSubImage2D",
|
||||||
"glUniform1i",
|
"glUniform1i",
|
||||||
"glUniformMatrix4fv",
|
"glUniformMatrix4fv",
|
||||||
"glUseProgram",
|
"glUseProgram",
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
// - Requires linking with the GameController framework ("-framework GameController").
|
// - Requires linking with the GameController framework ("-framework GameController").
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||||
// [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 kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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 kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [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.
|
// [x] Platform: Multi-viewport / platform windows.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
// [ ] Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
|
|
||||||
// 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,6 +23,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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,16 @@
|
|||||||
// - Requires linking with the GameController framework ("-framework GameController").
|
// - Requires linking with the GameController framework ("-framework GameController").
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||||
// [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 kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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 kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [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.
|
// [x] Platform: Multi-viewport / platform windows.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
// [ ] Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
|
|
||||||
// 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,7 +33,13 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-07-08: [Docking] Fixed multi-viewport handling broken on 2025-06-02. (#8644, #8777)
|
||||||
|
// 2025-06-27: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
|
// 2025-06-12: ImGui_ImplOSX_HandleEvent() only process event for window containing our view. (#8644)
|
||||||
|
// 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-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:
|
||||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||||
@@ -41,7 +47,7 @@
|
|||||||
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
||||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
||||||
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
||||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mice).
|
||||||
// 2022-11-02: Fixed mouse coordinates before clicking the host window.
|
// 2022-11-02: Fixed mouse coordinates before clicking the host window.
|
||||||
// 2022-10-06: Fixed mouse inputs on flipped views.
|
// 2022-10-06: Fixed mouse inputs on flipped views.
|
||||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||||
@@ -92,7 +98,7 @@ struct ImGui_ImplOSX_Data
|
|||||||
id Monitor;
|
id Monitor;
|
||||||
NSWindow* Window;
|
NSWindow* Window;
|
||||||
|
|
||||||
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
ImGui_ImplOSX_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
|
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
|
||||||
@@ -101,8 +107,8 @@ 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_InitPlatformInterface();
|
static void ImGui_ImplOSX_InitMultiViewportSupport();
|
||||||
static void ImGui_ImplOSX_ShutdownPlatformInterface();
|
static void ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
||||||
static void ImGui_ImplOSX_UpdateMonitors();
|
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);
|
||||||
@@ -113,6 +119,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||||||
+ (id)_windowResizeNorthEastSouthWestCursor;
|
+ (id)_windowResizeNorthEastSouthWestCursor;
|
||||||
+ (id)_windowResizeNorthSouthCursor;
|
+ (id)_windowResizeNorthSouthCursor;
|
||||||
+ (id)_windowResizeEastWestCursor;
|
+ (id)_windowResizeEastWestCursor;
|
||||||
|
+ (id)busyButClickableCursor;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,6 +298,7 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code);
|
||||||
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||||
{
|
{
|
||||||
switch (key_code)
|
switch (key_code)
|
||||||
@@ -447,20 +455,20 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
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_UpdateMonitors();
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
ImGui_ImplOSX_InitMultiViewportSupport();
|
||||||
ImGui_ImplOSX_InitPlatformInterface();
|
|
||||||
|
|
||||||
// Load cursors. Some of them are undocumented.
|
// Load cursors. Some of them are undocumented.
|
||||||
bd->MouseCursorHidden = false;
|
bd->MouseCursorHidden = false;
|
||||||
bd->MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
bd->MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
|
bd->MouseCursors[ImGuiMouseCursor_TextInput] = [NSCursor IBeamCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeAll] = [NSCursor closedHandCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
|
||||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNS] = [NSCursor respondsToSelector:@selector(_windowResizeNorthSouthCursor)] ? [NSCursor _windowResizeNorthSouthCursor] : [NSCursor resizeUpDownCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeEW] = [NSCursor respondsToSelector:@selector(_windowResizeEastWestCursor)] ? [NSCursor _windowResizeEastWestCursor] : [NSCursor resizeLeftRightCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = [NSCursor respondsToSelector:@selector(_windowResizeNorthEastSouthWestCursor)] ? [NSCursor _windowResizeNorthEastSouthWestCursor] : [NSCursor closedHandCursor];
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = [NSCursor respondsToSelector:@selector(_windowResizeNorthWestSouthEastCursor)] ? [NSCursor _windowResizeNorthWestSouthEastCursor] : [NSCursor closedHandCursor];
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Hand] = [NSCursor pointingHandCursor];
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Wait] = bd->MouseCursors[ImGuiMouseCursor_Progress] = [NSCursor respondsToSelector:@selector(busyButClickableCursor)] ? [NSCursor busyButClickableCursor] : [NSCursor arrowCursor];
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = [NSCursor operationNotAllowedCursor];
|
||||||
|
|
||||||
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
||||||
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
||||||
@@ -507,7 +515,7 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
[view addSubview:bd->KeyEventResponder];
|
[view addSubview:bd->KeyEventResponder];
|
||||||
ImGui_ImplOSX_AddTrackingArea(view);
|
ImGui_ImplOSX_AddTrackingArea(view);
|
||||||
|
|
||||||
platform_io.Platform_SetImeDataFn = [](ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
platform_io.Platform_SetImeDataFn = [](ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data) -> void
|
||||||
{
|
{
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
if (data->WantVisible)
|
if (data->WantVisible)
|
||||||
@@ -531,6 +539,7 @@ void ImGui_ImplOSX_Shutdown()
|
|||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
|
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:bd->Observer];
|
||||||
bd->Observer = nullptr;
|
bd->Observer = nullptr;
|
||||||
if (bd->Monitor != nullptr)
|
if (bd->Monitor != nullptr)
|
||||||
{
|
{
|
||||||
@@ -538,7 +547,7 @@ void ImGui_ImplOSX_Shutdown()
|
|||||||
bd->Monitor = nullptr;
|
bd->Monitor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui_ImplOSX_ShutdownPlatformInterface();
|
ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
||||||
ImGui_ImplOSX_DestroyBackendData();
|
ImGui_ImplOSX_DestroyBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
@@ -566,7 +575,7 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSCursor* desired = bd->MouseCursors[imgui_cursor] ?: bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
NSCursor* desired = bd->MouseCursors[imgui_cursor] ?: bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||||
// -[NSCursor set] generates measureable overhead if called unconditionally.
|
// -[NSCursor set] generates measurable overhead if called unconditionally.
|
||||||
if (desired != NSCursor.currentCursor)
|
if (desired != NSCursor.currentCursor)
|
||||||
{
|
{
|
||||||
[desired set];
|
[desired set];
|
||||||
@@ -582,8 +591,6 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
|
|||||||
static void ImGui_ImplOSX_UpdateGamepads()
|
static void ImGui_ImplOSX_UpdateGamepads()
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if APPLE_HAS_CONTROLLER
|
#if APPLE_HAS_CONTROLLER
|
||||||
GCController* controller = GCController.current;
|
GCController* controller = GCController.current;
|
||||||
@@ -654,9 +661,9 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
|
|||||||
// Setup display size
|
// Setup display size
|
||||||
if (view)
|
if (view)
|
||||||
{
|
{
|
||||||
const float dpi = (float)[view.window backingScaleFactor];
|
const float fb_scale = (float)[view.window backingScaleFactor];
|
||||||
io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height);
|
io.DisplaySize = ImVec2((float)view.bounds.size.width, (float)view.bounds.size.height);
|
||||||
io.DisplayFramebufferScale = ImVec2(dpi, dpi);
|
io.DisplayFramebufferScale = ImVec2(fb_scale, fb_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup time step
|
// Setup time step
|
||||||
@@ -694,8 +701,11 @@ static ImGuiMouseSource GetMouseSource(NSEvent* event)
|
|||||||
|
|
||||||
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
// Only process events from the window containing ImGui view
|
||||||
|
if (!ImGui::FindViewportByPlatformHandle((__bridge void*)event.window))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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];
|
||||||
@@ -828,8 +838,6 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
|||||||
default:
|
default:
|
||||||
return io.WantCaptureKeyboard;
|
return io.WantCaptureKeyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSEventModifierFlags modifier_flags = [event modifierFlags];
|
|
||||||
io.AddKeyEvent(key, (modifier_flags & mask) != 0);
|
io.AddKeyEvent(key, (modifier_flags & mask) != 0);
|
||||||
io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
|
io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
|
||||||
}
|
}
|
||||||
@@ -870,13 +878,13 @@ static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
|
|||||||
// 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..
|
// 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 ImGuiViewportDataOSX
|
struct ImGui_ImplOSX_ViewportData
|
||||||
{
|
{
|
||||||
NSWindow* Window;
|
NSWindow* Window;
|
||||||
bool WindowOwned;
|
bool WindowOwned;
|
||||||
|
|
||||||
ImGuiViewportDataOSX() { WindowOwned = false; }
|
ImGui_ImplOSX_ViewportData() { WindowOwned = false; }
|
||||||
~ImGuiViewportDataOSX() { IM_ASSERT(Window == nil); }
|
~ImGui_ImplOSX_ViewportData() { IM_ASSERT(Window == nil); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface ImGui_ImplOSX_Window: NSWindow
|
@interface ImGui_ImplOSX_Window: NSWindow
|
||||||
@@ -901,8 +909,8 @@ static void ConvertNSRect(NSRect* r)
|
|||||||
static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)();
|
ImGui_ImplOSX_ViewportData* vd = IM_NEW(ImGui_ImplOSX_ViewportData)();
|
||||||
viewport->PlatformUserData = data;
|
viewport->PlatformUserData = vd;
|
||||||
|
|
||||||
NSScreen* screen = bd->Window.screen;
|
NSScreen* screen = bd->Window.screen;
|
||||||
NSRect rect = NSMakeRect(viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y);
|
NSRect rect = NSMakeRect(viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y);
|
||||||
@@ -931,51 +939,48 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
|||||||
|
|
||||||
window.contentView = view;
|
window.contentView = view;
|
||||||
|
|
||||||
data->Window = window;
|
vd->Window = window;
|
||||||
data->WindowOwned = true;
|
vd->WindowOwned = true;
|
||||||
viewport->PlatformRequestResize = false;
|
viewport->PlatformRequestResize = false;
|
||||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window;
|
viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
NSWindow* window = (__bridge_transfer NSWindow*)viewport->PlatformHandleRaw;
|
if (ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData)
|
||||||
window = nil;
|
|
||||||
|
|
||||||
if (ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData)
|
|
||||||
{
|
{
|
||||||
NSWindow* window = data->Window;
|
NSWindow* window = vd->Window;
|
||||||
if (window != nil && data->WindowOwned)
|
if (window != nil && vd->WindowOwned)
|
||||||
{
|
{
|
||||||
window.contentView = nil;
|
window.contentView = nil;
|
||||||
window.contentViewController = nil;
|
window.contentViewController = nil;
|
||||||
[window orderOut:nil];
|
[window orderOut:nil];
|
||||||
}
|
}
|
||||||
data->Window = nil;
|
vd->Window = nil;
|
||||||
IM_DELETE(data);
|
IM_DELETE(vd);
|
||||||
}
|
}
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = nullptr;
|
viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||||
[data->Window orderFront:nil];
|
[vd->Window orderFront:nil];
|
||||||
else
|
else
|
||||||
[data->Window makeKeyAndOrderFront:nil];
|
[vd->Window makeKeyAndOrderFront:nil];
|
||||||
|
|
||||||
[data->Window setIsVisible:YES];
|
[vd->Window setIsVisible:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
NSWindow* window = data->Window;
|
NSWindow* window = vd->Window;
|
||||||
NSRect frame = window.frame;
|
NSRect frame = window.frame;
|
||||||
NSRect contentRect = window.contentLayoutRect;
|
NSRect contentRect = window.contentLayoutRect;
|
||||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
||||||
@@ -987,10 +992,10 @@ static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
|||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
NSWindow* window = data->Window;
|
NSWindow* window = vd->Window;
|
||||||
NSSize size = window.frame.size;
|
NSSize size = window.frame.size;
|
||||||
|
|
||||||
NSRect r = NSMakeRect(pos.x, pos.y, size.width, size.height);
|
NSRect r = NSMakeRect(pos.x, pos.y, size.width, size.height);
|
||||||
@@ -1000,20 +1005,20 @@ static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|||||||
|
|
||||||
static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport)
|
static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
NSWindow* window = data->Window;
|
NSWindow* window = vd->Window;
|
||||||
NSSize size = window.contentLayoutRect.size;
|
NSSize size = window.contentLayoutRect.size;
|
||||||
return ImVec2(size.width, size.height);
|
return ImVec2(size.width, size.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
NSWindow* window = data->Window;
|
NSWindow* window = vd->Window;
|
||||||
NSRect rect = window.frame;
|
NSRect rect = window.frame;
|
||||||
rect.origin.y -= (size.y - rect.size.height);
|
rect.origin.y -= (size.y - rect.size.height);
|
||||||
rect.size.width = size.x;
|
rect.size.width = size.x;
|
||||||
@@ -1021,53 +1026,61 @@ static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|||||||
[window setFrame:rect display:YES];
|
[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)
|
static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
[data->Window makeKeyAndOrderFront:bd->Window];
|
[vd->Window makeKeyAndOrderFront:bd->Window];
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport)
|
static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
return data->Window.isKeyWindow;
|
return vd->Window.isKeyWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport)
|
static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
return data->Window.isMiniaturized;
|
return vd->Window.isMiniaturized;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
data->Window.title = [NSString stringWithUTF8String:title];
|
vd->Window.title = [NSString stringWithUTF8String:title];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||||
|
|
||||||
data->Window.alphaValue = alpha;
|
vd->Window.alphaValue = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport)
|
static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
||||||
IM_ASSERT(data->Window != 0);
|
IM_ASSERT(vd->Window != 0);
|
||||||
|
|
||||||
return data->Window.backingScaleFactor;
|
return vd->Window.backingScaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_UpdateMonitors()
|
static void ImGui_ImplOSX_UpdateMonitors()
|
||||||
@@ -1097,7 +1110,7 @@ static void ImGui_ImplOSX_UpdateMonitors()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_InitPlatformInterface()
|
static void ImGui_ImplOSX_InitMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
|
|
||||||
@@ -1110,6 +1123,7 @@ static void ImGui_ImplOSX_InitPlatformInterface()
|
|||||||
platform_io.Platform_GetWindowPos = ImGui_ImplOSX_GetWindowPos;
|
platform_io.Platform_GetWindowPos = ImGui_ImplOSX_GetWindowPos;
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplOSX_SetWindowSize;
|
platform_io.Platform_SetWindowSize = ImGui_ImplOSX_SetWindowSize;
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplOSX_GetWindowSize;
|
platform_io.Platform_GetWindowSize = ImGui_ImplOSX_GetWindowSize;
|
||||||
|
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplOSX_GetWindowFramebufferScale;
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplOSX_SetWindowFocus;
|
platform_io.Platform_SetWindowFocus = ImGui_ImplOSX_SetWindowFocus;
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplOSX_GetWindowFocus;
|
platform_io.Platform_GetWindowFocus = ImGui_ImplOSX_GetWindowFocus;
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplOSX_GetWindowMinimized;
|
platform_io.Platform_GetWindowMinimized = ImGui_ImplOSX_GetWindowMinimized;
|
||||||
@@ -1119,10 +1133,10 @@ static void ImGui_ImplOSX_InitPlatformInterface()
|
|||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
// Register main window handle (which is owned by the main application, not by us)
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
ImGuiViewportDataOSX* data = IM_NEW(ImGuiViewportDataOSX)();
|
ImGui_ImplOSX_ViewportData* vd = IM_NEW(ImGui_ImplOSX_ViewportData)();
|
||||||
data->Window = bd->Window;
|
vd->Window = bd->Window;
|
||||||
data->WindowOwned = false;
|
vd->WindowOwned = false;
|
||||||
main_viewport->PlatformUserData = data;
|
main_viewport->PlatformUserData = vd;
|
||||||
main_viewport->PlatformHandle = (__bridge void*)bd->Window;
|
main_viewport->PlatformHandle = (__bridge void*)bd->Window;
|
||||||
|
|
||||||
[NSNotificationCenter.defaultCenter addObserver:bd->Observer
|
[NSNotificationCenter.defaultCenter addObserver:bd->Observer
|
||||||
@@ -1131,7 +1145,7 @@ static void ImGui_ImplOSX_InitPlatformInterface()
|
|||||||
object:nil];
|
object:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplOSX_ShutdownPlatformInterface()
|
static void ImGui_ImplOSX_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||||
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer
|
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer
|
||||||
@@ -1146,8 +1160,8 @@ static void ImGui_ImplOSX_ShutdownPlatformInterface()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
ImGuiViewportDataOSX* data = (ImGuiViewportDataOSX*)main_viewport->PlatformUserData;
|
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)main_viewport->PlatformUserData;
|
||||||
IM_DELETE(data);
|
IM_DELETE(vd);
|
||||||
main_viewport->PlatformUserData = nullptr;
|
main_viewport->PlatformUserData = nullptr;
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
// [x] Platform: Basic IME support. 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.
|
||||||
@@ -25,7 +25,22 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-07-08: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
|
||||||
|
// 2025-06-11: Added ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) and ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) helper to facilitate making DPI-aware apps.
|
||||||
|
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
||||||
|
// 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-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-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-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-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.
|
||||||
|
// 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f.
|
||||||
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
|
// 2024-09-09: use SDL_Vulkan_GetDrawableSize() when available. (#7967, #3190)
|
||||||
// 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
|
||||||
@@ -99,6 +114,7 @@
|
|||||||
// Clang warnings with -Weverything
|
// Clang warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -106,12 +122,14 @@
|
|||||||
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
|
// (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()
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten/em_js.h>
|
#include <emscripten/em_js.h>
|
||||||
#endif
|
#endif
|
||||||
|
#undef Status // X11 headers are leaking this.
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
|
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS) && !defined(__amigaos4__)
|
||||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
|
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 1
|
||||||
@@ -124,10 +142,11 @@
|
|||||||
#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)
|
#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9)
|
||||||
|
#define SDL_HAS_OPEN_URL SDL_VERSION_ATLEAST(2,0,14)
|
||||||
#define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
|
#define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
|
||||||
#if SDL_HAS_VULKAN
|
#if SDL_HAS_VULKAN
|
||||||
extern "C" { extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window* window, int* w, int* h); }
|
#include <SDL_vulkan.h>
|
||||||
#elif
|
#else
|
||||||
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -135,10 +154,11 @@ static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
|||||||
struct ImGui_ImplSDL2_Data
|
struct ImGui_ImplSDL2_Data
|
||||||
{
|
{
|
||||||
SDL_Window* Window;
|
SDL_Window* Window;
|
||||||
Uint32 WindowID;
|
Uint32 WindowID; // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
|
||||||
SDL_Renderer* Renderer;
|
SDL_Renderer* Renderer;
|
||||||
Uint64 Time;
|
Uint64 Time;
|
||||||
char* ClipboardTextData;
|
char* ClipboardTextData;
|
||||||
|
char BackendPlatformName[48];
|
||||||
bool UseVulkan;
|
bool UseVulkan;
|
||||||
bool WantUpdateMonitors;
|
bool WantUpdateMonitors;
|
||||||
|
|
||||||
@@ -149,6 +169,7 @@ struct ImGui_ImplSDL2_Data
|
|||||||
SDL_Cursor* MouseLastCursor;
|
SDL_Cursor* MouseLastCursor;
|
||||||
int MouseLastLeaveFrame;
|
int MouseLastLeaveFrame;
|
||||||
bool MouseCanUseGlobalState;
|
bool MouseCanUseGlobalState;
|
||||||
|
bool MouseCanUseCapture;
|
||||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
@@ -170,8 +191,8 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplSDL2_UpdateMonitors();
|
static void ImGui_ImplSDL2_UpdateMonitors();
|
||||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
|
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
|
||||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface();
|
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
|
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
|
||||||
@@ -203,9 +224,9 @@ static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport* view
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
|
||||||
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
||||||
{
|
{
|
||||||
IM_UNUSED(scancode);
|
|
||||||
switch (keycode)
|
switch (keycode)
|
||||||
{
|
{
|
||||||
case SDLK_TAB: return ImGuiKey_Tab;
|
case SDLK_TAB: return ImGuiKey_Tab;
|
||||||
@@ -223,17 +244,17 @@ ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
|||||||
case SDLK_SPACE: return ImGuiKey_Space;
|
case SDLK_SPACE: return ImGuiKey_Space;
|
||||||
case SDLK_RETURN: return ImGuiKey_Enter;
|
case SDLK_RETURN: return ImGuiKey_Enter;
|
||||||
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
||||||
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
|
//case SDLK_QUOTE: return ImGuiKey_Apostrophe;
|
||||||
case SDLK_COMMA: return ImGuiKey_Comma;
|
case SDLK_COMMA: return ImGuiKey_Comma;
|
||||||
case SDLK_MINUS: return ImGuiKey_Minus;
|
//case SDLK_MINUS: return ImGuiKey_Minus;
|
||||||
case SDLK_PERIOD: return ImGuiKey_Period;
|
case SDLK_PERIOD: return ImGuiKey_Period;
|
||||||
case SDLK_SLASH: return ImGuiKey_Slash;
|
//case SDLK_SLASH: return ImGuiKey_Slash;
|
||||||
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
||||||
case SDLK_EQUALS: return ImGuiKey_Equal;
|
//case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||||
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
//case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||||
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
//case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||||
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
//case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||||
case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
|
//case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
|
||||||
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||||
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||||
@@ -329,6 +350,24 @@ ImGuiKey ImGui_ImplSDL2_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
|||||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to scancode
|
||||||
|
switch (scancode)
|
||||||
|
{
|
||||||
|
case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||||
|
case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
|
||||||
|
case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
|
||||||
|
case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||||
|
case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||||
|
case SDL_SCANCODE_NONUSBACKSLASH: return ImGuiKey_Oem102;
|
||||||
|
case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||||
|
case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||||
|
case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||||
|
case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
|
||||||
|
case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
|
||||||
|
case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
return ImGuiKey_None;
|
return ImGuiKey_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +399,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
{
|
{
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == NULL)
|
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)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
@@ -376,7 +415,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
case SDL_MOUSEWHEEL:
|
case SDL_MOUSEWHEEL:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->wheel.windowID) == NULL)
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->wheel.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
||||||
#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
|
#if SDL_VERSION_ATLEAST(2,0,18) // If this fails to compile on Emscripten: update to latest Emscripten!
|
||||||
@@ -386,7 +425,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
float wheel_x = -(float)event->wheel.x;
|
float wheel_x = -(float)event->wheel.x;
|
||||||
float wheel_y = (float)event->wheel.y;
|
float wheel_y = (float)event->wheel.y;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __EMSCRIPTEN__
|
#if defined(__EMSCRIPTEN__) && !SDL_VERSION_ATLEAST(2,31,0)
|
||||||
wheel_x /= 100.0f;
|
wheel_x /= 100.0f;
|
||||||
#endif
|
#endif
|
||||||
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||||
@@ -396,7 +435,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->button.windowID) == NULL)
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->button.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
int mouse_button = -1;
|
int mouse_button = -1;
|
||||||
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
||||||
@@ -413,7 +452,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
case SDL_TEXTINPUT:
|
case SDL_TEXTINPUT:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->text.windowID) == NULL)
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->text.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
io.AddInputCharactersUTF8(event->text.text);
|
io.AddInputCharactersUTF8(event->text.text);
|
||||||
return true;
|
return true;
|
||||||
@@ -421,12 +460,15 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID) == NULL)
|
ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID);
|
||||||
|
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);
|
||||||
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, event->key.keysym.sym, event->key.keysym.scancode, 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
|
#if SDL_HAS_DISPLAY_EVENT
|
||||||
@@ -457,15 +499,17 @@ 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);
|
||||||
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||||
io.AddFocusEvent(false);
|
io.AddFocusEvent(false);
|
||||||
else if (window_event == SDL_WINDOWEVENT_CLOSE)
|
if (window_event == SDL_WINDOWEVENT_CLOSE)
|
||||||
viewport->PlatformRequestClose = true;
|
viewport->PlatformRequestClose = true;
|
||||||
else if (window_event == SDL_WINDOWEVENT_MOVED)
|
if (window_event == SDL_WINDOWEVENT_MOVED)
|
||||||
viewport->PlatformRequestMove = true;
|
viewport->PlatformRequestMove = true;
|
||||||
else if (window_event == SDL_WINDOWEVENT_RESIZED)
|
if (window_event == SDL_WINDOWEVENT_RESIZED)
|
||||||
viewport->PlatformRequestResize = true;
|
viewport->PlatformRequestResize = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -475,6 +519,8 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
bd->WantUpdateGamepadsList = true;
|
bd->WantUpdateGamepadsList = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -488,26 +534,23 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||||
|
//SDL_SetHint(SDL_HINT_EVENT_LOGGING, "2");
|
||||||
|
|
||||||
// Check and store if we are on a SDL backend that supports global mouse position
|
// Obtain compiled and runtime versions
|
||||||
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
SDL_version ver_compiled;
|
||||||
bool mouse_can_use_global_state = false;
|
SDL_version ver_runtime;
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
SDL_VERSION(&ver_compiled);
|
||||||
const char* sdl_backend = SDL_GetCurrentVideoDriver();
|
SDL_GetVersion(&ver_runtime);
|
||||||
const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
|
|
||||||
for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
|
|
||||||
if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
|
|
||||||
mouse_can_use_global_state = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
|
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
|
||||||
|
snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_sdl2 (%u.%u.%u, %u.%u.%u)",
|
||||||
|
ver_compiled.major, ver_compiled.minor, ver_compiled.patch, ver_runtime.major, ver_runtime.minor, ver_runtime.patch);
|
||||||
io.BackendPlatformUserData = (void*)bd;
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
io.BackendPlatformName = "imgui_impl_sdl2";
|
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)
|
||||||
if (mouse_can_use_global_state)
|
// (ImGuiBackendFlags_PlatformHasViewports may be set just below)
|
||||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
|
||||||
|
|
||||||
bd->Window = window;
|
bd->Window = window;
|
||||||
bd->WindowID = SDL_GetWindowID(window);
|
bd->WindowID = SDL_GetWindowID(window);
|
||||||
@@ -515,13 +558,26 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
|
|
||||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
// 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.
|
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
||||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
||||||
#else
|
#else
|
||||||
bd->MouseCanReportHoveredViewport = false;
|
bd->MouseCanReportHoveredViewport = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check and store if we are on a SDL backend that supports SDL_GetGlobalMouseState() and SDL_CaptureMouse()
|
||||||
|
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
||||||
|
bd->MouseCanUseGlobalState = false;
|
||||||
|
bd->MouseCanUseCapture = false;
|
||||||
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
|
const char* sdl_backend = SDL_GetCurrentVideoDriver();
|
||||||
|
const char* capture_and_global_state_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
|
||||||
|
for (const char* item : capture_and_global_state_whitelist)
|
||||||
|
if (strncmp(sdl_backend, item, strlen(item)) == 0)
|
||||||
|
bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true;
|
||||||
|
#endif
|
||||||
|
if (bd->MouseCanUseGlobalState)
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
||||||
@@ -529,6 +585,8 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
|
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL2_PlatformSetImeData;
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplSDL2_EmscriptenOpenURL(url); return true; };
|
||||||
|
#elif SDL_HAS_OPEN_URL
|
||||||
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Update monitor a first time during init
|
// Update monitor a first time during init
|
||||||
@@ -547,6 +605,8 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Wait] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Progress] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAITARROW);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||||
|
|
||||||
// Set platform dependent data in viewport
|
// Set platform dependent data in viewport
|
||||||
@@ -587,9 +647,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
||||||
// We left the call to ImGui_ImplSDL2_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
|
// We left the call to ImGui_ImplSDL2_InitMultiViewportSupport() outside of #ifdef to avoid unused-function warnings.
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
|
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
|
||||||
ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context);
|
ImGui_ImplSDL2_InitMultiViewportSupport(window, sdl_gl_context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -642,7 +702,7 @@ void ImGui_ImplSDL2_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplSDL2_ShutdownPlatformInterface();
|
ImGui_ImplSDL2_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
if (bd->ClipboardTextData)
|
if (bd->ClipboardTextData)
|
||||||
SDL_free(bd->ClipboardTextData);
|
SDL_free(bd->ClipboardTextData);
|
||||||
@@ -664,8 +724,17 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||||||
|
|
||||||
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
|
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
// - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
||||||
SDL_CaptureMouse((bd->MouseButtonsDown != 0) ? SDL_TRUE : SDL_FALSE);
|
// - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to mitigate the issue we wait until mouse has moved to begin capture.
|
||||||
|
if (bd->MouseCanUseCapture)
|
||||||
|
{
|
||||||
|
bool want_capture = false;
|
||||||
|
for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++)
|
||||||
|
if (ImGui::IsMouseDragging(button_n, 1.0f))
|
||||||
|
want_capture = true;
|
||||||
|
SDL_CaptureMouse(want_capture ? SDL_TRUE : SDL_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
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 = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL2_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
|
||||||
#else
|
#else
|
||||||
@@ -675,7 +744,7 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||||||
|
|
||||||
if (is_app_focused)
|
if (is_app_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos 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)
|
||||||
{
|
{
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
@@ -687,7 +756,8 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
const bool is_relative_mouse_mode = SDL_GetRelativeMouseMode() != 0;
|
||||||
|
if (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)
|
// 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)
|
||||||
@@ -745,6 +815,27 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - On Windows the process needs to be marked DPI-aware!! SDL2 doesn't do it by default. You can call ::SetProcessDPIAware() or call ImGui_ImplWin32_EnableDpiAwareness() from Win32 backend.
|
||||||
|
// - Apple platforms use FramebufferScale so we always return 1.0f.
|
||||||
|
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
|
||||||
|
float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window)
|
||||||
|
{
|
||||||
|
return ImGui_ImplSDL2_GetContentScaleForDisplay(SDL_GetWindowDisplayIndex(window));
|
||||||
|
}
|
||||||
|
|
||||||
|
float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index)
|
||||||
|
{
|
||||||
|
#if SDL_HAS_PER_MONITOR_DPI
|
||||||
|
#if !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
|
||||||
|
float dpi = 0.0f;
|
||||||
|
if (SDL_GetDisplayDPI(display_index, &dpi, nullptr, nullptr) == 0)
|
||||||
|
return dpi / 96.0f;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
IM_UNUSED(display_index);
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_CloseGamepads()
|
static void ImGui_ImplSDL2_CloseGamepads()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||||
@@ -760,7 +851,7 @@ void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_
|
|||||||
ImGui_ImplSDL2_CloseGamepads();
|
ImGui_ImplSDL2_CloseGamepads();
|
||||||
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
|
if (mode == ImGui_ImplSDL2_GamepadMode_Manual)
|
||||||
{
|
{
|
||||||
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
|
IM_ASSERT(manual_gamepads_array != nullptr || manual_gamepads_count <= 0);
|
||||||
for (int n = 0; n < manual_gamepads_count; n++)
|
for (int n = 0; n < manual_gamepads_count; n++)
|
||||||
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
||||||
}
|
}
|
||||||
@@ -814,9 +905,6 @@ static void ImGui_ImplSDL2_UpdateGamepads()
|
|||||||
bd->WantUpdateGamepadsList = false;
|
bd->WantUpdateGamepadsList = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
|
||||||
return;
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||||
if (bd->Gamepads.Size == 0)
|
if (bd->Gamepads.Size == 0)
|
||||||
return;
|
return;
|
||||||
@@ -867,51 +955,55 @@ static void ImGui_ImplSDL2_UpdateMonitors()
|
|||||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||||
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
|
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
|
||||||
SDL_GetDisplayUsableBounds(n, &r);
|
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
|
|
||||||
#if SDL_HAS_PER_MONITOR_DPI
|
|
||||||
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
|
|
||||||
// DpiScale to cocoa_window.backingScaleFactor here.
|
|
||||||
float dpi = 0.0f;
|
|
||||||
if (!SDL_GetDisplayDPI(n, &dpi, nullptr, nullptr))
|
|
||||||
{
|
{
|
||||||
if (dpi <= 0.0f)
|
monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||||
monitor.DpiScale = dpi / 96.0f;
|
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
monitor.PlatformHandle = (void*)(intptr_t)n;
|
||||||
platform_io.Monitors.push_back(monitor);
|
platform_io.Monitors.push_back(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window, SDL_Renderer* renderer, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
int display_w, display_h;
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||||
|
w = h = 0;
|
||||||
|
if (renderer != nullptr)
|
||||||
|
SDL_GetRendererOutputSize(renderer, &display_w, &display_h);
|
||||||
|
#if SDL_HAS_VULKAN
|
||||||
|
else if (SDL_GetWindowFlags(window) & SDL_WINDOW_VULKAN)
|
||||||
|
SDL_Vulkan_GetDrawableSize(window, &display_w, &display_h);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
|
||||||
|
if (out_size != nullptr)
|
||||||
|
*out_size = ImVec2((float)w, (float)h);
|
||||||
|
if (out_framebuffer_scale != nullptr)
|
||||||
|
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDL2_NewFrame()
|
void ImGui_ImplSDL2_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
int w, h;
|
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(bd->Window, bd->Renderer, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
int display_w, display_h;
|
|
||||||
SDL_GetWindowSize(bd->Window, &w, &h);
|
|
||||||
if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED)
|
|
||||||
w = h = 0;
|
|
||||||
if (bd->Renderer != nullptr)
|
|
||||||
SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h);
|
|
||||||
#if SDL_HAS_VULKAN
|
|
||||||
else if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_VULKAN)
|
|
||||||
SDL_Vulkan_GetDrawableSize(bd->Window, &display_w, &display_h);
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
|
|
||||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
|
||||||
if (w > 0 && h > 0)
|
|
||||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
|
||||||
|
|
||||||
// Update monitors
|
// 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)
|
if (bd->WantUpdateMonitors)
|
||||||
ImGui_ImplSDL2_UpdateMonitors();
|
ImGui_ImplSDL2_UpdateMonitors();
|
||||||
|
|
||||||
@@ -951,16 +1043,16 @@ void ImGui_ImplSDL2_NewFrame()
|
|||||||
// 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..
|
// 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.
|
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
struct ImGui_ImplSDL2_ViewportData
|
struct ImGui_ImplSDL2_ViewportData
|
||||||
{
|
{
|
||||||
SDL_Window* Window;
|
SDL_Window* Window;
|
||||||
Uint32 WindowID;
|
Uint32 WindowID; // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
|
||||||
bool WindowOwned;
|
bool WindowOwned;
|
||||||
SDL_GLContext GLContext;
|
SDL_GLContext GLContext;
|
||||||
|
|
||||||
ImGui_ImplSDL2_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
ImGui_ImplSDL2_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
||||||
~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
||||||
@@ -1037,7 +1129,7 @@ static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
|
|||||||
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||||
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
|
#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;
|
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||||
|
|
||||||
// SDL hack: Hide icon from task bar
|
// SDL hack: Hide icon from task bar
|
||||||
@@ -1092,6 +1184,15 @@ static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|||||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
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)
|
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||||
@@ -1154,7 +1255,7 @@ static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
|
|||||||
}
|
}
|
||||||
#endif // SDL_HAS_VULKAN
|
#endif // SDL_HAS_VULKAN
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context)
|
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
|
||||||
{
|
{
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
// Register platform interface (will be coupled with a renderer interface)
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
@@ -1165,6 +1266,7 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g
|
|||||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
|
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
|
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
|
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
|
||||||
|
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL2_GetWindowFramebufferScale;
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
|
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
|
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
|
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
|
||||||
@@ -1190,7 +1292,7 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g
|
|||||||
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface()
|
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||||
// [x] Platform: Basic IME support. 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.
|
||||||
@@ -42,9 +42,13 @@ IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||||
|
|
||||||
|
// DPI-related helpers (optional)
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index);
|
||||||
|
|
||||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
// dear imgui: Platform Backend for SDL3
|
||||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||||
|
|
||||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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: 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.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
// [ ] 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.
|
||||||
@@ -24,7 +23,24 @@
|
|||||||
|
|
||||||
// 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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 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-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-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-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-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-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.
|
||||||
|
// 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-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:
|
||||||
@@ -59,11 +75,13 @@
|
|||||||
// Clang warnings with -Weverything
|
// Clang warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||||
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
#include <stdio.h> // for snprintf()
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#include <TargetConditionals.h>
|
#include <TargetConditionals.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -96,6 +114,7 @@ struct ImGui_ImplSDL3_Data
|
|||||||
SDL_Renderer* Renderer;
|
SDL_Renderer* Renderer;
|
||||||
Uint64 Time;
|
Uint64 Time;
|
||||||
char* ClipboardTextData;
|
char* ClipboardTextData;
|
||||||
|
char BackendPlatformName[48];
|
||||||
bool UseVulkan;
|
bool UseVulkan;
|
||||||
bool WantUpdateMonitors;
|
bool WantUpdateMonitors;
|
||||||
|
|
||||||
@@ -109,6 +128,7 @@ struct ImGui_ImplSDL3_Data
|
|||||||
SDL_Cursor* MouseLastCursor;
|
SDL_Cursor* MouseLastCursor;
|
||||||
int MousePendingLeaveFrame;
|
int MousePendingLeaveFrame;
|
||||||
bool MouseCanUseGlobalState;
|
bool MouseCanUseGlobalState;
|
||||||
|
bool MouseCanUseCapture;
|
||||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
@@ -130,8 +150,8 @@ static ImGui_ImplSDL3_Data* ImGui_ImplSDL3_GetBackendData()
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplSDL3_UpdateMonitors();
|
static void ImGui_ImplSDL3_UpdateMonitors();
|
||||||
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
|
static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
|
||||||
static void ImGui_ImplSDL3_ShutdownPlatformInterface();
|
static void ImGui_ImplSDL3_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
||||||
@@ -139,8 +159,7 @@ static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
|||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||||
if (bd->ClipboardTextData)
|
if (bd->ClipboardTextData)
|
||||||
SDL_free(bd->ClipboardTextData);
|
SDL_free(bd->ClipboardTextData);
|
||||||
const char* sdl_clipboard_text = SDL_GetClipboardText();
|
bd->ClipboardTextData = SDL_GetClipboardText();
|
||||||
bd->ClipboardTextData = sdl_clipboard_text ? SDL_strdup(sdl_clipboard_text) : NULL;
|
|
||||||
return bd->ClipboardTextData;
|
return bd->ClipboardTextData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +173,7 @@ static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport* view
|
|||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||||
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
||||||
SDL_Window* window = SDL_GetWindowFromID(window_id);
|
SDL_Window* window = SDL_GetWindowFromID(window_id);
|
||||||
if ((data->WantVisible == false || bd->ImeWindow != window) && bd->ImeWindow != NULL)
|
if ((!(data->WantVisible || data->WantTextInput) || bd->ImeWindow != window) && bd->ImeWindow != nullptr)
|
||||||
{
|
{
|
||||||
SDL_StopTextInput(bd->ImeWindow);
|
SDL_StopTextInput(bd->ImeWindow);
|
||||||
bd->ImeWindow = nullptr;
|
bd->ImeWindow = nullptr;
|
||||||
@@ -167,12 +186,14 @@ static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport* view
|
|||||||
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);
|
||||||
SDL_StartTextInput(window);
|
|
||||||
bd->ImeWindow = window;
|
bd->ImeWindow = window;
|
||||||
}
|
}
|
||||||
|
if (!SDL_TextInputActive(window) && (data->WantVisible || data->WantTextInput))
|
||||||
|
SDL_StartTextInput(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode);
|
||||||
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode scancode)
|
||||||
{
|
{
|
||||||
// Keypad doesn't have individual key values in SDL3
|
// Keypad doesn't have individual key values in SDL3
|
||||||
@@ -214,17 +235,17 @@ ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
|||||||
case SDLK_SPACE: return ImGuiKey_Space;
|
case SDLK_SPACE: return ImGuiKey_Space;
|
||||||
case SDLK_RETURN: return ImGuiKey_Enter;
|
case SDLK_RETURN: return ImGuiKey_Enter;
|
||||||
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
||||||
case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe;
|
//case SDLK_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||||
case SDLK_COMMA: return ImGuiKey_Comma;
|
case SDLK_COMMA: return ImGuiKey_Comma;
|
||||||
case SDLK_MINUS: return ImGuiKey_Minus;
|
//case SDLK_MINUS: return ImGuiKey_Minus;
|
||||||
case SDLK_PERIOD: return ImGuiKey_Period;
|
case SDLK_PERIOD: return ImGuiKey_Period;
|
||||||
case SDLK_SLASH: return ImGuiKey_Slash;
|
//case SDLK_SLASH: return ImGuiKey_Slash;
|
||||||
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
||||||
case SDLK_EQUALS: return ImGuiKey_Equal;
|
//case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||||
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
//case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||||
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
//case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||||
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
//case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||||
case SDLK_GRAVE: return ImGuiKey_GraveAccent;
|
//case SDLK_GRAVE: return ImGuiKey_GraveAccent;
|
||||||
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||||
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||||
@@ -303,6 +324,24 @@ ImGuiKey ImGui_ImplSDL3_KeyEventToImGuiKey(SDL_Keycode keycode, SDL_Scancode sca
|
|||||||
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
case SDLK_AC_FORWARD: return ImGuiKey_AppForward;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to scancode
|
||||||
|
switch (scancode)
|
||||||
|
{
|
||||||
|
case SDL_SCANCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||||
|
case SDL_SCANCODE_MINUS: return ImGuiKey_Minus;
|
||||||
|
case SDL_SCANCODE_EQUALS: return ImGuiKey_Equal;
|
||||||
|
case SDL_SCANCODE_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||||
|
case SDL_SCANCODE_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||||
|
case SDL_SCANCODE_NONUSBACKSLASH: return ImGuiKey_Oem102;
|
||||||
|
case SDL_SCANCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||||
|
case SDL_SCANCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||||
|
case SDL_SCANCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||||
|
case SDL_SCANCODE_COMMA: return ImGuiKey_Comma;
|
||||||
|
case SDL_SCANCODE_PERIOD: return ImGuiKey_Period;
|
||||||
|
case SDL_SCANCODE_SLASH: return ImGuiKey_Slash;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
return ImGuiKey_None;
|
return ImGuiKey_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +373,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
{
|
{
|
||||||
case SDL_EVENT_MOUSE_MOTION:
|
case SDL_EVENT_MOUSE_MOTION:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->motion.windowID) == NULL)
|
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)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
@@ -350,14 +389,11 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
case SDL_EVENT_MOUSE_WHEEL:
|
case SDL_EVENT_MOUSE_WHEEL:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->wheel.windowID) == NULL)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->wheel.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
//IMGUI_DEBUG_LOG("wheel %.2f %.2f, precise %.2f %.2f\n", (float)event->wheel.x, (float)event->wheel.y, event->wheel.preciseX, event->wheel.preciseY);
|
||||||
float wheel_x = -event->wheel.x;
|
float wheel_x = -event->wheel.x;
|
||||||
float wheel_y = event->wheel.y;
|
float wheel_y = event->wheel.y;
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
wheel_x /= 100.0f;
|
|
||||||
#endif
|
|
||||||
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
io.AddMouseSourceEvent(event->wheel.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||||
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
||||||
return true;
|
return true;
|
||||||
@@ -365,7 +401,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->button.windowID) == NULL)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->button.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
int mouse_button = -1;
|
int mouse_button = -1;
|
||||||
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
||||||
@@ -382,7 +418,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
case SDL_EVENT_TEXT_INPUT:
|
case SDL_EVENT_TEXT_INPUT:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->text.windowID) == NULL)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->text.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
io.AddInputCharactersUTF8(event->text.text);
|
io.AddInputCharactersUTF8(event->text.text);
|
||||||
return true;
|
return true;
|
||||||
@@ -390,13 +426,15 @@ 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:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->key.windowID) == NULL)
|
ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(event->key.windowID);
|
||||||
|
if (viewport == nullptr)
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("SDL_EVENT_KEY_%d: key=%d, scancode=%d, mod=%X\n", (event->type == SDL_EVENT_KEY_DOWN) ? "DOWN" : "UP", event->key.key, event->key.scancode, event->key.mod);
|
//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);
|
||||||
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, event->key.key, event->key.scancode, 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_ORIENTATION:
|
||||||
@@ -410,7 +448,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == NULL)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
bd->MouseWindowID = event->window.windowID;
|
bd->MouseWindowID = event->window.windowID;
|
||||||
bd->MousePendingLeaveFrame = 0;
|
bd->MousePendingLeaveFrame = 0;
|
||||||
@@ -422,7 +460,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
// FIXME: Unconfirmed whether this is still needed with SDL3.
|
// FIXME: Unconfirmed whether this is still needed with SDL3.
|
||||||
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
case SDL_EVENT_WINDOW_MOUSE_LEAVE:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == NULL)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
bd->MousePendingLeaveFrame = ImGui::GetFrameCount() + 1;
|
bd->MousePendingLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||||
return true;
|
return true;
|
||||||
@@ -430,8 +468,10 @@ 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:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == NULL)
|
ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -456,6 +496,8 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
bd->WantUpdateGamepadsList = true;
|
bd->WantUpdateGamepadsList = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -466,7 +508,7 @@ static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Win
|
|||||||
viewport->PlatformHandleRaw = nullptr;
|
viewport->PlatformHandleRaw = nullptr;
|
||||||
#if defined(_WIN32) && !defined(__WINRT__)
|
#if defined(_WIN32) && !defined(__WINRT__)
|
||||||
viewport->PlatformHandleRaw = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
viewport->PlatformHandleRaw = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr);
|
||||||
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
|
#elif defined(__APPLE__)
|
||||||
viewport->PlatformHandleRaw = SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr);
|
viewport->PlatformHandleRaw = SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -477,26 +519,19 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||||
IM_UNUSED(sdl_gl_context); // Unused in this branch
|
IM_UNUSED(sdl_gl_context); // Unused in this branch
|
||||||
|
//SDL_SetHint(SDL_HINT_EVENT_LOGGING, "2");
|
||||||
|
|
||||||
// Check and store if we are on a SDL backend that supports global mouse position
|
const int ver_linked = SDL_GetVersion();
|
||||||
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
|
||||||
bool mouse_can_use_global_state = false;
|
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
|
||||||
const char* sdl_backend = SDL_GetCurrentVideoDriver();
|
|
||||||
const char* global_mouse_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
|
|
||||||
for (int n = 0; n < IM_ARRAYSIZE(global_mouse_whitelist); n++)
|
|
||||||
if (strncmp(sdl_backend, global_mouse_whitelist[n], strlen(global_mouse_whitelist[n])) == 0)
|
|
||||||
mouse_can_use_global_state = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
// Setup backend capabilities flags
|
||||||
ImGui_ImplSDL3_Data* bd = IM_NEW(ImGui_ImplSDL3_Data)();
|
ImGui_ImplSDL3_Data* bd = IM_NEW(ImGui_ImplSDL3_Data)();
|
||||||
|
snprintf(bd->BackendPlatformName, sizeof(bd->BackendPlatformName), "imgui_impl_sdl3 (%d.%d.%d; %d.%d.%d)",
|
||||||
|
SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_MICRO_VERSION, SDL_VERSIONNUM_MAJOR(ver_linked), SDL_VERSIONNUM_MINOR(ver_linked), SDL_VERSIONNUM_MICRO(ver_linked));
|
||||||
io.BackendPlatformUserData = (void*)bd;
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
io.BackendPlatformName = "imgui_impl_sdl3";
|
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)
|
||||||
if (mouse_can_use_global_state)
|
// (ImGuiBackendFlags_PlatformHasViewports may be set just below)
|
||||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
|
||||||
|
|
||||||
bd->Window = window;
|
bd->Window = window;
|
||||||
bd->WindowID = SDL_GetWindowID(window);
|
bd->WindowID = SDL_GetWindowID(window);
|
||||||
@@ -504,17 +539,31 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
|
|
||||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
// 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.
|
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
||||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
||||||
#else
|
#else
|
||||||
bd->MouseCanReportHoveredViewport = false;
|
bd->MouseCanReportHoveredViewport = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check and store if we are on a SDL backend that supports SDL_GetGlobalMouseState() and SDL_CaptureMouse()
|
||||||
|
// ("wayland" and "rpi" don't support it, but we chose to use a white-list instead of a black-list)
|
||||||
|
bd->MouseCanUseGlobalState = false;
|
||||||
|
bd->MouseCanUseCapture = false;
|
||||||
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
|
const char* sdl_backend = SDL_GetCurrentVideoDriver();
|
||||||
|
const char* capture_and_global_state_whitelist[] = { "windows", "cocoa", "x11", "DIVE", "VMAN" };
|
||||||
|
for (const char* item : capture_and_global_state_whitelist)
|
||||||
|
if (strncmp(sdl_backend, item, strlen(item)) == 0)
|
||||||
|
bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true;
|
||||||
|
#endif
|
||||||
|
if (bd->MouseCanUseGlobalState)
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
platform_io.Platform_GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
|
||||||
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) == 0; };
|
||||||
|
|
||||||
// Update monitor a first time during init
|
// Update monitor a first time during init
|
||||||
ImGui_ImplSDL3_UpdateMonitors();
|
ImGui_ImplSDL3_UpdateMonitors();
|
||||||
@@ -532,6 +581,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE);
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NESW_RESIZE);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE);
|
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NWSE_RESIZE);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
|
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_POINTER);
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Wait] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||||
|
bd->MouseCursors[ImGuiMouseCursor_Progress] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_PROGRESS);
|
||||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
||||||
|
|
||||||
// Set platform dependent data in viewport
|
// Set platform dependent data in viewport
|
||||||
@@ -543,7 +594,7 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
|
// Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
|
||||||
// (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
|
// (This is unfortunately a global SDL setting, so enabling it might have a side-effect on your application.
|
||||||
// It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
|
// It is unlikely to make a difference, but if your app absolutely needs to ignore the initial on-focus click:
|
||||||
// you can ignore SDL_EVENT_MOUSE_BUTTON_DOWN events coming right after a SDL_WINDOWEVENT_FOCUS_GAINED)
|
// you can ignore SDL_EVENT_MOUSE_BUTTON_DOWN events coming right after a SDL_EVENT_WINDOW_FOCUS_GAINED)
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||||
|
|
||||||
// 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)
|
||||||
@@ -554,8 +605,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
|
|
||||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
// 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.
|
// We left the call to ImGui_ImplSDL3_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
|
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
|
||||||
ImGui_ImplSDL3_InitPlatformInterface(window, sdl_gl_context);
|
ImGui_ImplSDL3_InitMultiViewportSupport(window, sdl_gl_context);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -593,6 +644,11 @@ bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* rendere
|
|||||||
return ImGui_ImplSDL3_Init(window, renderer, nullptr);
|
return ImGui_ImplSDL3_Init(window, renderer, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window)
|
||||||
|
{
|
||||||
|
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui_ImplSDL3_InitForOther(SDL_Window* window)
|
bool ImGui_ImplSDL3_InitForOther(SDL_Window* window)
|
||||||
{
|
{
|
||||||
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||||
@@ -606,7 +662,7 @@ void ImGui_ImplSDL3_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplSDL3_ShutdownPlatformInterface();
|
ImGui_ImplSDL3_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
if (bd->ClipboardTextData)
|
if (bd->ClipboardTextData)
|
||||||
SDL_free(bd->ClipboardTextData);
|
SDL_free(bd->ClipboardTextData);
|
||||||
@@ -628,8 +684,17 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
|
|
||||||
// We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
|
// We forward mouse input when hovered or captured (via SDL_EVENT_MOUSE_MOTION) or when focused (below)
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger other operations outside
|
// - SDL_CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
||||||
SDL_CaptureMouse(bd->MouseButtonsDown != 0);
|
// - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to mitigate the issue we wait until mouse has moved to begin capture.
|
||||||
|
if (bd->MouseCanUseCapture)
|
||||||
|
{
|
||||||
|
bool want_capture = false;
|
||||||
|
for (int button_n = 0; button_n < ImGuiMouseButton_COUNT && !want_capture; button_n++)
|
||||||
|
if (ImGui::IsMouseDragging(button_n, 1.0f))
|
||||||
|
want_capture = true;
|
||||||
|
SDL_CaptureMouse(want_capture);
|
||||||
|
}
|
||||||
|
|
||||||
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 = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
|
||||||
#else
|
#else
|
||||||
@@ -638,7 +703,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
#endif
|
#endif
|
||||||
if (is_app_focused)
|
if (is_app_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos 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)
|
||||||
{
|
{
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||||
@@ -650,7 +715,8 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) Fallback to provide mouse position when focused (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
// (Optional) Fallback to provide mouse position when focused (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
||||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
const bool is_relative_mouse_mode = SDL_GetWindowRelativeMouseMode(bd->Window);
|
||||||
|
if (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)
|
// 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)
|
||||||
@@ -724,7 +790,7 @@ void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad*
|
|||||||
ImGui_ImplSDL3_CloseGamepads();
|
ImGui_ImplSDL3_CloseGamepads();
|
||||||
if (mode == ImGui_ImplSDL3_GamepadMode_Manual)
|
if (mode == ImGui_ImplSDL3_GamepadMode_Manual)
|
||||||
{
|
{
|
||||||
IM_ASSERT(manual_gamepads_array != nullptr && manual_gamepads_count > 0);
|
IM_ASSERT(manual_gamepads_array != nullptr || manual_gamepads_count <= 0);
|
||||||
for (int n = 0; n < manual_gamepads_count; n++)
|
for (int n = 0; n < manual_gamepads_count; n++)
|
||||||
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
bd->Gamepads.push_back(manual_gamepads_array[n]);
|
||||||
}
|
}
|
||||||
@@ -779,9 +845,6 @@ static void ImGui_ImplSDL3_UpdateGamepads()
|
|||||||
SDL_free(sdl_gamepads);
|
SDL_free(sdl_gamepads);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
|
||||||
return;
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||||
if (bd->Gamepads.Size == 0)
|
if (bd->Gamepads.Size == 0)
|
||||||
return;
|
return;
|
||||||
@@ -833,12 +896,12 @@ static void ImGui_ImplSDL3_UpdateMonitors()
|
|||||||
SDL_GetDisplayBounds(display_id, &r);
|
SDL_GetDisplayBounds(display_id, &r);
|
||||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||||
SDL_GetDisplayUsableBounds(display_id, &r);
|
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.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||||
// FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
|
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||||
// DpiScale to cocoa_window.backingScaleFactor here.
|
}
|
||||||
monitor.DpiScale = SDL_GetDisplayContentScale(display_id);
|
monitor.DpiScale = SDL_GetDisplayContentScale(display_id); // See https://wiki.libsdl.org/SDL3/README-highdpi for details.
|
||||||
monitor.PlatformHandle = (void*)(intptr_t)n;
|
monitor.PlatformHandle = (void*)(intptr_t)n;
|
||||||
if (monitor.DpiScale <= 0.0f)
|
if (monitor.DpiScale <= 0.0f)
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
||||||
@@ -847,28 +910,37 @@ static void ImGui_ImplSDL3_UpdateMonitors()
|
|||||||
SDL_free(displays);
|
SDL_free(displays);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||||
|
{
|
||||||
|
int w, h;
|
||||||
|
int display_w, display_h;
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||||
|
w = h = 0;
|
||||||
|
SDL_GetWindowSizeInPixels(window, &display_w, &display_h);
|
||||||
|
if (out_size != nullptr)
|
||||||
|
*out_size = ImVec2((float)w, (float)h);
|
||||||
|
if (out_framebuffer_scale != nullptr)
|
||||||
|
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDL3_NewFrame()
|
void ImGui_ImplSDL3_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL3_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL3_Init()?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
int w, h;
|
ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
int display_w, display_h;
|
|
||||||
SDL_GetWindowSize(bd->Window, &w, &h);
|
|
||||||
if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED)
|
|
||||||
w = h = 0;
|
|
||||||
SDL_GetWindowSizeInPixels(bd->Window, &display_w, &display_h);
|
|
||||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
|
||||||
if (w > 0 && h > 0)
|
|
||||||
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
|
||||||
|
|
||||||
// Update monitors
|
// 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)
|
if (bd->WantUpdateMonitors)
|
||||||
ImGui_ImplSDL3_UpdateMonitors();
|
ImGui_ImplSDL3_UpdateMonitors();
|
||||||
|
|
||||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
// 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();
|
||||||
Uint64 current_time = SDL_GetPerformanceCounter();
|
Uint64 current_time = SDL_GetPerformanceCounter();
|
||||||
@@ -904,17 +976,17 @@ void ImGui_ImplSDL3_NewFrame()
|
|||||||
// 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..
|
// 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.
|
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
struct ImGui_ImplSDL3_ViewportData
|
struct ImGui_ImplSDL3_ViewportData
|
||||||
{
|
{
|
||||||
SDL_Window* Window;
|
SDL_Window* Window;
|
||||||
SDL_Window* ParentWindow;
|
SDL_Window* ParentWindow;
|
||||||
Uint32 WindowID;
|
Uint32 WindowID; // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
|
||||||
bool WindowOwned;
|
bool WindowOwned;
|
||||||
SDL_GLContext GLContext;
|
SDL_GLContext GLContext;
|
||||||
|
|
||||||
ImGui_ImplSDL3_ViewportData() { Window = ParentWindow = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
ImGui_ImplSDL3_ViewportData() { Window = ParentWindow = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
||||||
~ImGui_ImplSDL3_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
~ImGui_ImplSDL3_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
||||||
};
|
};
|
||||||
|
|
||||||
static SDL_Window* ImGui_ImplSDL3_GetSDLWindowFromViewportID(ImGuiID viewport_id)
|
static SDL_Window* ImGui_ImplSDL3_GetSDLWindowFromViewportID(ImGuiID viewport_id)
|
||||||
@@ -949,15 +1021,18 @@ static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
|
|||||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint32 sdl_flags = 0;
|
SDL_WindowFlags sdl_flags = 0;
|
||||||
|
sdl_flags |= SDL_WINDOW_HIDDEN;
|
||||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
|
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
|
||||||
sdl_flags |= SDL_GetWindowFlags(bd->Window);
|
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) ? SDL_WINDOW_BORDERLESS : 0;
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
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_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0;
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 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);
|
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);
|
SDL_SetWindowParent(vd->Window, vd->ParentWindow);
|
||||||
|
#endif
|
||||||
SDL_SetWindowPosition(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
SDL_SetWindowPosition(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
||||||
vd->WindowOwned = true;
|
vd->WindowOwned = true;
|
||||||
if (use_opengl)
|
if (use_opengl)
|
||||||
@@ -989,7 +1064,7 @@ static void ImGui_ImplSDL3_DestroyWindow(ImGuiViewport* viewport)
|
|||||||
static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||||
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
|
#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;
|
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||||
|
|
||||||
// SDL hack: Show icon in task bar (#7989)
|
// SDL hack: Show icon in task bar (#7989)
|
||||||
@@ -1004,14 +1079,20 @@ static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
|
|||||||
}
|
}
|
||||||
#endif
|
#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");
|
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "0" : "1");
|
||||||
|
#endif
|
||||||
SDL_ShowWindow(vd->Window);
|
SDL_ShowWindow(vd->Window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_UpdateWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplSDL3_UpdateWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
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.
|
// Update SDL3 parent if it changed _after_ creation.
|
||||||
// This is for advanced apps that are manipulating ParentViewportID manually.
|
// This is for advanced apps that are manipulating ParentViewportID manually.
|
||||||
SDL_Window* new_parent = ImGui_ImplSDL3_GetSDLWindowFromViewportID(viewport->ParentViewportId);
|
SDL_Window* new_parent = ImGui_ImplSDL3_GetSDLWindowFromViewportID(viewport->ParentViewportId);
|
||||||
@@ -1020,6 +1101,7 @@ static void ImGui_ImplSDL3_UpdateWindow(ImGuiViewport* viewport)
|
|||||||
vd->ParentWindow = new_parent;
|
vd->ParentWindow = new_parent;
|
||||||
SDL_SetWindowParent(vd->Window, vd->ParentWindow);
|
SDL_SetWindowParent(vd->Window, vd->ParentWindow);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL3_GetWindowPos(ImGuiViewport* viewport)
|
static ImVec2 ImGui_ImplSDL3_GetWindowPos(ImGuiViewport* viewport)
|
||||||
@@ -1050,6 +1132,14 @@ static void ImGui_ImplSDL3_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|||||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
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)
|
static void ImGui_ImplSDL3_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||||
@@ -1104,11 +1194,11 @@ static int ImGui_ImplSDL3_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
|
|||||||
{
|
{
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
||||||
(void)vk_allocator;
|
(void)vk_allocator;
|
||||||
bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
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
|
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context)
|
static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
|
||||||
{
|
{
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
// Register platform interface (will be coupled with a renderer interface)
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
@@ -1120,6 +1210,7 @@ static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_g
|
|||||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL3_GetWindowPos;
|
platform_io.Platform_GetWindowPos = ImGui_ImplSDL3_GetWindowPos;
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL3_SetWindowSize;
|
platform_io.Platform_SetWindowSize = ImGui_ImplSDL3_SetWindowSize;
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL3_GetWindowSize;
|
platform_io.Platform_GetWindowSize = ImGui_ImplSDL3_GetWindowSize;
|
||||||
|
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL3_GetWindowFramebufferScale;
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL3_SetWindowFocus;
|
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL3_SetWindowFocus;
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL3_GetWindowFocus;
|
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL3_GetWindowFocus;
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL3_GetWindowMinimized;
|
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL3_GetWindowMinimized;
|
||||||
@@ -1141,7 +1232,7 @@ static void ImGui_ImplSDL3_InitPlatformInterface(SDL_Window* window, void* sdl_g
|
|||||||
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_ShutdownPlatformInterface()
|
static void ImGui_ImplSDL3_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
// dear imgui: Platform Backend for SDL3 (*EXPERIMENTAL*)
|
// dear imgui: Platform Backend for SDL3
|
||||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||||
|
|
||||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support.
|
// [X] Platform: Clipboard support.
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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: 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.
|
||||||
// Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||||
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
// [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.
|
||||||
@@ -38,6 +36,7 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window);
|
|||||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window);
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window);
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
||||||
@@ -46,6 +45,6 @@ IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
|||||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||||
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
740
backends/imgui_impl_sdlgpu3.cpp
Normal file
740
backends/imgui_impl_sdlgpu3.cpp
Normal file
@@ -0,0 +1,740 @@
|
|||||||
|
// dear imgui: Renderer Backend for SDL_GPU
|
||||||
|
// This needs to be used along with the SDL3 Platform Backend
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
|
// 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/
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||||
|
// - Unlike other backends, the user must call the function ImGui_ImplSDLGPU3_PrepareDrawData() BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU3_RenderDrawData.
|
||||||
|
// 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
|
||||||
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-08-08: *BREAKING* Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
|
||||||
|
// 2025-08-08: Expose SamplerDefault and SamplerCurrent in ImGui_ImplSDLGPU3_RenderState. Allow callback to change sampler.
|
||||||
|
// 2025-06-25: Mapping transfer buffer for texture update use cycle=true. Fixes artifacts e.g. on Metal backend.
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
|
||||||
|
// 2025-04-28: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2025-03-30: Made ImGui_ImplSDLGPU3_PrepareDrawData() reuse GPU Transfer Buffers which were unusually slow to recreate every frame. Much faster now.
|
||||||
|
// 2025-03-21: Fixed typo in function name Imgui_ImplSDLGPU3_PrepareDrawData() -> ImGui_ImplSDLGPU3_PrepareDrawData().
|
||||||
|
// 2025-01-16: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device.
|
||||||
|
// 2025-01-09: SDL_GPU: Added the SDL_GPU3 backend.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_sdlgpu3.h"
|
||||||
|
#include "imgui_impl_sdlgpu3_shaders.h"
|
||||||
|
|
||||||
|
// SDL_GPU Data
|
||||||
|
|
||||||
|
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
|
||||||
|
struct ImGui_ImplSDLGPU3_FrameData
|
||||||
|
{
|
||||||
|
SDL_GPUBuffer* VertexBuffer = nullptr;
|
||||||
|
SDL_GPUTransferBuffer* VertexTransferBuffer = nullptr;
|
||||||
|
uint32_t VertexBufferSize = 0;
|
||||||
|
SDL_GPUBuffer* IndexBuffer = nullptr;
|
||||||
|
SDL_GPUTransferBuffer* IndexTransferBuffer = nullptr;
|
||||||
|
uint32_t IndexBufferSize = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImGui_ImplSDLGPU3_Data
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo InitInfo;
|
||||||
|
|
||||||
|
// Graphics pipeline & shaders
|
||||||
|
SDL_GPUShader* VertexShader = nullptr;
|
||||||
|
SDL_GPUShader* FragmentShader = nullptr;
|
||||||
|
SDL_GPUGraphicsPipeline* Pipeline = nullptr;
|
||||||
|
SDL_GPUSampler* TexSampler = nullptr;
|
||||||
|
SDL_GPUTransferBuffer* TexTransferBuffer = nullptr;
|
||||||
|
uint32_t TexTransferBufferSize = 0;
|
||||||
|
|
||||||
|
// Frame data for main window
|
||||||
|
ImGui_ImplSDLGPU3_FrameData MainWindowFrameData;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
static void ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// FUNCTIONS
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
// FIXME: multi-context support has never been tested.
|
||||||
|
static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, ImGui_ImplSDLGPU3_RenderState* render_state, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
render_state->SamplerCurrent = render_state->SamplerCurrent = bd->TexSampler;
|
||||||
|
|
||||||
|
// Bind graphics pipeline
|
||||||
|
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
|
||||||
|
|
||||||
|
// Bind Vertex And Index Buffers
|
||||||
|
if (draw_data->TotalVtxCount > 0)
|
||||||
|
{
|
||||||
|
SDL_GPUBufferBinding vertex_buffer_binding = {};
|
||||||
|
vertex_buffer_binding.buffer = fd->VertexBuffer;
|
||||||
|
vertex_buffer_binding.offset = 0;
|
||||||
|
SDL_GPUBufferBinding index_buffer_binding = {};
|
||||||
|
index_buffer_binding.buffer = fd->IndexBuffer;
|
||||||
|
index_buffer_binding.offset = 0;
|
||||||
|
SDL_BindGPUVertexBuffers(render_pass,0, &vertex_buffer_binding, 1);
|
||||||
|
SDL_BindGPUIndexBuffer(render_pass, &index_buffer_binding, sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
SDL_GPUViewport viewport = {};
|
||||||
|
viewport.x = 0;
|
||||||
|
viewport.y = 0;
|
||||||
|
viewport.w = (float)fb_width;
|
||||||
|
viewport.h = (float)fb_height;
|
||||||
|
viewport.min_depth = 0.0f;
|
||||||
|
viewport.max_depth = 1.0f;
|
||||||
|
SDL_SetGPUViewport(render_pass, &viewport);
|
||||||
|
|
||||||
|
// Setup scale and translation
|
||||||
|
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||||
|
struct UBO { float scale[2]; float translation[2]; } ubo;
|
||||||
|
ubo.scale[0] = 2.0f / draw_data->DisplaySize.x;
|
||||||
|
ubo.scale[1] = 2.0f / draw_data->DisplaySize.y;
|
||||||
|
ubo.translation[0] = -1.0f - draw_data->DisplayPos.x * ubo.scale[0];
|
||||||
|
ubo.translation[1] = -1.0f - draw_data->DisplayPos.y * ubo.scale[1];
|
||||||
|
SDL_PushGPUVertexUniformData(command_buffer, 0, &ubo, sizeof(UBO));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CreateOrResizeBuffers(SDL_GPUBuffer** buffer, SDL_GPUTransferBuffer** transferbuffer, uint32_t* old_size, uint32_t new_size, SDL_GPUBufferUsageFlags usage)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
// FIXME-OPT: Not optimal, but this is fairly rarely called.
|
||||||
|
SDL_WaitForGPUIdle(v->Device);
|
||||||
|
SDL_ReleaseGPUBuffer(v->Device, *buffer);
|
||||||
|
SDL_ReleaseGPUTransferBuffer(v->Device, *transferbuffer);
|
||||||
|
|
||||||
|
SDL_GPUBufferCreateInfo buffer_info = {};
|
||||||
|
buffer_info.usage = usage;
|
||||||
|
buffer_info.size = new_size;
|
||||||
|
buffer_info.props = 0;
|
||||||
|
*buffer = SDL_CreateGPUBuffer(v->Device, &buffer_info);
|
||||||
|
*old_size = new_size;
|
||||||
|
IM_ASSERT(*buffer != nullptr && "Failed to create GPU Buffer, call SDL_GetError() for more information");
|
||||||
|
|
||||||
|
SDL_GPUTransferBufferCreateInfo transferbuffer_info = {};
|
||||||
|
transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||||
|
transferbuffer_info.size = new_size;
|
||||||
|
*transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &transferbuffer_info);
|
||||||
|
IM_ASSERT(*transferbuffer != nullptr && "Failed to create GPU Transfer Buffer, call SDL_GetError() for more information");
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDL_GPU doesn't allow copy passes to occur while a render or compute pass is bound!
|
||||||
|
// The only way to allow a user to supply their own RenderPass (to render to a texture instead of the window for example),
|
||||||
|
// is to split the upload part of ImGui_ImplSDLGPU3_RenderDrawData() to another function that needs to be called by the user before rendering.
|
||||||
|
void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||||
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||||
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplSDLGPU3_UpdateTexture(tex);
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||||
|
|
||||||
|
uint32_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||||
|
uint32_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||||
|
if (fd->VertexBuffer == nullptr || fd->VertexBufferSize < vertex_size)
|
||||||
|
CreateOrResizeBuffers(&fd->VertexBuffer, &fd->VertexTransferBuffer, &fd->VertexBufferSize, vertex_size, SDL_GPU_BUFFERUSAGE_VERTEX);
|
||||||
|
if (fd->IndexBuffer == nullptr || fd->IndexBufferSize < index_size)
|
||||||
|
CreateOrResizeBuffers(&fd->IndexBuffer, &fd->IndexTransferBuffer, &fd->IndexBufferSize, index_size, SDL_GPU_BUFFERUSAGE_INDEX);
|
||||||
|
|
||||||
|
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->Device, fd->VertexTransferBuffer, true);
|
||||||
|
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->Device, fd->IndexTransferBuffer, true);
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
SDL_UnmapGPUTransferBuffer(v->Device, fd->VertexTransferBuffer);
|
||||||
|
SDL_UnmapGPUTransferBuffer(v->Device, fd->IndexTransferBuffer);
|
||||||
|
|
||||||
|
SDL_GPUTransferBufferLocation vertex_buffer_location = {};
|
||||||
|
vertex_buffer_location.offset = 0;
|
||||||
|
vertex_buffer_location.transfer_buffer = fd->VertexTransferBuffer;
|
||||||
|
SDL_GPUTransferBufferLocation index_buffer_location = {};
|
||||||
|
index_buffer_location.offset = 0;
|
||||||
|
index_buffer_location.transfer_buffer = fd->IndexTransferBuffer;
|
||||||
|
|
||||||
|
SDL_GPUBufferRegion vertex_buffer_region = {};
|
||||||
|
vertex_buffer_region.buffer = fd->VertexBuffer;
|
||||||
|
vertex_buffer_region.offset = 0;
|
||||||
|
vertex_buffer_region.size = vertex_size;
|
||||||
|
|
||||||
|
SDL_GPUBufferRegion index_buffer_region = {};
|
||||||
|
index_buffer_region.buffer = fd->IndexBuffer;
|
||||||
|
index_buffer_region.offset = 0;
|
||||||
|
index_buffer_region.size = index_size;
|
||||||
|
|
||||||
|
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer);
|
||||||
|
SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region, true);
|
||||||
|
SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region, true);
|
||||||
|
SDL_EndGPUCopyPass(copy_pass);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||||
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||||
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||||
|
|
||||||
|
if (pipeline == nullptr)
|
||||||
|
pipeline = bd->Pipeline;
|
||||||
|
|
||||||
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||||
|
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||||
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplSDLGPU3_RenderState render_state;
|
||||||
|
render_state.Device = bd->InitInfo.Device;
|
||||||
|
render_state.SamplerDefault = render_state.SamplerCurrent = bd->TexSampler;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback != nullptr)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
|
|
||||||
|
// Clamp to viewport as SDL_SetGPUScissor() won't accept values that are off bounds
|
||||||
|
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||||
|
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||||
|
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||||
|
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
SDL_Rect scissor_rect = {};
|
||||||
|
scissor_rect.x = (int)clip_min.x;
|
||||||
|
scissor_rect.y = (int)clip_min.y;
|
||||||
|
scissor_rect.w = (int)(clip_max.x - clip_min.x);
|
||||||
|
scissor_rect.h = (int)(clip_max.y - clip_min.y);
|
||||||
|
SDL_SetGPUScissor(render_pass,&scissor_rect);
|
||||||
|
|
||||||
|
// Bind DescriptorSet with font or user texture
|
||||||
|
SDL_GPUTextureSamplerBinding texture_sampler_binding;
|
||||||
|
texture_sampler_binding.texture = (SDL_GPUTexture*)(intptr_t)pcmd->GetTexID();
|
||||||
|
texture_sampler_binding.sampler = render_state.SamplerCurrent;
|
||||||
|
SDL_BindGPUFragmentSamplers(render_pass, 0, &texture_sampler_binding, 1);
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
// **IF YOU GET A CRASH HERE** In 1.92.2 on 2025/08/08 we have changed ImTextureID to store 'SDL_GPUTexture*' instead of storing 'SDL_GPUTextureSamplerBinding'.
|
||||||
|
// Any code loading custom texture using this backend needs to be updated.
|
||||||
|
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: at this point both SDL_SetGPUViewport() and SDL_SetGPUScissor() have been called.
|
||||||
|
// Our last values will leak into user/application rendering if you forgot to call SDL_SetGPUViewport() and SDL_SetGPUScissor() yourself to explicitly set that state
|
||||||
|
// In theory we should aim to backup/restore those values but I am not sure this is possible.
|
||||||
|
// We perform a call to SDL_SetGPUScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644)
|
||||||
|
SDL_Rect scissor_rect { 0, 0, fb_width, fb_height };
|
||||||
|
SDL_SetGPUScissor(render_pass, &scissor_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
|
||||||
|
if (raw_tex != nullptr)
|
||||||
|
SDL_ReleaseGPUTexture(bd->InitInfo.Device, raw_tex);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
SDL_GPUTextureCreateInfo texture_info = {};
|
||||||
|
texture_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||||
|
texture_info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
||||||
|
texture_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||||
|
texture_info.width = tex->Width;
|
||||||
|
texture_info.height = tex->Height;
|
||||||
|
texture_info.layer_count_or_depth = 1;
|
||||||
|
texture_info.num_levels = 1;
|
||||||
|
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||||
|
|
||||||
|
SDL_GPUTexture* raw_tex = SDL_CreateGPUTexture(v->Device, &texture_info);
|
||||||
|
IM_ASSERT(raw_tex != nullptr && "Failed to create font texture, call SDL_GetError() for more info");
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)raw_tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions.
|
||||||
|
// We could use the smaller rect on _WantCreate but using the full rect allows us to clear the texture.
|
||||||
|
const int upload_x = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.x;
|
||||||
|
const int upload_y = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.y;
|
||||||
|
const int upload_w = (tex->Status == ImTextureStatus_WantCreate) ? tex->Width : tex->UpdateRect.w;
|
||||||
|
const int upload_h = (tex->Status == ImTextureStatus_WantCreate) ? tex->Height : tex->UpdateRect.h;
|
||||||
|
uint32_t upload_pitch = upload_w * tex->BytesPerPixel;
|
||||||
|
uint32_t upload_size = upload_w * upload_h * tex->BytesPerPixel;
|
||||||
|
|
||||||
|
// Create transfer buffer
|
||||||
|
if (bd->TexTransferBufferSize < upload_size)
|
||||||
|
{
|
||||||
|
SDL_ReleaseGPUTransferBuffer(v->Device, bd->TexTransferBuffer);
|
||||||
|
SDL_GPUTransferBufferCreateInfo transferbuffer_info = {};
|
||||||
|
transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||||
|
transferbuffer_info.size = upload_size + 1024;
|
||||||
|
bd->TexTransferBufferSize = upload_size + 1024;
|
||||||
|
bd->TexTransferBuffer = SDL_CreateGPUTransferBuffer(v->Device, &transferbuffer_info);
|
||||||
|
IM_ASSERT(bd->TexTransferBuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy to transfer buffer
|
||||||
|
{
|
||||||
|
void* texture_ptr = SDL_MapGPUTransferBuffer(v->Device, bd->TexTransferBuffer, true);
|
||||||
|
for (int y = 0; y < upload_h; y++)
|
||||||
|
memcpy((void*)((uintptr_t)texture_ptr + y * upload_pitch), tex->GetPixelsAt(upload_x, upload_y + y), upload_pitch);
|
||||||
|
SDL_UnmapGPUTransferBuffer(v->Device, bd->TexTransferBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GPUTextureTransferInfo transfer_info = {};
|
||||||
|
transfer_info.offset = 0;
|
||||||
|
transfer_info.transfer_buffer = bd->TexTransferBuffer;
|
||||||
|
|
||||||
|
SDL_GPUTextureRegion texture_region = {};
|
||||||
|
texture_region.texture = raw_tex;
|
||||||
|
texture_region.x = (Uint32)upload_x;
|
||||||
|
texture_region.y = (Uint32)upload_y;
|
||||||
|
texture_region.w = (Uint32)upload_w;
|
||||||
|
texture_region.h = (Uint32)upload_h;
|
||||||
|
texture_region.d = 1;
|
||||||
|
|
||||||
|
// Upload
|
||||||
|
{
|
||||||
|
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->Device);
|
||||||
|
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||||
|
SDL_UploadToGPUTexture(copy_pass, &transfer_info, &texture_region, false);
|
||||||
|
SDL_EndGPUCopyPass(copy_pass);
|
||||||
|
SDL_SubmitGPUCommandBuffer(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
ImGui_ImplSDLGPU3_DestroyTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDLGPU3_CreateShaders()
|
||||||
|
{
|
||||||
|
// Create the shader modules
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
const char* driver = SDL_GetGPUDeviceDriver(v->Device);
|
||||||
|
|
||||||
|
SDL_GPUShaderCreateInfo vertex_shader_info = {};
|
||||||
|
vertex_shader_info.entrypoint = "main";
|
||||||
|
vertex_shader_info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
|
||||||
|
vertex_shader_info.num_uniform_buffers = 1;
|
||||||
|
vertex_shader_info.num_storage_buffers = 0;
|
||||||
|
vertex_shader_info.num_storage_textures = 0;
|
||||||
|
vertex_shader_info.num_samplers = 0;
|
||||||
|
|
||||||
|
SDL_GPUShaderCreateInfo fragment_shader_info = {};
|
||||||
|
fragment_shader_info.entrypoint = "main";
|
||||||
|
fragment_shader_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
|
||||||
|
fragment_shader_info.num_samplers = 1;
|
||||||
|
fragment_shader_info.num_storage_buffers = 0;
|
||||||
|
fragment_shader_info.num_storage_textures = 0;
|
||||||
|
fragment_shader_info.num_uniform_buffers = 0;
|
||||||
|
|
||||||
|
if (strcmp(driver, "vulkan") == 0)
|
||||||
|
{
|
||||||
|
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||||
|
vertex_shader_info.code = spirv_vertex;
|
||||||
|
vertex_shader_info.code_size = sizeof(spirv_vertex);
|
||||||
|
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||||
|
fragment_shader_info.code = spirv_fragment;
|
||||||
|
fragment_shader_info.code_size = sizeof(spirv_fragment);
|
||||||
|
}
|
||||||
|
else if (strcmp(driver, "direct3d12") == 0)
|
||||||
|
{
|
||||||
|
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||||
|
vertex_shader_info.code = dxbc_vertex;
|
||||||
|
vertex_shader_info.code_size = sizeof(dxbc_vertex);
|
||||||
|
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||||
|
fragment_shader_info.code = dxbc_fragment;
|
||||||
|
fragment_shader_info.code_size = sizeof(dxbc_fragment);
|
||||||
|
}
|
||||||
|
#ifdef __APPLE__
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertex_shader_info.entrypoint = "main0";
|
||||||
|
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||||
|
vertex_shader_info.code = metallib_vertex;
|
||||||
|
vertex_shader_info.code_size = sizeof(metallib_vertex);
|
||||||
|
fragment_shader_info.entrypoint = "main0";
|
||||||
|
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||||
|
fragment_shader_info.code = metallib_fragment;
|
||||||
|
fragment_shader_info.code_size = sizeof(metallib_fragment);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
bd->VertexShader = SDL_CreateGPUShader(v->Device, &vertex_shader_info);
|
||||||
|
bd->FragmentShader = SDL_CreateGPUShader(v->Device, &fragment_shader_info);
|
||||||
|
IM_ASSERT(bd->VertexShader != nullptr && "Failed to create vertex shader, call SDL_GetError() for more information");
|
||||||
|
IM_ASSERT(bd->FragmentShader != nullptr && "Failed to create fragment shader, call SDL_GetError() for more information");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
ImGui_ImplSDLGPU3_CreateShaders();
|
||||||
|
|
||||||
|
SDL_GPUVertexBufferDescription vertex_buffer_desc[1];
|
||||||
|
vertex_buffer_desc[0].slot = 0;
|
||||||
|
vertex_buffer_desc[0].input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX;
|
||||||
|
vertex_buffer_desc[0].instance_step_rate = 0;
|
||||||
|
vertex_buffer_desc[0].pitch = sizeof(ImDrawVert);
|
||||||
|
|
||||||
|
SDL_GPUVertexAttribute vertex_attributes[3];
|
||||||
|
vertex_attributes[0].buffer_slot = 0;
|
||||||
|
vertex_attributes[0].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||||
|
vertex_attributes[0].location = 0;
|
||||||
|
vertex_attributes[0].offset = offsetof(ImDrawVert,pos);
|
||||||
|
|
||||||
|
vertex_attributes[1].buffer_slot = 0;
|
||||||
|
vertex_attributes[1].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||||
|
vertex_attributes[1].location = 1;
|
||||||
|
vertex_attributes[1].offset = offsetof(ImDrawVert, uv);
|
||||||
|
|
||||||
|
vertex_attributes[2].buffer_slot = 0;
|
||||||
|
vertex_attributes[2].format = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM;
|
||||||
|
vertex_attributes[2].location = 2;
|
||||||
|
vertex_attributes[2].offset = offsetof(ImDrawVert, col);
|
||||||
|
|
||||||
|
SDL_GPUVertexInputState vertex_input_state = {};
|
||||||
|
vertex_input_state.num_vertex_attributes = 3;
|
||||||
|
vertex_input_state.vertex_attributes = vertex_attributes;
|
||||||
|
vertex_input_state.num_vertex_buffers = 1;
|
||||||
|
vertex_input_state.vertex_buffer_descriptions = vertex_buffer_desc;
|
||||||
|
|
||||||
|
SDL_GPURasterizerState rasterizer_state = {};
|
||||||
|
rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL;
|
||||||
|
rasterizer_state.cull_mode = SDL_GPU_CULLMODE_NONE;
|
||||||
|
rasterizer_state.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE;
|
||||||
|
rasterizer_state.enable_depth_bias = false;
|
||||||
|
rasterizer_state.enable_depth_clip = false;
|
||||||
|
|
||||||
|
SDL_GPUMultisampleState multisample_state = {};
|
||||||
|
multisample_state.sample_count = v->MSAASamples;
|
||||||
|
multisample_state.enable_mask = false;
|
||||||
|
|
||||||
|
SDL_GPUDepthStencilState depth_stencil_state = {};
|
||||||
|
depth_stencil_state.enable_depth_test = false;
|
||||||
|
depth_stencil_state.enable_depth_write = false;
|
||||||
|
depth_stencil_state.enable_stencil_test = false;
|
||||||
|
|
||||||
|
SDL_GPUColorTargetBlendState blend_state = {};
|
||||||
|
blend_state.enable_blend = true;
|
||||||
|
blend_state.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA;
|
||||||
|
blend_state.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
blend_state.color_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||||
|
blend_state.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE;
|
||||||
|
blend_state.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
|
blend_state.alpha_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||||
|
blend_state.color_write_mask = SDL_GPU_COLORCOMPONENT_R | SDL_GPU_COLORCOMPONENT_G | SDL_GPU_COLORCOMPONENT_B | SDL_GPU_COLORCOMPONENT_A;
|
||||||
|
|
||||||
|
SDL_GPUColorTargetDescription color_target_desc[1];
|
||||||
|
color_target_desc[0].format = v->ColorTargetFormat;
|
||||||
|
color_target_desc[0].blend_state = blend_state;
|
||||||
|
|
||||||
|
SDL_GPUGraphicsPipelineTargetInfo target_info = {};
|
||||||
|
target_info.num_color_targets = 1;
|
||||||
|
target_info.color_target_descriptions = color_target_desc;
|
||||||
|
target_info.has_depth_stencil_target = false;
|
||||||
|
|
||||||
|
SDL_GPUGraphicsPipelineCreateInfo pipeline_info = {};
|
||||||
|
pipeline_info.vertex_shader = bd->VertexShader;
|
||||||
|
pipeline_info.fragment_shader = bd->FragmentShader;
|
||||||
|
pipeline_info.vertex_input_state = vertex_input_state;
|
||||||
|
pipeline_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
|
||||||
|
pipeline_info.rasterizer_state = rasterizer_state;
|
||||||
|
pipeline_info.multisample_state = multisample_state;
|
||||||
|
pipeline_info.depth_stencil_state = depth_stencil_state;
|
||||||
|
pipeline_info.target_info = target_info;
|
||||||
|
|
||||||
|
bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->Device, &pipeline_info);
|
||||||
|
IM_ASSERT(bd->Pipeline != nullptr && "Failed to create graphics pipeline, call SDL_GetError() for more information");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
if (bd->TexSampler == nullptr)
|
||||||
|
{
|
||||||
|
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||||
|
SDL_GPUSamplerCreateInfo sampler_info = {};
|
||||||
|
sampler_info.min_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
|
sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
|
sampler_info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
|
||||||
|
sampler_info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_info.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_info.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||||
|
sampler_info.mip_lod_bias = 0.0f;
|
||||||
|
sampler_info.min_lod = -1000.0f;
|
||||||
|
sampler_info.max_lod = 1000.0f;
|
||||||
|
sampler_info.enable_anisotropy = false;
|
||||||
|
sampler_info.max_anisotropy = 1.0f;
|
||||||
|
sampler_info.enable_compare = false;
|
||||||
|
|
||||||
|
bd->TexSampler = SDL_CreateGPUSampler(v->Device, &sampler_info);
|
||||||
|
IM_ASSERT(bd->TexSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_CreateGraphicsPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_DestroyFrameData()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||||
|
SDL_ReleaseGPUBuffer(v->Device, fd->VertexBuffer);
|
||||||
|
SDL_ReleaseGPUBuffer(v->Device, fd->IndexBuffer);
|
||||||
|
SDL_ReleaseGPUTransferBuffer(v->Device, fd->VertexTransferBuffer);
|
||||||
|
SDL_ReleaseGPUTransferBuffer(v->Device, fd->IndexTransferBuffer);
|
||||||
|
fd->VertexBuffer = fd->IndexBuffer = nullptr;
|
||||||
|
fd->VertexTransferBuffer = fd->IndexTransferBuffer = nullptr;
|
||||||
|
fd->VertexBufferSize = fd->IndexBufferSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||||
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplSDLGPU3_DestroyTexture(tex);
|
||||||
|
if (bd->TexTransferBuffer) { SDL_ReleaseGPUTransferBuffer(v->Device, bd->TexTransferBuffer); bd->TexTransferBuffer = nullptr; }
|
||||||
|
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->Device, bd->VertexShader); bd->VertexShader = nullptr; }
|
||||||
|
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->Device, bd->FragmentShader); bd->FragmentShader = nullptr; }
|
||||||
|
if (bd->TexSampler) { SDL_ReleaseGPUSampler(v->Device, bd->TexSampler); bd->TexSampler = nullptr; }
|
||||||
|
if (bd->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)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = IM_NEW(ImGui_ImplSDLGPU3_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
||||||
|
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_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
|
IM_ASSERT(info->Device != nullptr);
|
||||||
|
IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
|
||||||
|
|
||||||
|
bd->InitInfo = *info;
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_InitMultiViewportSupport();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
|
||||||
|
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplSDLGPU3_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLGPU3_Init()?");
|
||||||
|
|
||||||
|
if (!bd->TexSampler)
|
||||||
|
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);
|
||||||
|
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
|
||||||
63
backends/imgui_impl_sdlgpu3.h
Normal file
63
backends/imgui_impl_sdlgpu3.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// dear imgui: Renderer Backend for SDL_GPU
|
||||||
|
// This needs to be used along with the SDL3 Platform Backend
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
|
// 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/
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||||
|
// - Unlike other backends, the user must call the function ImGui_ImplSDLGPU_PrepareDrawData BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData.
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include <SDL3/SDL_gpu.h>
|
||||||
|
|
||||||
|
// Initialization data, for ImGui_ImplSDLGPU_Init()
|
||||||
|
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
|
||||||
|
struct ImGui_ImplSDLGPU3_InitInfo
|
||||||
|
{
|
||||||
|
SDL_GPUDevice* Device = nullptr;
|
||||||
|
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||||
|
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLGPU3_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplSDLGPU3_RenderState
|
||||||
|
{
|
||||||
|
SDL_GPUDevice* Device;
|
||||||
|
SDL_GPUSampler* SamplerDefault; // Default sampler (bilinear filtering)
|
||||||
|
SDL_GPUSampler* SamplerCurrent; // Current sampler (may be changed by callback)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
372
backends/imgui_impl_sdlgpu3_shaders.h
Normal file
372
backends/imgui_impl_sdlgpu3_shaders.h
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Data exported using
|
||||||
|
// misc/fonts/binary_to_compressed_c.exe -u8 -nocompress filename symbolname >filename.h
|
||||||
|
// With some manual pasting.
|
||||||
|
|
||||||
|
// Check sdlgpu3/ folder for the shaders' source code and instruction on how to build them
|
||||||
|
const uint8_t spirv_vertex[1732] = {
|
||||||
|
3,2,35,7,0,0,1,0,11,0,13,0,55,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,10,0,0,0,0,0,4,0,0,0,109,
|
||||||
|
97,105,110,0,0,0,0,11,0,0,0,15,0,0,0,21,0,0,0,30,0,0,0,31,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,
|
||||||
|
95,100,105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,
|
||||||
|
0,0,0,5,0,3,0,9,0,0,0,0,0,0,0,6,0,5,0,9,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,9,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,11,0,0,0,79,117,116,0,5,0,4,0,15,0,0,0,97,67,111,108,111,114,
|
||||||
|
0,0,5,0,3,0,21,0,0,0,97,85,86,0,5,0,6,0,28,0,0,0,103,108,95,80,101,114,86,101,114,116,101,120,0,0,0,0,6,0,6,0,28,0,0,0,0,0,0,0,103,108,95,80,111,115,105,116,105,111,110,0,6,0,7,0,28,
|
||||||
|
0,0,0,1,0,0,0,103,108,95,80,111,105,110,116,83,105,122,101,0,0,0,0,6,0,7,0,28,0,0,0,2,0,0,0,103,108,95,67,108,105,112,68,105,115,116,97,110,99,101,0,6,0,7,0,28,0,0,0,3,0,0,0,103,108,
|
||||||
|
95,67,117,108,108,68,105,115,116,97,110,99,101,0,5,0,3,0,30,0,0,0,0,0,0,0,5,0,4,0,31,0,0,0,97,80,111,115,0,0,0,0,5,0,6,0,33,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,
|
||||||
|
0,0,6,0,5,0,33,0,0,0,0,0,0,0,117,83,99,97,108,101,0,0,6,0,6,0,33,0,0,0,1,0,0,0,117,84,114,97,110,115,108,97,116,101,0,0,5,0,3,0,35,0,0,0,112,99,0,0,71,0,4,0,11,0,0,0,30,0,0,0,0,0,0,
|
||||||
|
0,71,0,4,0,15,0,0,0,30,0,0,0,2,0,0,0,71,0,4,0,21,0,0,0,30,0,0,0,1,0,0,0,71,0,3,0,28,0,0,0,2,0,0,0,72,0,5,0,28,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,72,0,5,0,28,0,0,0,1,0,0,0,11,0,0,0,1,0,
|
||||||
|
0,0,72,0,5,0,28,0,0,0,2,0,0,0,11,0,0,0,3,0,0,0,72,0,5,0,28,0,0,0,3,0,0,0,11,0,0,0,4,0,0,0,71,0,4,0,31,0,0,0,30,0,0,0,0,0,0,0,71,0,3,0,33,0,0,0,2,0,0,0,72,0,5,0,33,0,0,0,0,0,0,0,35,
|
||||||
|
0,0,0,0,0,0,0,72,0,5,0,33,0,0,0,1,0,0,0,35,0,0,0,8,0,0,0,71,0,4,0,35,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,35,0,0,0,34,0,0,0,1,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,
|
||||||
|
0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,23,0,4,0,8,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,9,0,0,0,7,0,0,0,8,0,0,0,32,0,4,0,10,0,0,0,3,0,0,0,9,0,0,0,59,0,4,0,10,0,0,0,11,0,0,0,3,0,0,
|
||||||
|
0,21,0,4,0,12,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,12,0,0,0,13,0,0,0,0,0,0,0,32,0,4,0,14,0,0,0,1,0,0,0,7,0,0,0,59,0,4,0,14,0,0,0,15,0,0,0,1,0,0,0,32,0,4,0,17,0,0,0,3,0,0,0,7,0,0,0,43,0,
|
||||||
|
4,0,12,0,0,0,19,0,0,0,1,0,0,0,32,0,4,0,20,0,0,0,1,0,0,0,8,0,0,0,59,0,4,0,20,0,0,0,21,0,0,0,1,0,0,0,32,0,4,0,23,0,0,0,3,0,0,0,8,0,0,0,21,0,4,0,25,0,0,0,32,0,0,0,0,0,0,0,43,0,4,0,25,
|
||||||
|
0,0,0,26,0,0,0,1,0,0,0,28,0,4,0,27,0,0,0,6,0,0,0,26,0,0,0,30,0,6,0,28,0,0,0,7,0,0,0,6,0,0,0,27,0,0,0,27,0,0,0,32,0,4,0,29,0,0,0,3,0,0,0,28,0,0,0,59,0,4,0,29,0,0,0,30,0,0,0,3,0,0,0,
|
||||||
|
59,0,4,0,20,0,0,0,31,0,0,0,1,0,0,0,30,0,4,0,33,0,0,0,8,0,0,0,8,0,0,0,32,0,4,0,34,0,0,0,2,0,0,0,33,0,0,0,59,0,4,0,34,0,0,0,35,0,0,0,2,0,0,0,32,0,4,0,36,0,0,0,2,0,0,0,8,0,0,0,43,0,4,
|
||||||
|
0,6,0,0,0,43,0,0,0,0,0,0,0,43,0,4,0,6,0,0,0,44,0,0,0,0,0,128,63,43,0,4,0,6,0,0,0,49,0,0,0,0,0,128,191,32,0,4,0,50,0,0,0,3,0,0,0,6,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,
|
||||||
|
0,2,0,5,0,0,0,61,0,4,0,7,0,0,0,16,0,0,0,15,0,0,0,65,0,5,0,17,0,0,0,18,0,0,0,11,0,0,0,13,0,0,0,62,0,3,0,18,0,0,0,16,0,0,0,61,0,4,0,8,0,0,0,22,0,0,0,21,0,0,0,65,0,5,0,23,0,0,0,24,0,0,
|
||||||
|
0,11,0,0,0,19,0,0,0,62,0,3,0,24,0,0,0,22,0,0,0,61,0,4,0,8,0,0,0,32,0,0,0,31,0,0,0,65,0,5,0,36,0,0,0,37,0,0,0,35,0,0,0,13,0,0,0,61,0,4,0,8,0,0,0,38,0,0,0,37,0,0,0,133,0,5,0,8,0,0,0,
|
||||||
|
39,0,0,0,32,0,0,0,38,0,0,0,65,0,5,0,36,0,0,0,40,0,0,0,35,0,0,0,19,0,0,0,61,0,4,0,8,0,0,0,41,0,0,0,40,0,0,0,129,0,5,0,8,0,0,0,42,0,0,0,39,0,0,0,41,0,0,0,81,0,5,0,6,0,0,0,45,0,0,0,42,
|
||||||
|
0,0,0,0,0,0,0,81,0,5,0,6,0,0,0,46,0,0,0,42,0,0,0,1,0,0,0,80,0,7,0,7,0,0,0,47,0,0,0,45,0,0,0,46,0,0,0,43,0,0,0,44,0,0,0,65,0,5,0,17,0,0,0,48,0,0,0,30,0,0,0,13,0,0,0,62,0,3,0,48,0,0,
|
||||||
|
0,47,0,0,0,65,0,6,0,50,0,0,0,51,0,0,0,30,0,0,0,13,0,0,0,26,0,0,0,61,0,4,0,6,0,0,0,52,0,0,0,51,0,0,0,133,0,5,0,6,0,0,0,53,0,0,0,52,0,0,0,49,0,0,0,65,0,6,0,50,0,0,0,54,0,0,0,30,0,0,0,
|
||||||
|
13,0,0,0,26,0,0,0,62,0,3,0,54,0,0,0,53,0,0,0,253,0,1,0,56,0,1,0,
|
||||||
|
};
|
||||||
|
const uint8_t spirv_fragment[844] = {
|
||||||
|
3,2,35,7,0,0,1,0,11,0,13,0,30,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,7,0,4,0,0,0,4,0,0,0,109,97,
|
||||||
|
105,110,0,0,0,0,9,0,0,0,13,0,0,0,16,0,3,0,4,0,0,0,7,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,95,100,
|
||||||
|
105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,0,0,0,5,
|
||||||
|
0,4,0,9,0,0,0,102,67,111,108,111,114,0,0,5,0,3,0,11,0,0,0,0,0,0,0,6,0,5,0,11,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,11,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,13,0,0,0,73,110,0,0,5,
|
||||||
|
0,5,0,22,0,0,0,115,84,101,120,116,117,114,101,0,0,0,0,71,0,4,0,9,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,13,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,34,0,
|
||||||
|
0,0,2,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,32,0,4,0,8,0,0,0,3,0,0,0,7,0,0,0,59,0,4,0,8,0,0,0,9,0,0,0,3,0,0,0,23,
|
||||||
|
0,4,0,10,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,11,0,0,0,7,0,0,0,10,0,0,0,32,0,4,0,12,0,0,0,1,0,0,0,11,0,0,0,59,0,4,0,12,0,0,0,13,0,0,0,1,0,0,0,21,0,4,0,14,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,
|
||||||
|
14,0,0,0,15,0,0,0,0,0,0,0,32,0,4,0,16,0,0,0,1,0,0,0,7,0,0,0,25,0,9,0,19,0,0,0,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,27,0,3,0,20,0,0,0,19,0,0,0,32,0,4,0,21,0,0,0,0,
|
||||||
|
0,0,0,20,0,0,0,59,0,4,0,21,0,0,0,22,0,0,0,0,0,0,0,43,0,4,0,14,0,0,0,24,0,0,0,1,0,0,0,32,0,4,0,25,0,0,0,1,0,0,0,10,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,0,2,0,5,0,0,0,65,
|
||||||
|
0,5,0,16,0,0,0,17,0,0,0,13,0,0,0,15,0,0,0,61,0,4,0,7,0,0,0,18,0,0,0,17,0,0,0,61,0,4,0,20,0,0,0,23,0,0,0,22,0,0,0,65,0,5,0,25,0,0,0,26,0,0,0,13,0,0,0,24,0,0,0,61,0,4,0,10,0,0,0,27,0,
|
||||||
|
0,0,26,0,0,0,87,0,5,0,7,0,0,0,28,0,0,0,23,0,0,0,27,0,0,0,133,0,5,0,7,0,0,0,29,0,0,0,18,0,0,0,28,0,0,0,62,0,3,0,9,0,0,0,29,0,0,0,253,0,1,0,56,0,1,0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t dxbc_vertex[1064] = {
|
||||||
|
68,88,66,67,32,50,127,204,241,196,165,104,216,114,216,116,220,164,29,45,1,0,0,0,40,4,0,0,5,0,0,0,52,0,0,0,136,1,0,0,236,1,0,0,92,2,0,0,140,3,0,0,82,68,69,70,76,1,0,0,1,0,0,0,116,0,
|
||||||
|
0,0,1,0,0,0,60,0,0,0,1,5,254,255,0,5,0,0,34,1,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
|
||||||
|
0,1,0,0,0,1,0,0,0,0,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,171,171,100,0,0,0,2,0,0,0,140,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,8,0,0,0,2,0,0,0,240,0,0,
|
||||||
|
0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,20,1,0,0,8,0,0,0,8,0,0,0,2,0,0,0,240,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,112,99,95,117,83,99,97,
|
||||||
|
108,101,0,102,108,111,97,116,50,0,171,171,171,1,0,3,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,112,99,95,117,84,114,97,110,115,108,97,116,101,0,77,105,99,114,
|
||||||
|
111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,171,73,83,71,78,92,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,3,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,80,0,0,0,2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,15,15,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,
|
||||||
|
71,78,104,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,12,0,0,89,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,15,0,0,
|
||||||
|
0,84,69,88,67,79,79,82,68,0,83,86,95,80,111,115,105,116,105,111,110,0,171,171,171,83,72,69,88,40,1,0,0,81,0,1,0,74,0,0,0,106,8,0,1,89,0,0,7,70,142,48,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
|
||||||
|
0,0,1,0,0,0,95,0,0,3,50,16,16,0,0,0,0,0,95,0,0,3,50,16,16,0,1,0,0,0,95,0,0,3,242,16,16,0,2,0,0,0,101,0,0,3,242,32,16,0,0,0,0,0,101,0,0,3,50,32,16,0,1,0,0,0,103,0,0,4,242,32,16,0,2,
|
||||||
|
0,0,0,1,0,0,0,104,0,0,2,1,0,0,0,50,0,0,13,50,0,16,0,0,0,0,0,70,16,16,0,0,0,0,0,70,128,48,0,0,0,0,0,0,0,0,0,0,0,0,0,230,138,48,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,6,34,32,16,0,2,0,0,0,
|
||||||
|
26,0,16,128,65,0,0,0,0,0,0,0,54,0,0,5,242,32,16,0,0,0,0,0,70,30,16,0,2,0,0,0,54,0,0,5,18,32,16,0,2,0,0,0,10,0,16,0,0,0,0,0,54,0,0,8,194,32,16,0,2,0,0,0,2,64,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,128,63,54,0,0,5,50,32,16,0,1,0,0,0,70,16,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,6,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
const uint8_t dxbc_fragment[744] = {
|
||||||
|
68,88,66,67,235,219,43,109,38,151,39,223,98,41,193,28,215,98,67,110,1,0,0,0,232,2,0,0,5,0,0,0,52,0,0,0,12,1,0,0,88,1,0,0,140,1,0,0,76,2,0,0,82,68,69,70,208,0,0,0,0,0,0,0,0,0,0,0,2,
|
||||||
|
0,0,0,60,0,0,0,1,5,255,255,0,5,0,0,167,0,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,140,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
|
||||||
|
0,0,2,0,0,0,0,0,0,0,158,0,0,0,2,0,0,0,5,0,0,0,4,0,0,0,255,255,255,255,0,0,0,0,1,0,0,0,12,0,0,0,2,0,0,0,0,0,0,0,95,115,84,101,120,116,117,114,101,95,115,97,109,112,108,101,114,0,115,
|
||||||
|
84,101,120,116,117,114,101,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,73,83,71,78,
|
||||||
|
68,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,15,0,0,56,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,71,78,44,0,
|
||||||
|
0,0,1,0,0,0,8,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,83,86,95,84,97,114,103,101,116,0,171,171,83,72,69,88,184,0,0,0,81,0,0,0,46,0,0,0,106,8,0,1,90,0,0,6,70,110,48,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,88,24,0,7,70,126,48,0,0,0,0,0,0,0,0,0,0,0,0,0,85,85,0,0,2,0,0,0,98,16,0,3,242,16,16,0,0,0,0,0,98,16,0,3,50,16,16,0,1,0,0,0,101,0,0,3,242,32,16,0,0,
|
||||||
|
0,0,0,104,0,0,2,1,0,0,0,69,0,0,11,242,0,16,0,0,0,0,0,70,16,16,0,1,0,0,0,70,126,32,0,0,0,0,0,0,0,0,0,0,96,32,0,0,0,0,0,0,0,0,0,56,0,0,7,242,32,16,0,0,0,0,0,70,14,16,0,0,0,0,0,70,30,
|
||||||
|
16,0,0,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
#if TARGET_OS_MAC
|
||||||
|
const uint8_t metallib_vertex[3892] = {
|
||||||
|
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,52,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,32,
|
||||||
|
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,62,81,190,157,8,240,236,158,164,213,65,62,170,226,96,136,231,243,238,160,100,
|
||||||
|
26,13,254,254,64,19,129,180,3,149,75,77,68,83,90,8,0,32,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,84,
|
||||||
|
69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,
|
||||||
|
11,0,0,0,0,20,0,0,0,8,14,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,74,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,
|
||||||
|
6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,
|
||||||
|
32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,32,
|
||||||
|
36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,34,
|
||||||
|
8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,
|
||||||
|
192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,
|
||||||
|
202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||||
|
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||||
|
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||||
|
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||||
|
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||||
|
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,176,112,72,
|
||||||
|
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,
|
||||||
|
208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,
|
||||||
|
160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,
|
||||||
|
7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,
|
||||||
|
246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,
|
||||||
|
6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,
|
||||||
|
32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,160,48,0,0,8,0,0,0,4,0,0,0,0,0,10,64,98,131,64,81,166,1,0,128,44,16,0,11,0,0,0,50,30,152,16,25,17,
|
||||||
|
76,144,140,9,38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,98,24,1,40,3,218,17,0,210,177,132,39,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,
|
||||||
|
67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,
|
||||||
|
120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,
|
||||||
|
97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,
|
||||||
|
135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,
|
||||||
|
29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,
|
||||||
|
7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,
|
||||||
|
29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,
|
||||||
|
30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,
|
||||||
|
129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,
|
||||||
|
212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,
|
||||||
|
14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,
|
||||||
|
7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,
|
||||||
|
248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,26,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,
|
||||||
|
6,100,208,82,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,
|
||||||
|
97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,
|
||||||
|
95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,
|
||||||
|
97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,
|
||||||
|
112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,
|
||||||
|
56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,
|
||||||
|
116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,
|
||||||
|
97,105,114,46,118,101,114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,
|
||||||
|
116,52,97,105,114,46,97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,
|
||||||
|
111,115,105,116,105,111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,
|
||||||
|
110,100,101,120,97,80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,
|
||||||
|
97,105,114,46,97,100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,
|
||||||
|
108,97,116,101,97,105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,
|
||||||
|
67,111,110,115,116,97,110,116,112,99,0,0,0,166,119,0,0,0,0,0,0,48,130,144,4,35,8,74,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,
|
||||||
|
144,40,35,8,201,50,130,112,0,51,12,106,16,172,193,12,3,27,8,109,48,195,224,6,131,26,204,48,184,1,241,6,51,12,110,80,188,193,12,131,27,24,111,48,195,224,6,7,28,204,48,184,1,18,7,51,
|
||||||
|
12,110,144,200,193,12,129,50,195,160,6,115,64,7,51,16,75,29,176,1,29,204,16,48,51,4,205,12,129,51,131,241,64,145,52,81,51,24,79,21,89,211,53,67,129,69,210,148,205,48,152,194,41,160,
|
||||||
|
194,12,9,29,104,27,29,176,65,100,77,220,12,9,27,104,27,27,176,65,100,77,221,12,137,26,104,155,26,176,65,36,77,222,12,10,29,196,1,29,88,100,16,7,113,64,7,86,25,204,64,213,193,7,6,114,
|
||||||
|
176,209,1,27,132,129,24,168,193,24,180,130,25,200,193,25,196,65,132,6,83,26,204,64,168,194,42,176,130,43,204,48,216,65,42,188,194,157,1,192,113,28,199,113,28,199,113,28,199,185,129,
|
||||||
|
27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,22,29,208,129,27,208,1,46,224,2,46,240,3,122,128,130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,
|
||||||
|
185,81,18,59,184,3,60,200,3,61,216,3,62,232,3,63,72,133,141,205,174,205,37,141,172,204,141,110,148,224,15,114,9,75,147,115,177,43,147,155,75,123,115,27,37,0,133,164,194,210,228,92,
|
||||||
|
216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,66,33,167,176,52,57,151,177,183,54,184,52,182,178,175,55,56,186,180,55,183,185,81,6,81,24,5,82,72,37,44,77,206,
|
||||||
|
197,174,76,142,174,12,111,148,224,21,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,
|
||||||
|
29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,
|
||||||
|
195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,
|
||||||
|
15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,180,37,
|
||||||
|
64,61,7,161,72,146,52,7,161,72,9,65,48,26,48,2,48,70,0,130,32,136,127,20,115,16,150,117,97,36,163,1,52,51,0,0,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,
|
||||||
|
0,111,109,110,105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,
|
||||||
|
110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,133,89,33,216,194,44,172,24,110,193,22,104,97,67,32,11,27,134,88,192,133,90,216,48,228,
|
||||||
|
66,46,212,194,134,224,22,0,0,157,134,5,146,40,16,130,1,36,254,157,6,103,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,204,5,204,54,4,89,
|
||||||
|
48,219,16,12,194,6,1,49,0,4,0,0,0,91,138,32,200,133,67,23,182,20,68,144,11,135,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,134,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,
|
||||||
|
240,0,0,0,0,3,0,0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,13,0,0,0,18,3,148,102,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,
|
||||||
|
52,45,97,112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
const uint8_t metallib_fragment[3787] = {
|
||||||
|
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,203,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,
|
||||||
|
224,13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,201,103,233,140,10,95,185,107,79,93,85,82,78,218,248,8,95,184,8,139,191,
|
||||||
|
155,174,56,51,95,203,135,255,117,44,62,77,68,83,90,8,0,224,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,
|
||||||
|
84,69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,196,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,
|
||||||
|
12,0,0,44,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||||
|
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||||
|
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||||
|
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||||
|
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||||
|
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||||
|
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||||
|
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||||
|
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||||
|
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||||
|
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||||
|
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||||
|
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,176,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,
|
||||||
|
135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,
|
||||||
|
118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,
|
||||||
|
96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,
|
||||||
|
6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,
|
||||||
|
7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,
|
||||||
|
7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,
|
||||||
|
160,64,0,0,8,0,0,0,4,0,0,0,0,0,10,96,72,85,108,15,16,0,2,0,0,128,0,0,0,0,0,64,1,72,108,16,40,234,50,0,0,144,5,2,0,0,0,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,
|
||||||
|
80,2,133,80,14,229,83,128,2,5,81,32,197,48,2,80,6,36,199,18,158,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,
|
||||||
|
230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,
|
||||||
|
112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,
|
||||||
|
188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,
|
||||||
|
152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,
|
||||||
|
57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,
|
||||||
|
0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,
|
||||||
|
36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,
|
||||||
|
59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,
|
||||||
|
65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,
|
||||||
|
135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,
|
||||||
|
23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,
|
||||||
|
14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,
|
||||||
|
32,0,0,252,0,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,
|
||||||
|
6,81,100,48,134,180,40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,
|
||||||
|
97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,
|
||||||
|
46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,
|
||||||
|
101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,
|
||||||
|
114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,
|
||||||
|
101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,
|
||||||
|
112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,
|
||||||
|
46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,
|
||||||
|
116,95,105,110,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,
|
||||||
|
111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,
|
||||||
|
100,101,120,97,105,114,46,115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,
|
||||||
|
46,115,97,109,112,108,101,114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,198,96,0,0,0,0,0,0,48,130,208,8,35,8,82,51,130,208,12,35,8,13,49,130,208,
|
||||||
|
20,35,8,141,49,130,208,28,35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,13,51,130,144,0,51,12,100,16,148,193,12,131,25,8,103,48,195,128,6,3,25,204,48,160,1,145,6,51,12,104,80,164,
|
||||||
|
193,12,3,26,24,105,48,195,128,6,135,26,204,48,160,1,178,6,51,12,104,144,176,193,12,129,50,195,64,6,109,224,6,51,16,203,27,152,129,27,204,16,48,51,4,205,12,129,51,195,241,184,129,27,
|
||||||
|
64,145,52,205,16,128,194,12,137,27,80,149,117,65,145,132,205,144,152,1,149,89,23,164,73,219,12,10,25,112,157,27,152,129,7,125,18,24,204,144,188,65,24,116,110,96,6,144,24,72,99,48,3,
|
||||||
|
33,10,163,64,10,165,48,195,0,7,161,96,10,71,6,0,199,113,28,199,113,28,199,113,28,231,6,110,224,6,110,224,6,110,224,6,110,224,6,22,29,232,129,101,89,166,192,177,2,43,144,131,58,128,
|
||||||
|
130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,185,81,18,56,136,3,57,152,3,58,168,3,59,184,3,60,72,133,141,205,174,205,37,141,172,204,141,110,148,32,15,
|
||||||
|
114,9,75,147,115,177,43,147,155,75,123,115,27,37,208,131,164,194,210,228,92,216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,246,32,167,176,52,57,151,177,183,54,
|
||||||
|
184,52,182,178,175,55,56,186,180,55,183,185,81,6,62,232,3,63,72,38,44,77,206,197,76,46,236,172,173,204,141,110,148,192,20,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,
|
||||||
|
88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,
|
||||||
|
80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,
|
||||||
|
28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,
|
||||||
|
67,56,144,195,1,0,0,0,97,32,0,0,49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,
|
||||||
|
97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,
|
||||||
|
45,97,108,105,97,115,45,115,99,111,112,101,45,116,101,120,116,117,114,101,115,0,43,132,85,64,133,21,3,43,172,66,42,172,24,90,97,21,84,97,131,208,10,172,0,0,35,6,205,16,130,96,240,88,
|
||||||
|
135,129,20,3,33,8,204,104,66,0,96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,104,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,251,5,0,0,0,0,0,0,0,0,101,12,0,0,37,
|
||||||
|
0,0,0,18,3,148,40,1,0,0,0,3,0,0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,20,0,0,0,18,3,
|
||||||
|
148,161,0,0,0,0,109,97,105,110,48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,
|
||||||
|
112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
#elif TARGET_OS_IPHONE
|
||||||
|
const uint8_t metallib_vertex[3876] = {
|
||||||
|
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,36,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,16,
|
||||||
|
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,240,54,230,217,232,66,102,78,35,5,77,235,101,252,229,192,148,96,126,162,111,
|
||||||
|
77,253,247,211,52,17,198,182,137,68,244,77,68,83,90,8,0,16,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,
|
||||||
|
84,69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,
|
||||||
|
23,11,0,0,0,0,20,0,0,0,252,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,72,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,
|
||||||
|
4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,
|
||||||
|
136,32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,
|
||||||
|
32,36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,
|
||||||
|
34,8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,
|
||||||
|
218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,
|
||||||
|
29,202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||||
|
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||||
|
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||||
|
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||||
|
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||||
|
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,170,112,72,
|
||||||
|
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,
|
||||||
|
113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,
|
||||||
|
96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,
|
||||||
|
7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,
|
||||||
|
121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,
|
||||||
|
80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,
|
||||||
|
224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,3,0,128,0,0,0,64,0,0,0,0,0,160,0,36,54,8,20,85,26,0,0,200,2,1,0,11,0,0,0,50,30,152,16,25,17,76,144,140,9,
|
||||||
|
38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,17,128,50,160,29,1,32,29,75,144,2,0,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,
|
||||||
|
140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,
|
||||||
|
7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,
|
||||||
|
59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,
|
||||||
|
8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,
|
||||||
|
67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,
|
||||||
|
135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,
|
||||||
|
81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,
|
||||||
|
29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,
|
||||||
|
192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,
|
||||||
|
113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,
|
||||||
|
35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,
|
||||||
|
119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,
|
||||||
|
119,168,7,120,152,7,0,0,0,0,121,32,0,0,25,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,6,100,208,82,0,0,0,139,
|
||||||
|
210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,
|
||||||
|
101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,
|
||||||
|
97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,
|
||||||
|
116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,
|
||||||
|
65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,
|
||||||
|
108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,
|
||||||
|
95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,118,101,
|
||||||
|
114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,
|
||||||
|
97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,111,115,105,116,105,
|
||||||
|
111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,
|
||||||
|
80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,97,105,114,46,97,
|
||||||
|
100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,108,97,116,101,97,
|
||||||
|
105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,67,111,110,115,116,
|
||||||
|
97,110,116,112,99,0,0,0,230,117,0,0,0,0,0,0,48,130,144,4,35,8,10,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,144,40,35,8,7,48,195,
|
||||||
|
160,6,193,26,204,48,176,129,208,6,51,12,110,48,168,193,12,131,27,16,111,48,195,224,6,197,27,204,48,184,129,241,6,51,12,110,112,192,193,12,131,27,32,113,48,195,224,6,137,28,204,16,40,
|
||||||
|
51,12,106,224,6,115,48,3,177,208,129,26,204,193,12,1,51,67,208,204,16,56,51,24,15,20,73,19,53,131,241,84,145,53,93,51,20,88,36,77,217,12,67,41,152,194,41,204,144,204,129,182,205,1,
|
||||||
|
27,68,214,196,205,144,176,129,182,177,1,27,68,214,212,205,144,168,129,182,169,1,27,68,210,228,205,160,204,65,28,204,129,69,6,113,16,7,115,96,149,193,12,20,29,124,96,32,7,219,28,176,
|
||||||
|
65,24,136,129,26,140,1,43,152,129,28,156,65,28,68,104,48,165,193,12,68,42,168,194,42,180,194,12,67,29,160,130,43,156,25,0,28,199,113,28,199,113,28,199,113,110,224,6,110,224,6,110,224,
|
||||||
|
6,110,224,6,110,96,209,129,30,88,150,69,7,116,224,6,116,128,11,184,128,11,252,128,30,160,32,35,129,9,202,136,141,205,174,205,165,237,141,172,142,173,204,197,140,45,236,108,110,148,
|
||||||
|
164,14,236,224,14,240,32,15,244,96,15,248,160,15,82,97,99,179,107,115,73,35,43,115,163,27,37,240,131,92,194,210,228,92,236,202,228,230,210,222,220,70,9,254,32,169,176,52,57,23,182,
|
||||||
|
48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,80,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,205,109,110,148,33,20,68,97,20,82,9,75,147,115,177,
|
||||||
|
43,147,163,43,195,27,37,112,5,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,
|
||||||
|
33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,
|
||||||
|
180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,
|
||||||
|
128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,197,64,91,2,212,
|
||||||
|
115,16,73,20,69,115,16,73,36,17,4,163,1,35,0,99,4,32,8,130,248,71,49,7,97,89,23,70,50,26,64,51,3,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,0,111,109,110,
|
||||||
|
105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,
|
||||||
|
105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,101,89,33,212,130,44,172,24,108,161,22,102,97,67,16,11,27,6,88,184,5,90,216,48,224,2,46,208,194,134,
|
||||||
|
192,22,0,0,157,6,38,154,40,16,130,65,36,254,157,134,135,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,12,6,204,54,4,90,48,219,16,12,194,
|
||||||
|
6,1,49,0,4,0,0,0,91,138,32,192,133,35,23,182,20,68,128,11,71,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,132,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,240,0,0,0,0,3,0,
|
||||||
|
0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,12,0,0,0,18,3,148,99,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,
|
||||||
|
108,101,45,105,111,115,49,56,46,49,46,48,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
const uint8_t metallib_fragment[3771] = {
|
||||||
|
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,187,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,208,
|
||||||
|
13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,167,26,51,31,140,153,203,226,66,149,243,47,185,58,96,202,28,176,71,121,86,159,
|
||||||
|
244,234,235,69,155,58,121,67,241,212,77,68,83,90,8,0,208,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,84,
|
||||||
|
69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,180,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,
|
||||||
|
0,0,41,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||||
|
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||||
|
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||||
|
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||||
|
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||||
|
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||||
|
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||||
|
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||||
|
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||||
|
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||||
|
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||||
|
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||||
|
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,170,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,
|
||||||
|
56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,
|
||||||
|
118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,
|
||||||
|
122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,
|
||||||
|
128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,
|
||||||
|
160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,
|
||||||
|
7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,4,0,128,
|
||||||
|
0,0,0,64,0,0,0,0,0,160,0,134,84,197,246,0,1,32,0,0,0,8,0,0,0,0,0,20,128,196,6,129,162,43,3,0,0,89,32,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,80,2,133,80,14,229,
|
||||||
|
83,128,2,5,81,32,35,0,101,64,114,44,65,10,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,
|
||||||
|
128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,
|
||||||
|
135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,
|
||||||
|
240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,
|
||||||
|
238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,
|
||||||
|
56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,
|
||||||
|
144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,
|
||||||
|
7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,
|
||||||
|
57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,
|
||||||
|
225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,
|
||||||
|
96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,
|
||||||
|
29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,
|
||||||
|
14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,251,0,0,0,114,
|
||||||
|
30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,81,100,48,134,180,
|
||||||
|
40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,
|
||||||
|
97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,
|
||||||
|
104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,
|
||||||
|
105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,
|
||||||
|
51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,
|
||||||
|
95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,
|
||||||
|
97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,46,97,114,103,95,116,121,
|
||||||
|
112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,116,95,105,110,112,117,116,
|
||||||
|
117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,111,114,117,115,101,114,40,
|
||||||
|
108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,105,114,46,
|
||||||
|
115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,46,115,97,109,112,108,101,
|
||||||
|
114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,6,95,0,0,0,0,0,0,48,130,208,8,35,8,18,51,130,208,12,35,8,13,49,130,208,20,35,8,141,49,130,208,28,
|
||||||
|
35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,9,48,195,64,6,65,25,204,48,152,129,112,6,51,12,104,48,144,193,12,3,26,16,105,48,195,128,6,69,26,204,48,160,129,145,6,51,12,104,112,
|
||||||
|
168,193,12,3,26,32,107,48,195,128,6,9,27,204,16,40,51,12,100,128,6,109,48,3,177,184,1,25,180,193,12,1,51,67,208,204,16,56,51,28,79,27,180,1,20,73,211,12,193,31,204,144,180,1,85,89,
|
||||||
|
23,20,73,216,12,137,25,80,153,117,65,154,180,205,160,144,1,215,181,129,25,120,208,39,129,193,12,137,27,132,65,215,6,102,0,137,129,52,6,51,16,161,32,10,163,64,10,51,12,111,0,10,165,
|
||||||
|
112,99,0,112,28,199,113,28,199,113,28,199,185,129,27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,150,41,112,172,192,10,228,160,14,160,32,35,129,9,202,136,141,205,174,205,
|
||||||
|
165,237,141,172,142,173,204,197,140,45,236,108,110,148,228,13,224,32,14,228,96,14,232,160,14,236,224,14,82,97,99,179,107,115,73,35,43,115,163,27,37,192,131,92,194,210,228,92,236,202,
|
||||||
|
228,230,210,222,220,70,9,242,32,169,176,52,57,23,182,48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,61,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,
|
||||||
|
205,109,110,148,97,15,248,160,15,146,9,75,147,115,49,147,11,59,107,43,115,163,27,37,40,5,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,
|
||||||
|
67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,
|
||||||
|
112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,
|
||||||
|
200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,
|
||||||
|
49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,97,105,114,45,97,108,105,97,115,
|
||||||
|
45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,45,97,108,105,97,115,45,115,99,
|
||||||
|
111,112,101,45,116,101,120,116,117,114,101,115,0,43,4,85,56,133,21,195,42,168,2,42,172,24,88,65,21,82,97,131,192,10,171,0,0,35,6,205,16,130,96,240,84,135,129,20,3,33,8,204,104,66,0,
|
||||||
|
96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,96,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,248,5,0,0,0,0,0,0,0,0,101,12,0,0,37,0,0,0,18,3,148,40,1,0,0,0,3,0,
|
||||||
|
0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,19,0,0,0,18,3,148,126,0,0,0,0,109,97,105,110,
|
||||||
|
48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,108,101,45,105,111,115,
|
||||||
|
49,56,46,49,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
};
|
||||||
|
#elif TARGET_IPHONE_SIMULATOR
|
||||||
|
#error "SDL_GPU does not support the iphone simulator"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||||
// (Requires: SDL 2.0.17+)
|
// (Requires: SDL 2.0.17+)
|
||||||
|
|
||||||
// Note how SDL_Renderer is an _optional_ component of SDL2.
|
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
// For a multi-platform app consider using other technologies:
|
||||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||||
// it might be difficult to step out of those boundaries.
|
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||||
|
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||||
|
// and it might be difficult to step out of those boundaries.
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features:
|
// Missing features:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||||
|
|
||||||
@@ -22,6 +26,9 @@
|
|||||||
// - Introduction, links and more at the top of imgui.cpp
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLRenderer2_CreateFontsTexture() and ImGui_ImplSDLRenderer2_DestroyFontsTexture().
|
||||||
|
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||||
|
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||||
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
|
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
@@ -39,6 +46,8 @@
|
|||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
@@ -51,7 +60,7 @@
|
|||||||
struct ImGui_ImplSDLRenderer2_Data
|
struct ImGui_ImplSDLRenderer2_Data
|
||||||
{
|
{
|
||||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||||
SDL_Texture* FontTexture;
|
|
||||||
ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,6 +84,7 @@ bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
io.BackendRendererName = "imgui_impl_sdlrenderer2";
|
io.BackendRendererName = "imgui_impl_sdlrenderer2";
|
||||||
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.
|
||||||
|
|
||||||
bd->Renderer = renderer;
|
bd->Renderer = renderer;
|
||||||
|
|
||||||
@@ -91,44 +101,49 @@ void ImGui_ImplSDLRenderer2_Shutdown()
|
|||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
// 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_RenderSetViewport(renderer, nullptr);
|
SDL_RenderSetViewport(renderer, nullptr);
|
||||||
SDL_RenderSetClipRect(renderer, nullptr);
|
SDL_RenderSetClipRect(renderer, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer2_NewFrame()
|
void ImGui_ImplSDLRenderer2_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer2_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer2_Init()?");
|
||||||
|
IM_UNUSED(bd);
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
// If there's a scale factor set by the user, use that instead
|
// If there's a scale factor set by the user, use that instead
|
||||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||||
float rsx = 1.0f;
|
float rsx = 1.0f;
|
||||||
float rsy = 1.0f;
|
float rsy = 1.0f;
|
||||||
SDL_RenderGetScale(renderer, &rsx, &rsy);
|
SDL_RenderGetScale(renderer, &rsx, &rsy);
|
||||||
ImVec2 render_scale;
|
ImVec2 render_scale;
|
||||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||||
|
|
||||||
// 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 * render_scale.x);
|
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||||
if (fb_width == 0 || fb_height == 0)
|
if (fb_width == 0 || fb_height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplSDLRenderer2_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||||
struct BackupSDLRendererState
|
struct BackupSDLRendererState
|
||||||
@@ -142,21 +157,28 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
SDL_RenderGetViewport(renderer, &old.Viewport);
|
SDL_RenderGetViewport(renderer, &old.Viewport);
|
||||||
SDL_RenderGetClipRect(renderer, &old.ClipRect);
|
SDL_RenderGetClipRect(renderer, &old.ClipRect);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Setup desired state
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||||
ImVec2 clip_scale = render_scale;
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplSDLRenderer2_RenderState render_state;
|
||||||
|
render_state.Renderer = renderer;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||||
|
ImVec2 clip_scale = render_scale;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -164,7 +186,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -190,71 +212,84 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||||
SDL_RenderGeometryRaw(renderer, tex,
|
SDL_RenderGeometryRaw(renderer, tex,
|
||||||
xy, (int)sizeof(ImDrawVert),
|
xy, (int)sizeof(ImDrawVert),
|
||||||
color, (int)sizeof(ImDrawVert),
|
color, (int)sizeof(ImDrawVert),
|
||||||
uv, (int)sizeof(ImDrawVert),
|
uv, (int)sizeof(ImDrawVert),
|
||||||
cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
|
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
|
|
||||||
// Restore modified SDL_Renderer state
|
// Restore modified SDL_Renderer state
|
||||||
SDL_RenderSetViewport(renderer, &old.Viewport);
|
SDL_RenderSetViewport(renderer, &old.Viewport);
|
||||||
SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
void ImGui_ImplSDLRenderer2_UpdateTexture(ImTextureData* tex)
|
||||||
bool ImGui_ImplSDLRenderer2_CreateFontsTexture()
|
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||||
|
|
||||||
// Build texture atlas
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
|
||||||
if (bd->FontTexture == nullptr)
|
|
||||||
{
|
{
|
||||||
SDL_Log("error creating texture");
|
// Create and upload new texture to graphics system
|
||||||
return false;
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
// (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);
|
||||||
|
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
||||||
|
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
||||||
|
SDL_SetTextureBlendMode(sdl_texture, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_SetTextureScaleMode(sdl_texture, SDL_ScaleModeLinear);
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)sdl_texture);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
}
|
}
|
||||||
SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_SetTextureScaleMode(bd->FontTexture, SDL_ScaleModeLinear);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer2_DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
{
|
||||||
io.Fonts->SetTexID(0);
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
SDL_DestroyTexture(bd->FontTexture);
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
bd->FontTexture = nullptr;
|
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
SDL_Rect sdl_r = { r.x, r.y, r.w, r.h };
|
||||||
|
SDL_UpdateTexture(sdl_texture, &sdl_r, tex->GetPixelsAt(r.x, r.y), tex->GetPitch());
|
||||||
|
}
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||||
|
if (sdl_texture == nullptr)
|
||||||
|
return;
|
||||||
|
SDL_DestroyTexture(sdl_texture);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplSDLRenderer2_CreateDeviceObjects()
|
void ImGui_ImplSDLRenderer2_CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
return ImGui_ImplSDLRenderer2_CreateFontsTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
|
void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer2_DestroyFontsTexture();
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
{
|
||||||
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplSDLRenderer2_UpdateTexture(tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||||
// (Requires: SDL 2.0.17+)
|
// (Requires: SDL 2.0.17+)
|
||||||
|
|
||||||
// Note how SDL_Renderer is an _optional_ component of SDL2.
|
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
// For a multi-platform app consider using other technologies:
|
||||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||||
// it might be difficult to step out of those boundaries.
|
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||||
|
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||||
|
// and it might be difficult to step out of those boundaries.
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features:
|
// Missing features:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||||
|
|
||||||
@@ -34,9 +38,18 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture();
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer2_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplSDLRenderer2_RenderState
|
||||||
|
{
|
||||||
|
SDL_Renderer* Renderer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||||
// (Requires: SDL 3.0.0+)
|
// (Requires: SDL 3.1.8+)
|
||||||
|
|
||||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||||
|
// For a multi-platform app consider using other technologies:
|
||||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||||
// it might be difficult to step out of those boundaries.
|
// and it might be difficult to step out of those boundaries.
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features:
|
// Missing features:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||||
|
|
||||||
@@ -24,6 +26,9 @@
|
|||||||
// - Introduction, links and more at the top of imgui.cpp
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
|
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLRenderer3_CreateFontsTexture() and ImGui_ImplSDLRenderer3_DestroyFontsTexture().
|
||||||
|
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||||
|
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
|
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
|
||||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||||
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
|
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
|
||||||
@@ -38,6 +43,8 @@
|
|||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
@@ -50,7 +57,6 @@
|
|||||||
struct ImGui_ImplSDLRenderer3_Data
|
struct ImGui_ImplSDLRenderer3_Data
|
||||||
{
|
{
|
||||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||||
SDL_Texture* FontTexture;
|
|
||||||
ImVector<SDL_FColor> ColorBuffer;
|
ImVector<SDL_FColor> ColorBuffer;
|
||||||
|
|
||||||
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
@@ -76,6 +82,7 @@ bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
io.BackendRendererName = "imgui_impl_sdlrenderer3";
|
io.BackendRendererName = "imgui_impl_sdlrenderer3";
|
||||||
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.
|
||||||
|
|
||||||
bd->Renderer = renderer;
|
bd->Renderer = renderer;
|
||||||
|
|
||||||
@@ -92,25 +99,23 @@ void ImGui_ImplSDLRenderer3_Shutdown()
|
|||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_NewFrame()
|
void ImGui_ImplSDLRenderer3_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer3_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer3_Init()?");
|
||||||
|
IM_UNUSED(bd);
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/libsdl-org/SDL/issues/9009
|
// https://github.com/libsdl-org/SDL/issues/9009
|
||||||
@@ -135,21 +140,28 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||||
|
|
||||||
// If there's a scale factor set by the user, use that instead
|
// If there's a scale factor set by the user, use that instead
|
||||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||||
float rsx = 1.0f;
|
float rsx = 1.0f;
|
||||||
float rsy = 1.0f;
|
float rsy = 1.0f;
|
||||||
SDL_GetRenderScale(renderer, &rsx, &rsy);
|
SDL_GetRenderScale(renderer, &rsx, &rsy);
|
||||||
ImVec2 render_scale;
|
ImVec2 render_scale;
|
||||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||||
|
|
||||||
// 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 * render_scale.x);
|
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||||
if (fb_width == 0 || fb_height == 0)
|
if (fb_width == 0 || fb_height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplSDLRenderer3_UpdateTexture(tex);
|
||||||
|
|
||||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||||
struct BackupSDLRendererState
|
struct BackupSDLRendererState
|
||||||
@@ -165,21 +177,28 @@ 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);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Setup desired state
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||||
ImVec2 clip_scale = render_scale;
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplSDLRenderer3_RenderState render_state;
|
||||||
|
render_state.Renderer = renderer;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||||
|
ImVec2 clip_scale = render_scale;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback)
|
if (pcmd->UserCallback)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -187,7 +206,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -209,71 +228,84 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
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)); // SDL 2.0.19+
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||||
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),
|
||||||
uv, (int)sizeof(ImDrawVert),
|
uv, (int)sizeof(ImDrawVert),
|
||||||
cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
|
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
|
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
||||||
bool ImGui_ImplSDLRenderer3_CreateFontsTexture()
|
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||||
|
|
||||||
// Build texture atlas
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
|
||||||
if (bd->FontTexture == nullptr)
|
|
||||||
{
|
{
|
||||||
SDL_Log("error creating texture");
|
// Create and upload new texture to graphics system
|
||||||
return false;
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == 0 && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
// (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);
|
||||||
|
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
||||||
|
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
||||||
|
SDL_SetTextureBlendMode(sdl_texture, SDL_BLENDMODE_BLEND);
|
||||||
|
SDL_SetTextureScaleMode(sdl_texture, SDL_SCALEMODE_LINEAR);
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)sdl_texture);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
}
|
}
|
||||||
SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_SetTextureScaleMode(bd->FontTexture, SDL_SCALEMODE_LINEAR);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
{
|
||||||
io.Fonts->SetTexID(0);
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
SDL_DestroyTexture(bd->FontTexture);
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
bd->FontTexture = nullptr;
|
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
SDL_Rect sdl_r = { r.x, r.y, r.w, r.h };
|
||||||
|
SDL_UpdateTexture(sdl_texture, &sdl_r, tex->GetPixelsAt(r.x, r.y), tex->GetPitch());
|
||||||
|
}
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||||
|
{
|
||||||
|
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||||
|
if (sdl_texture == nullptr)
|
||||||
|
return;
|
||||||
|
SDL_DestroyTexture(sdl_texture);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplSDLRenderer3_CreateDeviceObjects()
|
void ImGui_ImplSDLRenderer3_CreateDeviceObjects()
|
||||||
{
|
{
|
||||||
return ImGui_ImplSDLRenderer3_CreateFontsTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_DestroyDeviceObjects()
|
void ImGui_ImplSDLRenderer3_DestroyDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer3_DestroyFontsTexture();
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
{
|
||||||
|
tex->SetStatus(ImTextureStatus_WantDestroy);
|
||||||
|
ImGui_ImplSDLRenderer3_UpdateTexture(tex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||||
// (Requires: SDL 3.0.0+)
|
// (Requires: SDL 3.1.8+)
|
||||||
|
|
||||||
// (**IMPORTANT: SDL 3.0.0 is NOT YET RELEASED AND CURRENTLY HAS A FAST CHANGING API. THIS CODE BREAKS OFTEN AS SDL3 CHANGES.**)
|
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||||
|
// For a multi-platform app consider using other technologies:
|
||||||
// Note how SDL_Renderer is an _optional_ component of SDL3.
|
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user and
|
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||||
// it might be difficult to step out of those boundaries.
|
// and it might be difficult to step out of those boundaries.
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features:
|
// Missing features:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||||
|
|
||||||
@@ -36,9 +38,18 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
// Called by Init/NewFrame/Shutdown
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateFontsTexture();
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer3_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplSDLRenderer3_RenderState
|
||||||
|
{
|
||||||
|
SDL_Renderer* Renderer;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -2,13 +2,12 @@
|
|||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
// [!] Renderer: User texture binding. Use '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) with 16-bit indices.
|
// [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: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||||
|
|
||||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
|
||||||
// See imgui_impl_vulkan.cpp file for details.
|
|
||||||
|
|
||||||
// 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/
|
||||||
|
|
||||||
@@ -64,28 +63,38 @@
|
|||||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Backend uses a small number of descriptors per font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||||
|
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (8) // Minimum per atlas
|
||||||
|
|
||||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||||
// - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
|
||||||
// and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor.
|
|
||||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
|
||||||
// [Please zero-clear before use!]
|
// [Please zero-clear before use!]
|
||||||
|
// - About descriptor pool:
|
||||||
|
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||||
|
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
|
||||||
|
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||||
|
// - About dynamic rendering:
|
||||||
|
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||||
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)
|
||||||
VkInstance Instance;
|
VkInstance Instance;
|
||||||
VkPhysicalDevice PhysicalDevice;
|
VkPhysicalDevice PhysicalDevice;
|
||||||
VkDevice Device;
|
VkDevice Device;
|
||||||
uint32_t QueueFamily;
|
uint32_t QueueFamily;
|
||||||
VkQueue Queue;
|
VkQueue Queue;
|
||||||
VkDescriptorPool DescriptorPool; // See requirements in note above
|
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||||
uint32_t MinImageCount; // >= 2
|
uint32_t MinImageCount; // >= 2
|
||||||
uint32_t ImageCount; // >= MinImageCount
|
uint32_t ImageCount; // >= MinImageCount
|
||||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||||
|
|
||||||
// (Optional)
|
// (Optional)
|
||||||
VkPipelineCache PipelineCache;
|
VkPipelineCache PipelineCache;
|
||||||
uint32_t Subpass;
|
uint32_t Subpass;
|
||||||
|
|
||||||
|
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||||
|
uint32_t DescriptorPoolSize;
|
||||||
|
|
||||||
// (Optional) Dynamic Rendering
|
// (Optional) Dynamic Rendering
|
||||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||||
bool UseDynamicRendering;
|
bool UseDynamicRendering;
|
||||||
@@ -96,42 +105,59 @@ struct ImGui_ImplVulkan_InitInfo
|
|||||||
// (Optional) Allocation, Debugging
|
// (Optional) Allocation, Debugging
|
||||||
const VkAllocationCallbacks* Allocator;
|
const VkAllocationCallbacks* Allocator;
|
||||||
void (*CheckVkResultFn)(VkResult err);
|
void (*CheckVkResultFn)(VkResult err);
|
||||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||||
|
|
||||||
// Optional: load Vulkan functions with a custom function loader
|
// Optional: load Vulkan functions with a custom function loader
|
||||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplVulkan_RenderState
|
||||||
|
{
|
||||||
|
VkCommandBuffer CommandBuffer;
|
||||||
|
VkPipeline Pipeline;
|
||||||
|
VkPipelineLayout PipelineLayout;
|
||||||
|
};
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Internal / Miscellaneous Vulkan Helpers
|
// Internal / Miscellaneous Vulkan Helpers
|
||||||
// (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.
|
||||||
|
//
|
||||||
// You probably do NOT need to use or care about those functions.
|
// You probably do NOT need to use or care about those functions.
|
||||||
// Those functions only exist because:
|
// Those functions only exist because:
|
||||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||||
//
|
//
|
||||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain,
|
||||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
// render pass, frame buffers, etc.). You may read this code if you are curious, but
|
||||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
// it is recommended you use you own custom tailored code to do equivalent work.
|
||||||
|
//
|
||||||
|
// We don't provide a strong guarantee that we won't change those functions API.
|
||||||
|
//
|
||||||
|
// The ImGui_ImplVulkanH_XXX functions should NOT interact with any of the state used
|
||||||
|
// by the regular ImGui_ImplVulkan_XXX functions).
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
struct ImGui_ImplVulkanH_Frame;
|
struct ImGui_ImplVulkanH_Frame;
|
||||||
@@ -142,6 +168,8 @@ IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkIns
|
|||||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
||||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||||
|
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
||||||
|
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
||||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||||
|
|
||||||
// Helper structure to hold the data needed by one rendering frame
|
// Helper structure to hold the data needed by one rendering frame
|
||||||
@@ -181,8 +209,8 @@ struct ImGui_ImplVulkanH_Window
|
|||||||
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
|
||||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||||
ImGui_ImplVulkanH_Frame* Frames;
|
ImVector<ImGui_ImplVulkanH_Frame> Frames;
|
||||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
ImVector<ImGui_ImplVulkanH_FrameSemaphores> FrameSemaphores;
|
||||||
|
|
||||||
ImGui_ImplVulkanH_Window()
|
ImGui_ImplVulkanH_Window()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
|
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// Missing features:
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] 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.
|
||||||
@@ -18,6 +20,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)
|
||||||
|
// 2025-06-12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. (#8465)
|
||||||
|
// 2025-02-26: Recreate image bind groups during render. (#8426, #8046, #7765, #8027) + Update for latest webgpu-native changes.
|
||||||
|
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
|
||||||
|
// 2024-10-07: Expose selected render state in ImGui_ImplWGPU_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
|
// 2024-10-07: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977)
|
// 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977)
|
||||||
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
|
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
|
||||||
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
|
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
|
||||||
@@ -38,6 +45,8 @@
|
|||||||
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
||||||
// 2021-01-28: Initial version.
|
// 2021-01-28: Initial version.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||||
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
@@ -50,26 +59,34 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "imgui.h"
|
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
#include "imgui_impl_wgpu.h"
|
#include "imgui_impl_wgpu.h"
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <webgpu/webgpu.h>
|
#include <webgpu/webgpu.h>
|
||||||
|
|
||||||
|
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||||
|
// 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 = 0);
|
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).
|
||||||
|
|
||||||
// WebGPU data
|
// WebGPU data
|
||||||
|
struct ImGui_ImplWGPU_Texture
|
||||||
|
{
|
||||||
|
WGPUTexture Texture = nullptr;
|
||||||
|
WGPUTextureView TextureView = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct RenderResources
|
struct RenderResources
|
||||||
{
|
{
|
||||||
WGPUTexture FontTexture = nullptr; // Font texture
|
WGPUSampler Sampler = nullptr; // Sampler for textures
|
||||||
WGPUTextureView FontTextureView = nullptr; // Texture view for font texture
|
|
||||||
WGPUSampler Sampler = nullptr; // Sampler for the font texture
|
|
||||||
WGPUBuffer Uniforms = nullptr; // Shader uniforms
|
WGPUBuffer Uniforms = nullptr; // Shader uniforms
|
||||||
WGPUBindGroup CommonBindGroup = nullptr; // Resources bind-group to bind the common resources to pipeline
|
WGPUBindGroup CommonBindGroup = nullptr; // Resources bind-group to bind the common resources to pipeline
|
||||||
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
||||||
WGPUBindGroup ImageBindGroup = nullptr; // Default font-resource of Dear ImGui
|
|
||||||
WGPUBindGroupLayout ImageBindGroupLayout = nullptr; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
|
WGPUBindGroupLayout ImageBindGroupLayout = nullptr; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -223,27 +240,11 @@ static void SafeRelease(WGPUShaderModule& res)
|
|||||||
wgpuShaderModuleRelease(res);
|
wgpuShaderModuleRelease(res);
|
||||||
res = nullptr;
|
res = nullptr;
|
||||||
}
|
}
|
||||||
static void SafeRelease(WGPUTextureView& res)
|
|
||||||
{
|
|
||||||
if (res)
|
|
||||||
wgpuTextureViewRelease(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
static void SafeRelease(WGPUTexture& res)
|
|
||||||
{
|
|
||||||
if (res)
|
|
||||||
wgpuTextureRelease(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SafeRelease(RenderResources& res)
|
static void SafeRelease(RenderResources& res)
|
||||||
{
|
{
|
||||||
SafeRelease(res.FontTexture);
|
|
||||||
SafeRelease(res.FontTextureView);
|
|
||||||
SafeRelease(res.Sampler);
|
SafeRelease(res.Sampler);
|
||||||
SafeRelease(res.Uniforms);
|
SafeRelease(res.Uniforms);
|
||||||
SafeRelease(res.CommonBindGroup);
|
SafeRelease(res.CommonBindGroup);
|
||||||
SafeRelease(res.ImageBindGroup);
|
|
||||||
SafeRelease(res.ImageBindGroupLayout);
|
SafeRelease(res.ImageBindGroupLayout);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -259,14 +260,14 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
|||||||
{
|
{
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||||
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||||
#else
|
#else
|
||||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||||
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||||
wgsl_desc.code = wgsl_source;
|
wgsl_desc.code = wgsl_source;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WGPUShaderModuleDescriptor desc = {};
|
WGPUShaderModuleDescriptor desc = {};
|
||||||
@@ -274,7 +275,12 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const c
|
|||||||
|
|
||||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||||
|
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||||
|
#else
|
||||||
stage_desc.entryPoint = "main";
|
stage_desc.entryPoint = "main";
|
||||||
|
#endif
|
||||||
return stage_desc;
|
return stage_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,9 +369,16 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
// 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);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplWGPU_UpdateTexture(tex);
|
||||||
|
|
||||||
// FIXME: Assuming that this only gets called once per frame!
|
// FIXME: Assuming that this only gets called once per frame!
|
||||||
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
@@ -387,6 +400,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
"Dear ImGui Vertex buffer",
|
"Dear ImGui Vertex buffer",
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
WGPU_STRLEN,
|
||||||
|
#endif
|
||||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||||
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
|
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
|
||||||
false
|
false
|
||||||
@@ -411,6 +427,9 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
"Dear ImGui Index buffer",
|
"Dear ImGui Index buffer",
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
WGPU_STRLEN,
|
||||||
|
#endif
|
||||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||||
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
|
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
|
||||||
false
|
false
|
||||||
@@ -425,13 +444,12 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
// Upload vertex/index data into a single contiguous GPU buffer
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
|
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
|
||||||
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
idx_dst += cmd_list->IdxBuffer.Size;
|
|
||||||
}
|
}
|
||||||
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4);
|
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4);
|
||||||
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4);
|
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4);
|
||||||
@@ -441,18 +459,24 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
// Setup desired render state
|
// Setup desired render state
|
||||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||||
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplWGPU_RenderState render_state;
|
||||||
|
render_state.Device = bd->wgpuDevice;
|
||||||
|
render_state.RenderPassEncoder = pass_encoder;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
int global_vtx_offset = 0;
|
int global_vtx_offset = 0;
|
||||||
int global_idx_offset = 0;
|
int global_idx_offset = 0;
|
||||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
ImVec2 clip_off = draw_data->DisplayPos;
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
{
|
{
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
if (pcmd->UserCallback != nullptr)
|
if (pcmd->UserCallback != nullptr)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
@@ -460,24 +484,20 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||||
else
|
else
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Bind custom texture
|
// Bind custom texture
|
||||||
ImTextureID tex_id = pcmd->GetTexID();
|
ImTextureID tex_id = pcmd->GetTexID();
|
||||||
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id));
|
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id), 0);
|
||||||
auto bind_group = bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash);
|
WGPUBindGroup bind_group = (WGPUBindGroup)bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash);
|
||||||
if (bind_group)
|
if (!bind_group)
|
||||||
{
|
{
|
||||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
|
bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
|
||||||
}
|
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, bind_group);
|
||||||
else
|
|
||||||
{
|
|
||||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
|
|
||||||
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group);
|
|
||||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, nullptr);
|
|
||||||
}
|
}
|
||||||
|
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
|
||||||
|
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
@@ -496,34 +516,68 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
|||||||
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove all ImageBindGroups
|
||||||
|
ImGuiStorage& image_bind_groups = bd->renderResources.ImageBindGroups;
|
||||||
|
for (int i = 0; i < image_bind_groups.Data.Size; i++)
|
||||||
|
{
|
||||||
|
WGPUBindGroup bind_group = (WGPUBindGroup)image_bind_groups.Data[i].val_p;
|
||||||
|
SafeRelease(bind_group);
|
||||||
|
}
|
||||||
|
image_bind_groups.Data.resize(0);
|
||||||
|
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWGPU_CreateFontsTexture()
|
static void ImGui_ImplWGPU_DestroyTexture(ImTextureData* tex)
|
||||||
{
|
{
|
||||||
// Build texture atlas
|
ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData;
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
if (backend_tex == nullptr)
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
return;
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height, size_pp;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &size_pp);
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
IM_ASSERT(backend_tex->TextureView == (WGPUTextureView)(intptr_t)tex->TexID);
|
||||||
|
wgpuTextureViewRelease(backend_tex->TextureView);
|
||||||
|
wgpuTextureRelease(backend_tex->Texture);
|
||||||
|
IM_DELETE(backend_tex);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
tex->BackendUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
{
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
ImGui_ImplWGPU_Texture* backend_tex = IM_NEW(ImGui_ImplWGPU_Texture)();
|
||||||
|
|
||||||
|
// Create texture
|
||||||
WGPUTextureDescriptor tex_desc = {};
|
WGPUTextureDescriptor tex_desc = {};
|
||||||
tex_desc.label = "Dear ImGui Font Texture";
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
tex_desc.label = { "Dear ImGui Texture", WGPU_STRLEN };
|
||||||
|
#else
|
||||||
|
tex_desc.label = "Dear ImGui Texture";
|
||||||
|
#endif
|
||||||
tex_desc.dimension = WGPUTextureDimension_2D;
|
tex_desc.dimension = WGPUTextureDimension_2D;
|
||||||
tex_desc.size.width = width;
|
tex_desc.size.width = tex->Width;
|
||||||
tex_desc.size.height = height;
|
tex_desc.size.height = tex->Height;
|
||||||
tex_desc.size.depthOrArrayLayers = 1;
|
tex_desc.size.depthOrArrayLayers = 1;
|
||||||
tex_desc.sampleCount = 1;
|
tex_desc.sampleCount = 1;
|
||||||
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||||
tex_desc.mipLevelCount = 1;
|
tex_desc.mipLevelCount = 1;
|
||||||
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
|
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
|
||||||
bd->renderResources.FontTexture = wgpuDeviceCreateTexture(bd->wgpuDevice, &tex_desc);
|
backend_tex->Texture = wgpuDeviceCreateTexture(bd->wgpuDevice, &tex_desc);
|
||||||
|
|
||||||
|
// Create texture view
|
||||||
WGPUTextureViewDescriptor tex_view_desc = {};
|
WGPUTextureViewDescriptor tex_view_desc = {};
|
||||||
tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||||
tex_view_desc.dimension = WGPUTextureViewDimension_2D;
|
tex_view_desc.dimension = WGPUTextureViewDimension_2D;
|
||||||
@@ -532,41 +586,50 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
|||||||
tex_view_desc.baseArrayLayer = 0;
|
tex_view_desc.baseArrayLayer = 0;
|
||||||
tex_view_desc.arrayLayerCount = 1;
|
tex_view_desc.arrayLayerCount = 1;
|
||||||
tex_view_desc.aspect = WGPUTextureAspect_All;
|
tex_view_desc.aspect = WGPUTextureAspect_All;
|
||||||
bd->renderResources.FontTextureView = wgpuTextureCreateView(bd->renderResources.FontTexture, &tex_view_desc);
|
backend_tex->TextureView = wgpuTextureCreateView(backend_tex->Texture, &tex_view_desc);
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)backend_tex->TextureView);
|
||||||
|
tex->BackendUserData = backend_tex;
|
||||||
|
// We don't set tex->Status to ImTextureStatus_OK to let the code fallthrough below.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload texture data
|
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||||
{
|
{
|
||||||
|
ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData;
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
|
// We could use the smaller rect on _WantCreate but using the full rect allows us to clear the texture.
|
||||||
|
const int upload_x = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.x;
|
||||||
|
const int upload_y = (tex->Status == ImTextureStatus_WantCreate) ? 0 : tex->UpdateRect.y;
|
||||||
|
const int upload_w = (tex->Status == ImTextureStatus_WantCreate) ? tex->Width : tex->UpdateRect.w;
|
||||||
|
const int upload_h = (tex->Status == ImTextureStatus_WantCreate) ? tex->Height : tex->UpdateRect.h;
|
||||||
|
|
||||||
|
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->UpdateRect but you can use tex->Updates[] to upload individual regions.
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
WGPUTexelCopyTextureInfo dst_view = {};
|
||||||
|
#else
|
||||||
WGPUImageCopyTexture dst_view = {};
|
WGPUImageCopyTexture dst_view = {};
|
||||||
dst_view.texture = bd->renderResources.FontTexture;
|
#endif
|
||||||
|
dst_view.texture = backend_tex->Texture;
|
||||||
dst_view.mipLevel = 0;
|
dst_view.mipLevel = 0;
|
||||||
dst_view.origin = { 0, 0, 0 };
|
dst_view.origin = { (uint32_t)upload_x, (uint32_t)upload_y, 0 };
|
||||||
dst_view.aspect = WGPUTextureAspect_All;
|
dst_view.aspect = WGPUTextureAspect_All;
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
WGPUTexelCopyBufferLayout layout = {};
|
||||||
|
#else
|
||||||
WGPUTextureDataLayout layout = {};
|
WGPUTextureDataLayout layout = {};
|
||||||
|
#endif
|
||||||
layout.offset = 0;
|
layout.offset = 0;
|
||||||
layout.bytesPerRow = width * size_pp;
|
layout.bytesPerRow = tex->Width * tex->BytesPerPixel;
|
||||||
layout.rowsPerImage = height;
|
layout.rowsPerImage = upload_h;
|
||||||
WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 };
|
WGPUExtent3D write_size = { (uint32_t)upload_w, (uint32_t)upload_h, 1 };
|
||||||
wgpuQueueWriteTexture(bd->defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size);
|
wgpuQueueWriteTexture(bd->defaultQueue, &dst_view, tex->GetPixelsAt(upload_x, upload_y), (uint32_t)(tex->Width * upload_h * tex->BytesPerPixel), &layout, &write_size);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
}
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
// Create the associated sampler
|
ImGui_ImplWGPU_DestroyTexture(tex);
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
{
|
|
||||||
WGPUSamplerDescriptor sampler_desc = {};
|
|
||||||
sampler_desc.minFilter = WGPUFilterMode_Linear;
|
|
||||||
sampler_desc.magFilter = WGPUFilterMode_Linear;
|
|
||||||
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
|
|
||||||
sampler_desc.addressModeU = WGPUAddressMode_Repeat;
|
|
||||||
sampler_desc.addressModeV = WGPUAddressMode_Repeat;
|
|
||||||
sampler_desc.addressModeW = WGPUAddressMode_Repeat;
|
|
||||||
sampler_desc.maxAnisotropy = 1;
|
|
||||||
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->renderResources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
|
||||||
io.Fonts->SetTexID((ImTextureID)bd->renderResources.FontTextureView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWGPU_CreateUniformBuffer()
|
static void ImGui_ImplWGPU_CreateUniformBuffer()
|
||||||
@@ -576,6 +639,9 @@ static void ImGui_ImplWGPU_CreateUniformBuffer()
|
|||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
"Dear ImGui Uniform buffer",
|
"Dear ImGui Uniform buffer",
|
||||||
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
|
WGPU_STRLEN,
|
||||||
|
#endif
|
||||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
||||||
MEMALIGN(sizeof(Uniforms), 16),
|
MEMALIGN(sizeof(Uniforms), 16),
|
||||||
false
|
false
|
||||||
@@ -639,9 +705,15 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
// Vertex input configuration
|
// Vertex input configuration
|
||||||
WGPUVertexAttribute attribute_desc[] =
|
WGPUVertexAttribute attribute_desc[] =
|
||||||
{
|
{
|
||||||
|
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||||
|
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||||
|
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||||
|
{ nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||||
|
#else
|
||||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||||
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
WGPUVertexBufferLayout buffer_layouts[1];
|
WGPUVertexBufferLayout buffer_layouts[1];
|
||||||
@@ -681,7 +753,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
// Create depth-stencil State
|
// Create depth-stencil State
|
||||||
WGPUDepthStencilState depth_stencil_state = {};
|
WGPUDepthStencilState depth_stencil_state = {};
|
||||||
depth_stencil_state.format = bd->depthStencilFormat;
|
depth_stencil_state.format = bd->depthStencilFormat;
|
||||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
||||||
#else
|
#else
|
||||||
depth_stencil_state.depthWriteEnabled = false;
|
depth_stencil_state.depthWriteEnabled = false;
|
||||||
@@ -701,26 +773,32 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
|
|
||||||
bd->pipelineState = wgpuDeviceCreateRenderPipeline(bd->wgpuDevice, &graphics_pipeline_desc);
|
bd->pipelineState = wgpuDeviceCreateRenderPipeline(bd->wgpuDevice, &graphics_pipeline_desc);
|
||||||
|
|
||||||
ImGui_ImplWGPU_CreateFontsTexture();
|
|
||||||
ImGui_ImplWGPU_CreateUniformBuffer();
|
ImGui_ImplWGPU_CreateUniformBuffer();
|
||||||
|
|
||||||
|
// Create sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
WGPUSamplerDescriptor sampler_desc = {};
|
||||||
|
sampler_desc.minFilter = WGPUFilterMode_Linear;
|
||||||
|
sampler_desc.magFilter = WGPUFilterMode_Linear;
|
||||||
|
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
|
||||||
|
sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
|
||||||
|
sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
|
||||||
|
sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
|
||||||
|
sampler_desc.maxAnisotropy = 1;
|
||||||
|
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc);
|
||||||
|
|
||||||
// Create resource bind group
|
// Create resource bind group
|
||||||
WGPUBindGroupEntry common_bg_entries[] =
|
WGPUBindGroupEntry common_bg_entries[] =
|
||||||
{
|
{
|
||||||
{ nullptr, 0, bd->renderResources.Uniforms, 0, MEMALIGN(sizeof(Uniforms), 16), 0, 0 },
|
{ nullptr, 0, bd->renderResources.Uniforms, 0, MEMALIGN(sizeof(Uniforms), 16), 0, 0 },
|
||||||
{ nullptr, 1, 0, 0, 0, bd->renderResources.Sampler, 0 },
|
{ nullptr, 1, 0, 0, 0, bd->renderResources.Sampler, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
WGPUBindGroupDescriptor common_bg_descriptor = {};
|
WGPUBindGroupDescriptor common_bg_descriptor = {};
|
||||||
common_bg_descriptor.layout = bg_layouts[0];
|
common_bg_descriptor.layout = bg_layouts[0];
|
||||||
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
||||||
common_bg_descriptor.entries = common_bg_entries;
|
common_bg_descriptor.entries = common_bg_entries;
|
||||||
bd->renderResources.CommonBindGroup = wgpuDeviceCreateBindGroup(bd->wgpuDevice, &common_bg_descriptor);
|
bd->renderResources.CommonBindGroup = wgpuDeviceCreateBindGroup(bd->wgpuDevice, &common_bg_descriptor);
|
||||||
|
|
||||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], bd->renderResources.FontTextureView);
|
|
||||||
bd->renderResources.ImageBindGroup = image_bind_group;
|
|
||||||
bd->renderResources.ImageBindGroupLayout = bg_layouts[1];
|
bd->renderResources.ImageBindGroupLayout = bg_layouts[1];
|
||||||
bd->renderResources.ImageBindGroups.SetVoidPtr(ImHashData(&bd->renderResources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
|
|
||||||
|
|
||||||
SafeRelease(vertex_shader_desc.module);
|
SafeRelease(vertex_shader_desc.module);
|
||||||
SafeRelease(pixel_shader_desc.module);
|
SafeRelease(pixel_shader_desc.module);
|
||||||
@@ -739,8 +817,10 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects()
|
|||||||
SafeRelease(bd->pipelineState);
|
SafeRelease(bd->pipelineState);
|
||||||
SafeRelease(bd->renderResources);
|
SafeRelease(bd->renderResources);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
// Destroy all textures
|
||||||
io.Fonts->SetTexID(0); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplWGPU_DestroyTexture(tex);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < bd->numFramesInFlight; i++)
|
for (unsigned int i = 0; i < bd->numFramesInFlight; i++)
|
||||||
SafeRelease(bd->pFrameResources[i]);
|
SafeRelease(bd->pFrameResources[i]);
|
||||||
@@ -765,6 +845,7 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
|||||||
io.BackendRendererName = "imgui_impl_webgpu";
|
io.BackendRendererName = "imgui_impl_webgpu";
|
||||||
#endif
|
#endif
|
||||||
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.
|
||||||
|
|
||||||
bd->initInfo = *init_info;
|
bd->initInfo = *init_info;
|
||||||
bd->wgpuDevice = init_info->Device;
|
bd->wgpuDevice = init_info->Device;
|
||||||
@@ -774,13 +855,10 @@ bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
|||||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||||
bd->frameIndex = UINT_MAX;
|
bd->frameIndex = UINT_MAX;
|
||||||
|
|
||||||
bd->renderResources.FontTexture = nullptr;
|
|
||||||
bd->renderResources.FontTextureView = nullptr;
|
|
||||||
bd->renderResources.Sampler = nullptr;
|
bd->renderResources.Sampler = nullptr;
|
||||||
bd->renderResources.Uniforms = nullptr;
|
bd->renderResources.Uniforms = nullptr;
|
||||||
bd->renderResources.CommonBindGroup = nullptr;
|
bd->renderResources.CommonBindGroup = nullptr;
|
||||||
bd->renderResources.ImageBindGroups.Data.reserve(100);
|
bd->renderResources.ImageBindGroups.Data.reserve(100);
|
||||||
bd->renderResources.ImageBindGroup = nullptr;
|
|
||||||
bd->renderResources.ImageBindGroupLayout = nullptr;
|
bd->renderResources.ImageBindGroupLayout = nullptr;
|
||||||
|
|
||||||
// Create buffers with a default size (they will later be grown as needed)
|
// Create buffers with a default size (they will later be grown as needed)
|
||||||
@@ -815,7 +893,7 @@ void ImGui_ImplWGPU_Shutdown()
|
|||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,7 +901,8 @@ void ImGui_ImplWGPU_NewFrame()
|
|||||||
{
|
{
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
if (!bd->pipelineState)
|
if (!bd->pipelineState)
|
||||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
if (!ImGui_ImplWGPU_CreateDeviceObjects())
|
||||||
|
IM_ASSERT(0 && "ImGui_ImplWGPU_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -10,10 +10,12 @@
|
|||||||
//#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
//#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||||
|
|
||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// Missing features:
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] 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.
|
||||||
@@ -53,7 +55,19 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
|
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
|
||||||
|
|
||||||
// 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 void ImGui_ImplWGPU_InvalidateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplWGPU_RenderState
|
||||||
|
{
|
||||||
|
WGPUDevice Device;
|
||||||
|
WGPURenderPassEncoder RenderPassEncoder;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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'.
|
// [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.
|
||||||
@@ -22,7 +22,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)
|
||||||
// 2024-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2025-06-02: [Docking] WM_DPICHANGED also apply io.ConfigDpiScaleViewports for main viewport instead of letting it be done by application code.
|
||||||
|
// 2025-04-30: Inputs: Fixed an issue where externally losing mouse capture (due to e.g. focus loss) would fail to claim it again the next subsequent click. (#8594)
|
||||||
|
// 2025-03-26: [Docking] Viewports: fixed an issue when closing a window from the OS close button (with io.ConfigViewportsNoDecoration = false) while user code was discarding the 'bool* p_open = false' output from Begin(). Because we allowed the Win32 window to close early, Windows destroyed it and our imgui window became not visible even though user code was still submitting it.
|
||||||
|
// 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: [Docking] 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.
|
||||||
|
// 2024-11-21: [Docking] Fixed a crash when multiple processes are running with multi-viewports, caused by misusage of GetProp(). (#8162, #8069)
|
||||||
|
// 2024-10-28: [Docking] Rely on property stored inside HWND to retrieve context/viewport, should facilitate attempt to use this for parallel contexts. (#8069)
|
||||||
// 2024-09-16: [Docking] Inputs: fixed an issue where a viewport destroyed while clicking would hog mouse tracking and temporary lead to incorrect update of HoveredWindow. (#7971)
|
// 2024-09-16: [Docking] 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.
|
||||||
@@ -107,8 +115,8 @@ typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc);
|
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc);
|
||||||
static void ImGui_ImplWin32_ShutdownPlatformInterface();
|
static void ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
||||||
static void ImGui_ImplWin32_UpdateMonitors();
|
static void ImGui_ImplWin32_UpdateMonitors();
|
||||||
|
|
||||||
struct ImGui_ImplWin32_Data
|
struct ImGui_ImplWin32_Data
|
||||||
@@ -142,12 +150,16 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
|||||||
{
|
{
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData(ImGuiIO& io)
|
||||||
|
{
|
||||||
|
return (ImGui_ImplWin32_Data*)io.BackendPlatformUserData;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplWin32_UpdateKeyboardCodePage()
|
static void ImGui_ImplWin32_UpdateKeyboardCodePage(ImGuiIO& io)
|
||||||
{
|
{
|
||||||
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||||
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
||||||
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
||||||
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
||||||
@@ -179,7 +191,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
|||||||
bd->TicksPerSecond = perf_frequency;
|
bd->TicksPerSecond = perf_frequency;
|
||||||
bd->Time = perf_counter;
|
bd->Time = perf_counter;
|
||||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||||
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||||
|
|
||||||
// Update monitor a first time during init
|
// Update monitor a first time during init
|
||||||
ImGui_ImplWin32_UpdateMonitors();
|
ImGui_ImplWin32_UpdateMonitors();
|
||||||
@@ -187,8 +199,11 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
|||||||
// 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;
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
ImGui_ImplWin32_InitPlatformInterface(platform_has_own_dc);
|
// 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);
|
||||||
|
|
||||||
// Dynamically load XInput library
|
// Dynamically load XInput library
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
@@ -231,7 +246,8 @@ void ImGui_ImplWin32_Shutdown()
|
|||||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
ImGui_ImplWin32_ShutdownPlatformInterface();
|
::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
|
||||||
@@ -245,13 +261,11 @@ void ImGui_ImplWin32_Shutdown()
|
|||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
static bool ImGui_ImplWin32_UpdateMouseCursor(ImGuiIO& io, ImGuiMouseCursor imgui_cursor)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
|
||||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||||
{
|
{
|
||||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||||
@@ -271,6 +285,8 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
|||||||
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||||
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||||
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||||
|
case ImGuiMouseCursor_Wait: win32_cursor = IDC_WAIT; break;
|
||||||
|
case ImGuiMouseCursor_Progress: win32_cursor = IDC_APPSTARTING; break;
|
||||||
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||||
}
|
}
|
||||||
::SetCursor(::LoadCursor(nullptr, win32_cursor));
|
::SetCursor(::LoadCursor(nullptr, win32_cursor));
|
||||||
@@ -283,54 +299,62 @@ static bool IsVkDown(int vk)
|
|||||||
return (::GetKeyState(vk) & 0x8000) != 0;
|
return (::GetKeyState(vk) & 0x8000) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
static void ImGui_ImplWin32_AddKeyEvent(ImGuiIO& io, ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.AddKeyEvent(key, down);
|
io.AddKeyEvent(key, down);
|
||||||
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
||||||
IM_UNUSED(native_scancode);
|
IM_UNUSED(native_scancode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds(ImGuiIO& io)
|
||||||
{
|
{
|
||||||
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
|
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
|
||||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
|
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
||||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
|
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||||
|
|
||||||
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
|
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
||||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
|
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
||||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
|
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightSuper, false, VK_RWIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
static void ImGui_ImplWin32_UpdateKeyModifiers(ImGuiIO& io)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
||||||
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
||||||
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
||||||
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)
|
||||||
|
{
|
||||||
|
// 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)
|
// 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!
|
// Because of that, it is a little more complicated than your typical single-viewport binding code!
|
||||||
static void ImGui_ImplWin32_UpdateMouseData()
|
static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io, ImGuiPlatformIO& platform_io)
|
||||||
{
|
{
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
IM_ASSERT(bd->hWnd != 0);
|
IM_ASSERT(bd->hWnd != 0);
|
||||||
|
|
||||||
POINT mouse_screen_pos;
|
POINT mouse_screen_pos;
|
||||||
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
|
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::FindViewportByPlatformHandle((void*)focused_window)));
|
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, focused_window)));
|
||||||
if (is_app_focused)
|
if (is_app_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos 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.
|
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
{
|
{
|
||||||
@@ -365,19 +389,16 @@ static void ImGui_ImplWin32_UpdateMouseData()
|
|||||||
ImGuiID mouse_viewport_id = 0;
|
ImGuiID mouse_viewport_id = 0;
|
||||||
if (has_mouse_screen_pos)
|
if (has_mouse_screen_pos)
|
||||||
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
||||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
|
if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hovered_hwnd))
|
||||||
mouse_viewport_id = viewport->ID;
|
mouse_viewport_id = viewport->ID;
|
||||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gamepad navigation mapping
|
// Gamepad navigation mapping
|
||||||
static void ImGui_ImplWin32_UpdateGamepads()
|
static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
||||||
{
|
{
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
||||||
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
||||||
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||||
@@ -424,7 +445,9 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
|||||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||||
#undef MAP_BUTTON
|
#undef MAP_BUTTON
|
||||||
#undef MAP_ANALOG
|
#undef MAP_ANALOG
|
||||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#else // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
|
IM_UNUSED(io);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
||||||
@@ -463,6 +486,7 @@ 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 };
|
||||||
@@ -478,31 +502,34 @@ void ImGui_ImplWin32_NewFrame()
|
|||||||
bd->Time = current_time;
|
bd->Time = current_time;
|
||||||
|
|
||||||
// Update OS mouse position
|
// Update OS mouse position
|
||||||
ImGui_ImplWin32_UpdateMouseData();
|
ImGui_ImplWin32_UpdateMouseData(io, platform_io);
|
||||||
|
|
||||||
// Process workarounds for known Windows key handling issues
|
// Process workarounds for known Windows key handling issues
|
||||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
|
||||||
|
|
||||||
// Update OS mouse cursor with the cursor requested by imgui
|
// Update OS mouse cursor with the cursor requested by imgui
|
||||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||||
if (bd->LastMouseCursor != mouse_cursor)
|
if (bd->LastMouseCursor != mouse_cursor)
|
||||||
{
|
{
|
||||||
bd->LastMouseCursor = mouse_cursor;
|
bd->LastMouseCursor = mouse_cursor;
|
||||||
ImGui_ImplWin32_UpdateMouseCursor();
|
ImGui_ImplWin32_UpdateMouseCursor(io, mouse_cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update game controllers (if enabled and available)
|
// Update game controllers (if enabled and available)
|
||||||
ImGui_ImplWin32_UpdateGamepads();
|
ImGui_ImplWin32_UpdateGamepads(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map VK_xxx to ImGuiKey_xxx.
|
// Map VK_xxx to ImGuiKey_xxx.
|
||||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||||
|
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam);
|
||||||
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED.
|
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED.
|
||||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||||
return ImGuiKey_KeypadEnter;
|
return ImGuiKey_KeypadEnter;
|
||||||
|
|
||||||
|
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||||
|
//IMGUI_DEBUG_LOG("scancode %3d, keycode = 0x%02X\n", scancode, wParam);
|
||||||
switch (wParam)
|
switch (wParam)
|
||||||
{
|
{
|
||||||
case VK_TAB: return ImGuiKey_Tab;
|
case VK_TAB: return ImGuiKey_Tab;
|
||||||
@@ -520,17 +547,17 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
|||||||
case VK_SPACE: return ImGuiKey_Space;
|
case VK_SPACE: return ImGuiKey_Space;
|
||||||
case VK_RETURN: return ImGuiKey_Enter;
|
case VK_RETURN: return ImGuiKey_Enter;
|
||||||
case VK_ESCAPE: return ImGuiKey_Escape;
|
case VK_ESCAPE: return ImGuiKey_Escape;
|
||||||
case VK_OEM_7: return ImGuiKey_Apostrophe;
|
//case VK_OEM_7: return ImGuiKey_Apostrophe;
|
||||||
case VK_OEM_COMMA: return ImGuiKey_Comma;
|
case VK_OEM_COMMA: return ImGuiKey_Comma;
|
||||||
case VK_OEM_MINUS: return ImGuiKey_Minus;
|
//case VK_OEM_MINUS: return ImGuiKey_Minus;
|
||||||
case VK_OEM_PERIOD: return ImGuiKey_Period;
|
case VK_OEM_PERIOD: return ImGuiKey_Period;
|
||||||
case VK_OEM_2: return ImGuiKey_Slash;
|
//case VK_OEM_2: return ImGuiKey_Slash;
|
||||||
case VK_OEM_1: return ImGuiKey_Semicolon;
|
//case VK_OEM_1: return ImGuiKey_Semicolon;
|
||||||
case VK_OEM_PLUS: return ImGuiKey_Equal;
|
//case VK_OEM_PLUS: return ImGuiKey_Equal;
|
||||||
case VK_OEM_4: return ImGuiKey_LeftBracket;
|
//case VK_OEM_4: return ImGuiKey_LeftBracket;
|
||||||
case VK_OEM_5: return ImGuiKey_Backslash;
|
//case VK_OEM_5: return ImGuiKey_Backslash;
|
||||||
case VK_OEM_6: return ImGuiKey_RightBracket;
|
//case VK_OEM_6: return ImGuiKey_RightBracket;
|
||||||
case VK_OEM_3: return ImGuiKey_GraveAccent;
|
//case VK_OEM_3: return ImGuiKey_GraveAccent;
|
||||||
case VK_CAPITAL: return ImGuiKey_CapsLock;
|
case VK_CAPITAL: return ImGuiKey_CapsLock;
|
||||||
case VK_SCROLL: return ImGuiKey_ScrollLock;
|
case VK_SCROLL: return ImGuiKey_ScrollLock;
|
||||||
case VK_NUMLOCK: return ImGuiKey_NumLock;
|
case VK_NUMLOCK: return ImGuiKey_NumLock;
|
||||||
@@ -622,8 +649,29 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
|||||||
case VK_F24: return ImGuiKey_F24;
|
case VK_F24: return ImGuiKey_F24;
|
||||||
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
||||||
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
||||||
default: return ImGuiKey_None;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fallback to scancode
|
||||||
|
// https://handmade.network/forums/t/2011-keyboard_inputs_-_scancodes,_raw_input,_text_input,_key_names
|
||||||
|
switch (scancode)
|
||||||
|
{
|
||||||
|
case 41: return ImGuiKey_GraveAccent; // VK_OEM_8 in EN-UK, VK_OEM_3 in EN-US, VK_OEM_7 in FR, VK_OEM_5 in DE, etc.
|
||||||
|
case 12: return ImGuiKey_Minus;
|
||||||
|
case 13: return ImGuiKey_Equal;
|
||||||
|
case 26: return ImGuiKey_LeftBracket;
|
||||||
|
case 27: return ImGuiKey_RightBracket;
|
||||||
|
case 86: return ImGuiKey_Oem102;
|
||||||
|
case 43: return ImGuiKey_Backslash;
|
||||||
|
case 39: return ImGuiKey_Semicolon;
|
||||||
|
case 40: return ImGuiKey_Apostrophe;
|
||||||
|
case 51: return ImGuiKey_Comma;
|
||||||
|
case 52: return ImGuiKey_Period;
|
||||||
|
case 53: return ImGuiKey_Slash;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImGuiKey_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||||
@@ -634,22 +682,10 @@ ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
|||||||
#define DBT_DEVNODES_CHANGED 0x0007
|
#define DBT_DEVNODES_CHANGED 0x0007
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
// Helper to obtain the source of mouse messages.
|
||||||
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
|
||||||
// When implementing your own backend, 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.
|
|
||||||
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
|
||||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
|
||||||
#if 0
|
|
||||||
// Copy this line into your .cpp file to forward declare the function.
|
|
||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
||||||
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
||||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
static ImGuiMouseSource ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo()
|
||||||
{
|
{
|
||||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||||
@@ -659,22 +695,44 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|||||||
return ImGuiMouseSource_Mouse;
|
return ImGuiMouseSource_Mouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||||
|
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||||
|
// When implementing your own backend, 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.
|
||||||
|
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||||
|
|
||||||
|
// Copy either line into your .cpp file to forward declare the function:
|
||||||
|
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()
|
||||||
|
|
||||||
|
#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().
|
||||||
// We silently allow both context or just only backend data to be nullptr.
|
// We silently allow both context or just only backend data to be nullptr.
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
if (ImGui::GetCurrentContext() == nullptr)
|
||||||
|
return 0;
|
||||||
|
return ImGui_ImplWin32_WndProcHandlerEx(hwnd, msg, wParam, lParam, ImGui::GetIO());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This version is in theory thread-safe in the sense that no path should access ImGui::GetCurrentContext().
|
||||||
|
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io)
|
||||||
|
{
|
||||||
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||||
if (bd == nullptr)
|
if (bd == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
case WM_NCMOUSEMOVE:
|
case WM_NCMOUSEMOVE:
|
||||||
{
|
{
|
||||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||||
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||||
bd->MouseHwnd = hwnd;
|
bd->MouseHwnd = hwnd;
|
||||||
if (bd->MouseTrackedArea != area)
|
if (bd->MouseTrackedArea != area)
|
||||||
@@ -724,14 +782,17 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||||
{
|
{
|
||||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||||
int button = 0;
|
int button = 0;
|
||||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||||
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
|
HWND hwnd_with_capture = ::GetCapture();
|
||||||
::SetCapture(hwnd);
|
if (bd->MouseButtonsDown != 0 && hwnd_with_capture != hwnd) // Did we externally lost capture?
|
||||||
|
bd->MouseButtonsDown = 0;
|
||||||
|
if (bd->MouseButtonsDown == 0 && hwnd_with_capture == nullptr)
|
||||||
|
::SetCapture(hwnd); // Allow us to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||||
bd->MouseButtonsDown |= 1 << button;
|
bd->MouseButtonsDown |= 1 << button;
|
||||||
io.AddMouseSourceEvent(mouse_source);
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
io.AddMouseButtonEvent(button, true);
|
io.AddMouseButtonEvent(button, true);
|
||||||
@@ -742,7 +803,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
{
|
{
|
||||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||||
int button = 0;
|
int button = 0;
|
||||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||||
@@ -770,7 +831,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
if (wParam < 256)
|
if (wParam < 256)
|
||||||
{
|
{
|
||||||
// Submit modifiers
|
// Submit modifiers
|
||||||
ImGui_ImplWin32_UpdateKeyModifiers();
|
ImGui_ImplWin32_UpdateKeyModifiers(io);
|
||||||
|
|
||||||
// Obtain virtual key code and convert to ImGuiKey
|
// Obtain virtual key code and convert to ImGuiKey
|
||||||
const ImGuiKey key = ImGui_ImplWin32_KeyEventToImGuiKey(wParam, lParam);
|
const ImGuiKey key = ImGui_ImplWin32_KeyEventToImGuiKey(wParam, lParam);
|
||||||
@@ -779,28 +840,28 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
|
|
||||||
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
||||||
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
||||||
ImGui_ImplWin32_AddKeyEvent(key, true, vk, scancode);
|
ImGui_ImplWin32_AddKeyEvent(io, key, true, vk, scancode);
|
||||||
|
|
||||||
// Submit key event
|
// Submit key event
|
||||||
if (key != ImGuiKey_None)
|
if (key != ImGuiKey_None)
|
||||||
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
ImGui_ImplWin32_AddKeyEvent(io, key, is_key_down, vk, scancode);
|
||||||
|
|
||||||
// Submit individual left/right modifier events
|
// Submit individual left/right modifier events
|
||||||
if (vk == VK_SHIFT)
|
if (vk == VK_SHIFT)
|
||||||
{
|
{
|
||||||
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||||
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||||
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||||
}
|
}
|
||||||
else if (vk == VK_CONTROL)
|
else if (vk == VK_CONTROL)
|
||||||
{
|
{
|
||||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||||
}
|
}
|
||||||
else if (vk == VK_MENU)
|
else if (vk == VK_MENU)
|
||||||
{
|
{
|
||||||
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||||
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -810,7 +871,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_INPUTLANGCHANGE:
|
case WM_INPUTLANGCHANGE:
|
||||||
ImGui_ImplWin32_UpdateKeyboardCodePage();
|
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||||
return 0;
|
return 0;
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
if (::IsWindowUnicode(hwnd))
|
if (::IsWindowUnicode(hwnd))
|
||||||
@@ -828,7 +889,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
return 0;
|
return 0;
|
||||||
case WM_SETCURSOR:
|
case WM_SETCURSOR:
|
||||||
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
||||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor(io, bd->LastMouseCursor))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DEVICECHANGE:
|
case WM_DEVICECHANGE:
|
||||||
@@ -840,6 +901,17 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
case WM_DISPLAYCHANGE:
|
case WM_DISPLAYCHANGE:
|
||||||
bd->WantUpdateMonitors = true;
|
bd->WantUpdateMonitors = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
case WM_SETTINGCHANGE:
|
||||||
|
if (wParam == SPI_SETWORKAREA)
|
||||||
|
bd->WantUpdateMonitors = true;
|
||||||
|
return 0;
|
||||||
|
case WM_DPICHANGED:
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
@@ -865,9 +937,9 @@ static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
|||||||
{
|
{
|
||||||
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||||
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
|
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = nullptr;
|
||||||
if (RtlVerifyVersionInfoFn == nullptr)
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||||
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||||
if (RtlVerifyVersionInfoFn == nullptr)
|
if (RtlVerifyVersionInfoFn == nullptr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@@ -875,10 +947,10 @@ static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
|||||||
ULONGLONG conditionMask = 0;
|
ULONGLONG conditionMask = 0;
|
||||||
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||||
versionInfo.dwMajorVersion = major;
|
versionInfo.dwMajorVersion = major;
|
||||||
versionInfo.dwMinorVersion = minor;
|
versionInfo.dwMinorVersion = minor;
|
||||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
||||||
@@ -940,16 +1012,16 @@ float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
|||||||
UINT xdpi = 96, ydpi = 96;
|
UINT xdpi = 96, ydpi = 96;
|
||||||
if (_IsWindows8Point1OrGreater())
|
if (_IsWindows8Point1OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
static PFN_GetDpiForMonitor GetDpiForMonitorFn = nullptr;
|
||||||
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
if (GetDpiForMonitorFn == nullptr && shcore_dll != nullptr)
|
||||||
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||||
if (GetDpiForMonitorFn != nullptr)
|
if (GetDpiForMonitorFn != nullptr)
|
||||||
{
|
{
|
||||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
return xdpi / 96.0f;
|
return xdpi / 96.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NOGDI
|
#ifndef NOGDI
|
||||||
const HDC dc = ::GetDC(nullptr);
|
const HDC dc = ::GetDC(nullptr);
|
||||||
@@ -1013,10 +1085,10 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
|||||||
// 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..
|
// 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.
|
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
struct ImGui_ImplWin32_ViewportData
|
struct ImGui_ImplWin32_ViewportData
|
||||||
{
|
{
|
||||||
HWND Hwnd;
|
HWND Hwnd; // Stored in ImGuiViewport::PlatformHandle + PlatformHandleRaw
|
||||||
HWND HwndParent;
|
HWND HwndParent;
|
||||||
bool HwndOwned;
|
bool HwndOwned;
|
||||||
DWORD DwStyle;
|
DWORD DwStyle;
|
||||||
@@ -1239,7 +1311,12 @@ static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char*
|
|||||||
ImVector<wchar_t> title_w;
|
ImVector<wchar_t> title_w;
|
||||||
title_w.resize(n);
|
title_w.resize(n);
|
||||||
::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n);
|
::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n);
|
||||||
::SetWindowTextW(vd->Hwnd, title_w.Data);
|
|
||||||
|
// 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)
|
static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||||
@@ -1283,24 +1360,27 @@ static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
|
|||||||
#endif
|
#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)
|
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
|
// Allow secondary viewport WndProc to be called regardless of current context
|
||||||
ImGuiContext* hwnd_ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
|
ImGuiContext* ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
|
||||||
ImGuiContext* prev_ctx = ImGui::GetCurrentContext();
|
if (ctx == NULL)
|
||||||
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL)
|
return DefWindowProc(hWnd, msg, wParam, lParam); // unlike ImGui_ImplWin32_WndProcHandler() we are called directly by Windows, we can't just return 0.
|
||||||
ImGui::SetCurrentContext(hwnd_ctx);
|
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO(ctx);
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(ctx);
|
||||||
LRESULT result = 0;
|
LRESULT result = 0;
|
||||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
if (ImGui_ImplWin32_WndProcHandlerEx(hWnd, msg, wParam, lParam, io))
|
||||||
result = true;
|
result = 1;
|
||||||
else if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
|
else if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hWnd))
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
viewport->PlatformRequestClose = true;
|
viewport->PlatformRequestClose = true;
|
||||||
break;
|
return 0; // 0 = Operating system will ignore the message and not destroy the window. We close ourselves.
|
||||||
case WM_MOVE:
|
case WM_MOVE:
|
||||||
viewport->PlatformRequestMove = true;
|
viewport->PlatformRequestMove = true;
|
||||||
break;
|
break;
|
||||||
@@ -1323,12 +1403,10 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
|
|||||||
}
|
}
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
||||||
if (hwnd_ctx != prev_ctx && hwnd_ctx != NULL)
|
|
||||||
ImGui::SetCurrentContext(prev_ctx);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
|
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc)
|
||||||
{
|
{
|
||||||
WNDCLASSEXW wcex;
|
WNDCLASSEXW wcex;
|
||||||
wcex.cbSize = sizeof(WNDCLASSEXW);
|
wcex.cbSize = sizeof(WNDCLASSEXW);
|
||||||
@@ -1373,12 +1451,11 @@ static void ImGui_ImplWin32_InitPlatformInterface(bool platform_has_own_dc)
|
|||||||
vd->Hwnd = bd->hWnd;
|
vd->Hwnd = bd->hWnd;
|
||||||
vd->HwndOwned = false;
|
vd->HwndOwned = false;
|
||||||
main_viewport->PlatformUserData = vd;
|
main_viewport->PlatformUserData = vd;
|
||||||
main_viewport->PlatformHandle = (void*)bd->hWnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplWin32_ShutdownPlatformInterface()
|
static void ImGui_ImplWin32_ShutdownMultiViewportSupport()
|
||||||
{
|
{
|
||||||
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(nullptr));
|
::UnregisterClassW(L"ImGui Platform", ::GetModuleHandle(nullptr));
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||||
// [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 will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
// [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. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility. 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'.
|
// [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.
|
||||||
|
|||||||
40
backends/sdlgpu3/build_instructions.txt
Normal file
40
backends/sdlgpu3/build_instructions.txt
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Instructions to rebuild imgui_impl_sdlgpu3_shaders.h
|
||||||
|
(You don't need to copy this folder if you are using the backend as-is)
|
||||||
|
|
||||||
|
1) Compile the raw shader files to SPIRV:
|
||||||
|
|
||||||
|
glslc -o vertex.spv -c shader.vert
|
||||||
|
glslc -o fragment.spv -c shader.frag
|
||||||
|
|
||||||
|
|
||||||
|
2) Build SDL_shadercross (https://github.com/libsdl-org/SDL_shadercross)
|
||||||
|
|
||||||
|
|
||||||
|
3-A) Compiling for the Vulkan Driver:
|
||||||
|
|
||||||
|
Nothing to do, you just need the previous vertex.spv/fragment.spv, proceed to step 4
|
||||||
|
|
||||||
|
|
||||||
|
3-B) Compiling for the DirectX 12 Driver:
|
||||||
|
|
||||||
|
./shadercross vertex.spv -s SPIRV -d DXBC -t vertex -e main -o vertex.dxbc
|
||||||
|
./shadercross fragment.spv -s SPIRV -d DXBC -t fragment -e main -o fragment.dxbc
|
||||||
|
|
||||||
|
Proceed to step 4
|
||||||
|
|
||||||
|
|
||||||
|
3-C) Compiling for Metal (On windows you'll need the Metal Developer Tools for Windows, on linux you might use wine, but I never tested it):
|
||||||
|
|
||||||
|
./shadercross vertex.spv -s SPIRV -d MSL -t vertex -e main -o vertex.metal
|
||||||
|
./shadercross fragment.spv -s SPIRV -d MSL -t fragment -e main -o fragment.metal
|
||||||
|
|
||||||
|
xcrun -sdk macosx metal -o vertex.ir -c vertex.metal
|
||||||
|
xcrun -sdk macosx metal -o fragment.ir -c fragment.metal
|
||||||
|
xcrun -sdk macosx metallib -o vertex.metallib -c vertex.ir
|
||||||
|
xcrun -sdk macosx metallib -o fragment.metallib -c fragment.ir
|
||||||
|
|
||||||
|
Proceed to step 4
|
||||||
|
|
||||||
|
|
||||||
|
4) Use a tool like https://notisrac.github.io/FileToCArray/ or misc/fonts/binary_to_compressed_c.cpp in imgui repository to convert the file to a uint8_t array.
|
||||||
15
backends/sdlgpu3/shader.frag
Normal file
15
backends/sdlgpu3/shader.frag
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#version 450 core
|
||||||
|
layout(location = 0) out vec4 fColor;
|
||||||
|
|
||||||
|
layout(set=2, binding=0) uniform sampler2D sTexture;
|
||||||
|
|
||||||
|
layout(location = 0) in struct
|
||||||
|
{
|
||||||
|
vec4 Color;
|
||||||
|
vec2 UV;
|
||||||
|
} In;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fColor = In.Color * texture(sTexture, In.UV.st);
|
||||||
|
}
|
||||||
24
backends/sdlgpu3/shader.vert
Normal file
24
backends/sdlgpu3/shader.vert
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#version 450 core
|
||||||
|
layout(location = 0) in vec2 aPos;
|
||||||
|
layout(location = 1) in vec2 aUV;
|
||||||
|
layout(location = 2) in vec4 aColor;
|
||||||
|
|
||||||
|
layout(set=1,binding=0) uniform UBO
|
||||||
|
{
|
||||||
|
vec2 uScale;
|
||||||
|
vec2 uTranslate;
|
||||||
|
} ubo;
|
||||||
|
|
||||||
|
layout(location = 0) out struct
|
||||||
|
{
|
||||||
|
vec4 Color;
|
||||||
|
vec2 UV;
|
||||||
|
} Out;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Out.Color = aColor;
|
||||||
|
Out.UV = aUV;
|
||||||
|
gl_Position = vec4(aPos * ubo.uScale + ubo.uTranslate, 0, 1);
|
||||||
|
gl_Position.y *= -1.0f;
|
||||||
|
}
|
||||||
4
backends/vulkan/build_instructions.txt
Normal file
4
backends/vulkan/build_instructions.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
Script to rebuild shaders stored inside imgui_impl_vulkan.h
|
||||||
|
(You don't need to copy this folder if you are using the backend as-is)
|
||||||
|
|
||||||
301
docs/BACKENDS.md
301
docs/BACKENDS.md
@@ -1,18 +1,33 @@
|
|||||||
_(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md or view this file with any Markdown viewer)_
|
_(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md or view this file with any Markdown viewer)_
|
||||||
|
|
||||||
## Dear ImGui: Backends
|
# Dear ImGui: Backends
|
||||||
|
|
||||||
### Integrating backends
|
## Index
|
||||||
|
|
||||||
|
- [Introduction](#introduction)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
- [What are Backends?](#what-are-backends)
|
||||||
|
- [Using standard Backends](#using-standard-backends)
|
||||||
|
- [Using third-party Backends](#using-third-party-backends)
|
||||||
|
- [Writing your own Backend](#writing-your-own-backend)
|
||||||
|
- [Using a custom engine?](#using-a-custom-engine)
|
||||||
|
- [Platform: Implementing your Platform Backend](#platform-implementing-your-platform-backend)
|
||||||
|
- [Rendering: Implementing your RenderDrawData function](#rendering-implementing-your-renderdrawdata-function)
|
||||||
|
- [Rendering: Adding support for `ImGuiBackendFlags_RendererHasTextures` (1.92+)](#rendering-adding-support-for-imguibackendflags_rendererhastextures-192)
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
💡 The **[Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) wiki guide** has examples of how to integrate Dear ImGui into an existing application.
|
💡 The **[Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) wiki guide** has examples of how to integrate Dear ImGui into an existing application.
|
||||||
<BR> The [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) documentation may also be worth a read.
|
<BR> The [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) documentation may also be worth a read.
|
||||||
|
|
||||||
### What are backends?
|
### What are Backends?
|
||||||
|
|
||||||
Dear ImGui is highly portable and only requires a few things to run and render, typically:
|
Dear ImGui is highly portable and only requires a few things to run and render, typically:
|
||||||
|
|
||||||
- Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure).
|
- Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure).
|
||||||
- Required: uploading the font atlas texture into graphics memory.
|
- Required: creating, updating and destroying textures.
|
||||||
- Required: rendering indexed textured triangles with a clipping rectangle.
|
- Required: rendering indexed textured triangles with a clipping rectangle.
|
||||||
|
|
||||||
Extra features are opt-in, our backends try to support as many as possible:
|
Extra features are opt-in, our backends try to support as many as possible:
|
||||||
@@ -34,13 +49,13 @@ and the backends which we are describing here (backends/ folder).
|
|||||||
- You should be able to write backends for pretty much any platform and any 3D graphics API.
|
- You should be able to write backends for pretty much any platform and any 3D graphics API.
|
||||||
e.g. you can get creative and use software rendering or render remotely on a different machine.
|
e.g. you can get creative and use software rendering or render remotely on a different machine.
|
||||||
|
|
||||||
### Standard backends
|
## Using standard Backends
|
||||||
|
|
||||||
**The [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder contains backends for popular platforms/graphics API, which you can use in
|
**The [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder contains backends for popular platforms/graphics API, which you can use in
|
||||||
your application or engine to easily integrate Dear ImGui.** Each backend is typically self-contained in a pair of files: imgui_impl_XXXX.cpp + imgui_impl_XXXX.h.
|
your application or engine to easily integrate Dear ImGui.** Each backend is typically self-contained in a pair of files: imgui_impl_XXXX.cpp + imgui_impl_XXXX.h.
|
||||||
|
|
||||||
- The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, and windowing.<BR>
|
- The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, and windowing.<BR>
|
||||||
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl2.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl2.cpp)), etc.
|
e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), SDL3 ([imgui_impl_sdl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl3.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), etc.
|
||||||
|
|
||||||
- The 'Renderer' backends are in charge of: creating atlas texture, and rendering imgui draw data.<BR>
|
- The 'Renderer' backends are in charge of: creating atlas texture, and rendering imgui draw data.<BR>
|
||||||
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc.
|
e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc.
|
||||||
@@ -53,44 +68,41 @@ For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree
|
|||||||
|
|
||||||
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
|
**Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
|
||||||
|
|
||||||
### List of backends
|
### List of standard Backends
|
||||||
|
|
||||||
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 Platforms 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 (*EXPERIMENTAL UNTIL SDL3 IS RELEASED*)
|
imgui_impl_sdl3.cpp ; SDL3 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
|
||||||
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!)
|
||||||
|
|
||||||
List of Renderer Backends:
|
List of Renderer Backends:
|
||||||
|
|
||||||
imgui_impl_dx9.cpp ; DirectX9
|
imgui_impl_dx9.cpp ; DirectX9
|
||||||
imgui_impl_dx10.cpp ; DirectX10
|
imgui_impl_dx10.cpp ; DirectX10
|
||||||
imgui_impl_dx11.cpp ; DirectX11
|
imgui_impl_dx11.cpp ; DirectX11
|
||||||
imgui_impl_dx12.cpp ; DirectX12
|
imgui_impl_dx12.cpp ; DirectX12
|
||||||
imgui_impl_metal.mm ; Metal (with ObjC)
|
imgui_impl_metal.mm ; Metal (ObjC or C++)
|
||||||
imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context)
|
imgui_impl_opengl2.cpp ; OpenGL 2 (legacy fixed pipeline. Don't use with modern OpenGL code!)
|
||||||
imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline)
|
imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2/3, WebGL
|
||||||
|
imgui_impl_sdlgpu3.cpp ; SDL_GPU (portable 3D graphics API of SDL3)
|
||||||
imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
|
imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
|
||||||
imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3 available from SDL 3.0.0+)
|
imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3. Prefer using SDL_GPU!).
|
||||||
imgui_impl_vulkan.cpp ; Vulkan
|
imgui_impl_vulkan.cpp ; Vulkan
|
||||||
imgui_impl_wgpu.cpp ; WebGPU (web and desktop)
|
imgui_impl_wgpu.cpp ; WebGPU (web + desktop)
|
||||||
|
|
||||||
List of high-level Frameworks Backends (combining Platform + Renderer):
|
List of high-level Frameworks Backends (combining Platform + Renderer):
|
||||||
|
|
||||||
imgui_impl_allegro5.cpp
|
imgui_impl_allegro5.cpp
|
||||||
|
|
||||||
Emscripten is also supported!
|
Emscripten is also supported!
|
||||||
The SDL+GL, GLFW+GL and GLFW+WebGPU examples are all ready to build and run with Emscripten.
|
The SDL2+GL, SDL3+GL, GLFW+GL and GLFW+WebGPU examples are all ready to build and run with Emscripten.
|
||||||
|
|
||||||
### Backends for third-party frameworks, graphics API or other languages
|
|
||||||
|
|
||||||
See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others).
|
|
||||||
|
|
||||||
### Recommended Backends
|
### Recommended Backends
|
||||||
|
|
||||||
@@ -98,18 +110,32 @@ If you are not sure which backend to use, the recommended platform/frameworks fo
|
|||||||
|
|
||||||
|Library |Website |Backend |Note |
|
|Library |Website |Backend |Note |
|
||||||
|--------|--------|--------|-----|
|
|--------|--------|--------|-----|
|
||||||
| GLFW | https://github.com/glfw/glfw | imgui_impl_glfw.cpp | |
|
| SDL3 | https://www.libsdl.org | imgui_impl_sdl3.cpp | Recommended |
|
||||||
| SDL2 | https://www.libsdl.org | imgui_impl_sdl2.cpp | |
|
| SDL2 | https://www.libsdl.org | imgui_impl_sdl2.cpp | |
|
||||||
|
| GLFW | https://github.com/glfw/glfw | imgui_impl_glfw.cpp | |
|
||||||
| Sokol | https://github.com/floooh/sokol | [util/sokol_imgui.h](https://github.com/floooh/sokol/blob/master/util/sokol_imgui.h) | Lower-level than GLFW/SDL |
|
| Sokol | https://github.com/floooh/sokol | [util/sokol_imgui.h](https://github.com/floooh/sokol/blob/master/util/sokol_imgui.h) | Lower-level than GLFW/SDL |
|
||||||
|
|
||||||
|
If your application runs on Windows or if you are using multi-viewport, the win32 backend handles some details a little better than other backends.
|
||||||
|
|
||||||
|
## Using third-party Backends
|
||||||
|
|
||||||
|
See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others).
|
||||||
|
|
||||||
|
## Writing your own Backend
|
||||||
|
|
||||||
### Using a custom engine?
|
### Using a custom engine?
|
||||||
|
|
||||||
You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities...<BR>
|
You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities...<BR>
|
||||||
Think twice!
|
Think twice!
|
||||||
|
|
||||||
If you are new to Dear ImGui, first try using the existing backends as-is.
|
TL;DR;
|
||||||
|
- Writing your own Renderer Backend is easy.
|
||||||
|
- Writing your own Platform Backend is harder and you are more likely to introduce bugs.
|
||||||
|
- **It is unlikely you will add value to your project by creating your own backend.**
|
||||||
|
|
||||||
|
**Consider using the existing backends as-is**.
|
||||||
You will save lots of time integrating the library.
|
You will save lots of time integrating the library.
|
||||||
|
Standard backends are battle-tested and handle subtleties that you are likely to implement incorrectly.
|
||||||
You can LATER decide to rewrite yourself a custom backend if you really need to.
|
You can LATER decide to rewrite yourself a custom backend if you really need to.
|
||||||
In most situations, custom backends have fewer features and more bugs than the standard backends we provide.
|
In most situations, custom backends have fewer features and more bugs than the standard backends we provide.
|
||||||
If you want portability, you can use multiple backends and choose between them either at compile time
|
If you want portability, you can use multiple backends and choose between them either at compile time
|
||||||
@@ -131,16 +157,221 @@ Suggestion: try using a non-portable backend first (e.g. win32 + underlying grap
|
|||||||
your desktop builds working first. This will get you running faster and get your acquainted with
|
your desktop builds working first. This will get you running faster and get your acquainted with
|
||||||
how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API...
|
how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API...
|
||||||
|
|
||||||
Generally:
|
|
||||||
It is unlikely you will add value to your project by creating your own backend.
|
|
||||||
|
|
||||||
Also:
|
Also:
|
||||||
The [multi-viewports feature](https://github.com/ocornut/imgui/wiki/Multi-Viewports) of the 'docking' branch allows
|
The [multi-viewports feature](https://github.com/ocornut/imgui/wiki/Multi-Viewports) of the 'docking' branch allows
|
||||||
Dear ImGui windows to be seamlessly detached from the main application window. This is achieved using an
|
Dear ImGui windows to be seamlessly detached from the main application window. This is achieved using an
|
||||||
extra layer to the Platform and Renderer backends, which allows Dear ImGui to communicate platform-specific
|
extra layer to the Platform and Renderer backends, which allows Dear ImGui to communicate platform-specific
|
||||||
requests such as: "create an additional OS window", "create a render context", "get the OS position of this
|
requests such as: "create an additional OS window", "create a render context", "get the OS position of this
|
||||||
window" etc. See 'ImGuiPlatformIO' for details.
|
window", but some things are more difficult "find OS window under mouse position BUT with some windows marked as passthrough". See 'ImGuiPlatformIO' for details.
|
||||||
Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult
|
Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult
|
||||||
than supporting single-viewport.
|
than supporting single-viewport.
|
||||||
If you decide to use unmodified imgui_impl_XXXX.cpp files, you can automatically benefit from
|
If you decide to use unmodified imgui_impl_XXXX.cpp files, you can automatically benefit from
|
||||||
improvements and fixes related to viewports and platform windows without extra work on your side.
|
improvements and fixes related to viewports and platform windows without extra work on your side.
|
||||||
|
|
||||||
|
### Platform: Implementing your Platform Backend
|
||||||
|
|
||||||
|
The Platform backends in impl_impl_XXX.cpp files contain many implementations.
|
||||||
|
|
||||||
|
**In your `ImGui_ImplXXX_Init()` function:**
|
||||||
|
- You can allocate your backend data and use `io.BackendPlatformUserData` to store/retrieve it later.
|
||||||
|
- Set `io.BackendPlatformName` to a name `"imgui_impl_xxxx"` which will be available in e.g. About box.
|
||||||
|
- Set `io.BackendPlatformUserData` to your backend data.
|
||||||
|
- Set `io.BackendFlags` with supported optional features:
|
||||||
|
- `ImGuiBackendFlags_HasGamepad`: supports gamepad and currently has one connected.
|
||||||
|
- `ImGuiBackendFlags_HasMouseCursors`: supports honoring GetMouseCursor() value to change the OS cursor shape.
|
||||||
|
- `ImGuiBackendFlags_HasSetMousePos`: supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set).
|
||||||
|
- `ImGuiBackendFlags_PlatformHasViewports` supports multiple viewports. (multi-viewports only)
|
||||||
|
- `ImGuiBackendFlags_HasMouseHoveredViewport` supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag. If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under mouse position, as it doesn't know about foreign windows. (multi-viewports only)
|
||||||
|
|
||||||
|
**In your `ImGui_ImplXXX_NewFrame()` function:**
|
||||||
|
- Set `io.DeltaTime` to the time elapsed (in seconds) since last frame.
|
||||||
|
- Set `io.DisplaySize` to your window size.
|
||||||
|
- Set `io.DisplayFrameBufferSize` to your window pixel density (macOS/iOS only).
|
||||||
|
- Update mouse cursor shape is supported.
|
||||||
|
|
||||||
|
**In your `ImGui_ImplXXX_NewFrame()` function or event handlers:**
|
||||||
|
- **Mouse Support**
|
||||||
|
- Use `io.AddMousePosEvent()`, `io.AddMouseButtonEvent()`, `io.AddMouseWheelEvent()` to pass mouse events.
|
||||||
|
- Use `io.AddMouseSourceEvent()` if you are able to distinguish Mouse from TouchScreen from Pen inputs. TouchScreen and Pen inputs requires different logic for some Dear ImGui features.
|
||||||
|
- Use `io.AddMouseViewportEvent()` to specify which viewport/OS window is being hovered by the mouse. Read instructions carefully as this is not as simple as it seems! (multi-viewports only)
|
||||||
|
- **Keyboard Support**
|
||||||
|
- Use `io.AddKeyEvent()` to pass key events.
|
||||||
|
- Use `io.AddInputCharacter()` to pass text/character events.
|
||||||
|
- **Gamepad Support**
|
||||||
|
- Use `io.AddKeyEvent()` and `io.AddKeyAnalogEvent()` to pass gamepad events, using `ImGuiKey_GamepadXXX` values.
|
||||||
|
- **Miscellaneous**
|
||||||
|
- Clipboard Support: setup `Platform_GetClipboardTextFn()`, `Platform_SetClipboardTextFn()` handlers in `ImGuiPlatformIO`.
|
||||||
|
- Open in Shell support: setup `Platform_OpenInShellFn()` handler in `ImGuiPlatformIO`.
|
||||||
|
- IME Support: setup `Platform_SetImeDataFn()` handler in `ImGuiPlatformIO`.
|
||||||
|
- Use `io.AddFocusEvent()` to notify when application window gets focused/unfocused.
|
||||||
|
- **Multi-viewport Support**
|
||||||
|
- Update monitor list if supported.
|
||||||
|
- Setup all required handlers in `ImGuiPlatformIO` to create/destroy/move/resize/title/focus/etc. windows.
|
||||||
|
|
||||||
|
### Rendering: Implementing your RenderDrawData function
|
||||||
|
|
||||||
|
Note: set `ImGuiBackendFlags_RendererHasVtxOffset` to signify your backend can handle rendering with a vertex offset (`ImDrawCmd::VtxOffset` field).
|
||||||
|
Otherwise, rendering will be limited to 64K vertices per window, which may be limiting for advanced plot.
|
||||||
|
As an alternative, you may also use `#define ImDrawIdx unsigned int` in your `imconfig.h` file to support 32-bit indices.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void MyImGuiBackend_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// TODO: Update textures.
|
||||||
|
// - Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// - This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates.
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
MyImGuiBackend_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// TODO: Setup render state:
|
||||||
|
// - Alpha-blending enabled
|
||||||
|
// - No backface culling
|
||||||
|
// - No depth testing, no depth writing
|
||||||
|
// - Scissor enabled
|
||||||
|
MyEngineSetupenderState();
|
||||||
|
|
||||||
|
// TODO: Setup texture sampling state
|
||||||
|
// - 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 orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
|
||||||
|
|
||||||
|
// TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color.
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui
|
||||||
|
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback)
|
||||||
|
{
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
MyEngineSetupenderState();
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
// - Clipping coordinates are provided in imgui coordinates space:
|
||||||
|
// - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size
|
||||||
|
// - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values.
|
||||||
|
// - In the interest of supporting multi-viewport applications (see 'docking' branch on github),
|
||||||
|
// always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space.
|
||||||
|
// - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min)
|
||||||
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We are using scissoring to clip some objects. All low-level graphics API should support it.
|
||||||
|
// - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches
|
||||||
|
// (some elements visible outside their bounds) but you can fix that once everything else works!
|
||||||
|
MyEngineSetScissor(clip_min.x, clip_min.y, clip_max.x, clip_max.y);
|
||||||
|
|
||||||
|
// The texture for the draw call is specified by pcmd->GetTexID().
|
||||||
|
// The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization.
|
||||||
|
MyEngineBindTexture((MyTexture*)pcmd->GetTexID());
|
||||||
|
|
||||||
|
// Render 'pcmd->ElemCount/3' indexed triangles.
|
||||||
|
// By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices.
|
||||||
|
MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset, vtx_buffer, pcmd->VtxOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rendering: Adding support for `ImGuiBackendFlags_RendererHasTextures` (1.92+)
|
||||||
|
|
||||||
|
Version [1.92.0](https://github.com/ocornut/imgui/releases/tag/v1.92.0) (June 2025), added texture support in Rendering Backends, which is the backbone for supporting dynamic font scaling among other things.
|
||||||
|
|
||||||
|
**In order to move forward and take advantage of all new features, support for `ImGuiBackendFlags_RendererHasTextures` will likely be REQUIRED for all backends before June 2026.**
|
||||||
|
|
||||||
|
`ImFontAtlas` functions such as `Build()`, `GetTexDataAsRGBA32()`, `GetTexDataAsAlpha8()`, `SetTexID()`, `IsBuilt()` were obsoleted in favor if iterating a `Textures[]` array and updating their state when requested by Dear ImGui.
|
||||||
|
|
||||||
|
**TD;DR: List of commits which added support for `ImGuiBackendFlags_RendererHasTextures` in standard backends:**
|
||||||
|
|
||||||
|
- Allegro5: [ee8941e](https://github.com/ocornut/imgui/commit/ee8941e) (+35 lines)
|
||||||
|
- DirectX9: [75efba7](https://github.com/ocornut/imgui/commit/75efba7) (+48 lines)
|
||||||
|
- DirectX10: [2d2b1bc](https://github.com/ocornut/imgui/commit/2d2b1bc) (+40 lines)
|
||||||
|
- DirectX11: [372fd27](https://github.com/ocornut/imgui/commit/372fd27) (+40 lines)
|
||||||
|
- DirectX12: [eefe5d5](https://github.com/ocornut/imgui/commit/eefe5d5) (+87 lines)
|
||||||
|
- Metal: [26c017d](https://github.com/ocornut/imgui/commit/26c017d) (+55 lines)
|
||||||
|
- OpenGL Legacy: [0430c55](https://github.com/ocornut/imgui/commit/0430c55) (+25 lines)
|
||||||
|
- OpenGL3/WebGL/ES: [dbb91a5](https://github.com/ocornut/imgui/commit/dbb91a5) (+47 lines)
|
||||||
|
- SDL_Renderer2: [9fa65cd](https://github.com/ocornut/imgui/commit/9fa65cd) (+20 lines)
|
||||||
|
- SDL_Renderer3: [e538883](https://github.com/ocornut/imgui/commit/e538883) (+19 lines)
|
||||||
|
- SDL_GPU: [16fe666](https://github.com/ocornut/imgui/commit/16fe666) (+41 lines)
|
||||||
|
- Vulkan: [abe294b](https://github.com/ocornut/imgui/commit/abe294b) (+33 lines)
|
||||||
|
- WGPU: [571dae9](https://github.com/ocornut/imgui/commit/571dae9) (+30 lines)
|
||||||
|
|
||||||
|
**Instructions:**
|
||||||
|
|
||||||
|
- Set `ImGuiBackendFlags_RendererHasTextures` to signify your backend can handle the feature.
|
||||||
|
- During rendering, e.g. in your RenderDrawData function, iterate `ImDrawData->Textures` array and process all textures.
|
||||||
|
- During shutdown, iterate the `ImGui::GetPlatformIO().Textures` and destroy all textures.
|
||||||
|
- (Both arrays are `ImVector<ImTextureData*>`. They are only in different location because: to allow advanced users to perform multi-threaded rendering, we store a pointer to the texture list in ImDrawData, with the aim that multi-threaded rendering users replace it with their own pointer.)
|
||||||
|
|
||||||
|
Pseudo-code for processing a texture:
|
||||||
|
```cpp
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
MyImGuiBackend_UpdateTexture(tex);
|
||||||
|
```
|
||||||
|
```cpp
|
||||||
|
void MyImGuiBackend_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create texture based on tex->Width, tex->Height.
|
||||||
|
// - Most backends only support tex->Format == ImTextureFormat_RGBA32.
|
||||||
|
// - Backends for particularly memory constrainted platforms may support tex->Format == ImTextureFormat_Alpha8.
|
||||||
|
|
||||||
|
// Upload all texture pixels
|
||||||
|
// - Read from our CPU-side copy of the texture and copy to your graphics API.
|
||||||
|
// - Use tex->Width, tex->Height, tex->GetPixels(), tex->GetPixelsAt(), tex->GetPitch() as needed.
|
||||||
|
|
||||||
|
// Store your data, and acknowledge creation.
|
||||||
|
tex->SetTexID(xxxx); // Specify backend-specific ImTextureID identifier which will be stored in ImDrawCmd.
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
tex->BackendUserData = xxxx; // Store more backend data if needed (most backend allocate a small texture to store data in there)
|
||||||
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Upload a rectangle of pixels to the existing texture
|
||||||
|
// - We only ever write to textures regions which have never been used before!
|
||||||
|
// - Use tex->TexID or tex->BackendUserData to retrieve your stored data.
|
||||||
|
// - Use tex->UpdateRect.x/y, tex->UpdateRect.w/h to obtain the block position and size.
|
||||||
|
// - Use tex->Updates[] to obtain individual sub-regions within tex->UpdateRect. Not recommended.
|
||||||
|
// - Read from our CPU-side copy of the texture and copy to your graphics API.
|
||||||
|
// - Use tex->Width, tex->Height, tex->GetPixels(), tex->GetPixelsAt(), tex->GetPitch() as needed.
|
||||||
|
|
||||||
|
// Acknowledge update
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
{
|
||||||
|
// If you use staged rendering and have in-flight renders, changed tex->UnusedFrames > 0 check to higher count as needed e.g. > 2
|
||||||
|
|
||||||
|
// Destroy texture
|
||||||
|
// - Use tex->TexID or tex->BackendUserData to retrieve your stored data.
|
||||||
|
// - Destroy texture in your graphics API.
|
||||||
|
|
||||||
|
// Acknowledge destruction
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Refer to "List of commits which added support for `ImGuiBackendFlags_RendererHasTextures` in standard backends" above for concrete examples of this.
|
||||||
|
|||||||
2117
docs/CHANGELOG.txt
2117
docs/CHANGELOG.txt
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@ Only if you:
|
|||||||
|
|
||||||
Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue.
|
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
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ Steps:
|
|||||||
- **Please INCLUDE CODE. Provide a Minimal, Complete, and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem**. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/../main.cpp) or demo (imgui_demo.cpp) to understand and reproduce it. **Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it**. Please test your shortened code to ensure it exhibits the problem. **Often while creating the MCVE you will solve the problem!** Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
|
- **Please INCLUDE CODE. Provide a Minimal, Complete, and Verifiable Example ([MCVE](https://stackoverflow.com/help/mcve)) to demonstrate your problem**. An ideal submission includes a small piece of code that anyone can paste into one of the examples applications (examples/../main.cpp) or demo (imgui_demo.cpp) to understand and reproduce it. **Narrowing your problem to its shortest and purest form is the easiest way to understand it, explain it and fix it**. Please test your shortened code to ensure it exhibits the problem. **Often while creating the MCVE you will solve the problem!** Many questions that are missing a standalone verifiable example are missing the actual cause of their issue in the description, which ends up wasting everyone's time.
|
||||||
- **Attach screenshots (or GIF/video) to clarify the context**. They often convey useful information that is omitted by the description. You can drag pictures/files in the message edit box. Avoid using 3rd party image hosting services, prefer the long-term longevity of GitHub attachments (you can drag pictures into your post). On Windows, you can use [ScreenToGif](https://www.screentogif.com/) to easily capture .gif files.
|
- **Attach screenshots (or GIF/video) to clarify the context**. They often convey useful information that is omitted by the description. You can drag pictures/files in the message edit box. Avoid using 3rd party image hosting services, prefer the long-term longevity of GitHub attachments (you can drag pictures into your post). On Windows, you can use [ScreenToGif](https://www.screentogif.com/) to easily capture .gif files.
|
||||||
- **If you are discussing an assert or a crash, please provide a debugger callstack**. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful.
|
- **If you are discussing an assert or a crash, please provide a debugger callstack**. Never state "it crashes" without additional information. If you don't know how to use a debugger and retrieve a callstack, learning about it will be useful.
|
||||||
- **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled.
|
- **Please make sure that your project has asserts enabled.** Calls to IM_ASSERT() are scattered in the code to help catch common issues. When an assert is triggered read the comments around it. By default IM_ASSERT() calls the standard assert() function. To verify that your asserts are enabled, add the line `IM_ASSERT(false);` in your main() function. Your application should display an error message and abort. If your application doesn't report an error, your asserts are disabled.
|
||||||
- Please state if you have made substantial modifications to your copy of Dear ImGui or the back-end.
|
- Please state if you have made substantial modifications to your copy of Dear ImGui or the back-end.
|
||||||
- If you are not calling Dear ImGui directly from C++, please provide information about your Language and the wrapper/binding you are using.
|
- If you are not calling Dear ImGui directly from C++, please provide information about your Language and the wrapper/binding you are using.
|
||||||
- Be mindful that messages are being sent to the mailbox of "Watching" users. Try to proofread your messages before sending them. Edits are not seen by those users unless they browse the site.
|
- Be mindful that messages are being sent to the mailbox of "Watching" users. Try to proofread your messages before sending them. Edits are not seen by those users unless they browse the site.
|
||||||
@@ -65,17 +65,17 @@ If you have been using Dear ImGui for a while or have been using C/C++ for sever
|
|||||||
|
|
||||||
## How to open a Pull Request
|
## How to open a Pull Request
|
||||||
|
|
||||||
- **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
- **Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance.** PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||||
- Many PRs are useful to demonstrate a need and a possible solution but aren't adequate for merging (causing other issues, not seeing other aspects of the big picture, etc.). In doubt, don't hesitate to push a PR because that is always the first step toward pointing toward a problem, and finding the mergeable solution! Even if a PR stays unmerged for a long time, its presence can be useful for other users and helps toward finding a general solution.
|
- Many PRs are useful to demonstrate a need and a possible solution but aren't adequate for merging (causing other issues, not seeing other aspects of the big picture, etc.). In doubt, don't hesitate to push a PR because that is always the first step toward pointing toward a problem, and finding the mergeable solution! Even if a PR stays unmerged for a long time, its presence can be useful for other users and helps toward finding a general solution.
|
||||||
- **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/).
|
- **When adding a feature,** please describe the usage context (how you intend to use it, why you need it, etc.). Be mindful of [The XY Problem](http://xyproblem.info/).
|
||||||
- **When fixing a warning or compilation problem,** please post the compiler log and specify the compiler version and platform you are using.
|
- **When fixing a warning or compilation problem,** please post the compiler log and specify the compiler version and platform you are using.
|
||||||
- **Attach screenshots (or GIF/video) to clarify the context and demonstrate the feature at a glance.** You can drag pictures/files in the message edit box. Prefer the long-term longevity of GitHub attachments over 3rd party hosting (you can drag pictures into your post).
|
- **Attach screenshots (or GIF/video) to clarify the context and demonstrate the feature at a glance.** You can drag pictures/files in the message edit box. Prefer the long-term longevity of GitHub attachments over 3rd party hosting (you can drag pictures into your post).
|
||||||
- **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample).
|
- **Make sure your code follows the coding style already used in the codebase:** 4 spaces indentations (no tabs), `local_variable`, `FunctionName()`, `MemberName`, `// Text Comment`, `//CodeComment();`, C-style casts, etc.. We don't use modern C++ idioms and tend to use only a minimum of C++11 features. The applications under examples/ are generally less consistent because they sometimes try to mimic the coding style often adopted by a certain ecosystem (e.g. DirectX-related code tend to use the style of their sample).
|
||||||
- **Make sure you create a branch dedicated to the pull request**. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits).
|
- **Make sure you create a branch dedicated to the pull request**. In Git, 1 PR is associated to 1 branch. If you keep pushing to the same branch after you submitted the PR, your new commits will appear in the PR (we can still cherry-pick individual commits).
|
||||||
|
|
||||||
## Copyright / Contributor License Agreement
|
## Copyright / Contributor License Agreement
|
||||||
|
|
||||||
Any code you submit will become part of the repository and be distributed under the [Dear ImGui license](https://github.com/ocornut/imgui/blob/master/LICENSE.txt). By submitting code to the project you agree that the code is your work and that you can give it to the project.
|
Any code you submit will become part of the repository and be distributed under the [Dear ImGui license](https://github.com/ocornut/imgui/blob/master/LICENSE.txt). By submitting code to the project you agree that the code is your work and that you can give it to the project.
|
||||||
|
|
||||||
You also agree by submitting your code that you grant all transferrable rights to the code to the project maintainer, including for example re-licensing the code, modifying the code, and distributing it in source or binary forms. Specifically, this includes a requirement that you assign copyright to the project maintainer. For this reason, do not modify any copyright statements in files in any PRs.
|
You also agree by submitting your code that you grant all transferable rights to the code to the project maintainer, including for example re-licensing the code, modifying the code, and distributing it in source or binary forms. Specifically, this includes a requirement that you assign copyright to the project maintainer. For this reason, do not modify any copyright statements in files in any PRs.
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/EXAMP
|
|||||||
## Dear ImGui: Examples
|
## Dear ImGui: Examples
|
||||||
|
|
||||||
**The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of
|
**The [examples/](https://github.com/ocornut/imgui/blob/master/examples) folder example applications (standalone, ready-to-build) for variety of
|
||||||
platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder (see [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md)).
|
platforms and graphics APIs.** They all use standard backends from the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder (see [docs/BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md)).
|
||||||
|
|
||||||
The purpose of Examples is to showcase integration with backends, let you try Dear ImGui, and guide you toward
|
The purpose of Examples is to showcase integration with backends, let you try Dear ImGui, and guide you toward
|
||||||
integrating Dear ImGui in your own application/game/engine.
|
integrating Dear ImGui in your own application/game/engine.
|
||||||
@@ -58,7 +58,7 @@ Allegro 5 example. <BR>
|
|||||||
Android + OpenGL3 (ES) example. <BR>
|
Android + OpenGL3 (ES) example. <BR>
|
||||||
= main.cpp + imgui_impl_android.cpp + imgui_impl_opengl3.cpp
|
= main.cpp + imgui_impl_android.cpp + imgui_impl_opengl3.cpp
|
||||||
|
|
||||||
[example_apple_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_metal/) <BR>
|
[example_apple_metal/](https://github.com/ocornut/imgui/tree/master/examples/example_apple_metal/) <BR>
|
||||||
OSX & iOS + Metal example. <BR>
|
OSX & iOS + Metal example. <BR>
|
||||||
= main.m + imgui_impl_osx.mm + imgui_impl_metal.mm <BR>
|
= main.m + imgui_impl_osx.mm + imgui_impl_metal.mm <BR>
|
||||||
It is based on the "cross-platform" game template provided with Xcode as of Xcode 9.
|
It is based on the "cross-platform" game template provided with Xcode as of Xcode 9.
|
||||||
@@ -139,8 +139,8 @@ This support building with Emscripten and targeting WebGL.<BR>
|
|||||||
Prefer using that if you are using modern GL or WebGL in your application.
|
Prefer using that if you are using modern GL or WebGL in your application.
|
||||||
|
|
||||||
[example_sdl2_sdlrenderer2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_sdlrenderer2/) <BR>
|
[example_sdl2_sdlrenderer2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_sdlrenderer2/) <BR>
|
||||||
SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL2 (most graphics backends are supported underneath) <BR>
|
SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL2 example.<BR>
|
||||||
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer.cpp <BR>
|
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp <BR>
|
||||||
This requires SDL 2.0.18+ (released November 2021) <BR>
|
This requires SDL 2.0.18+ (released November 2021) <BR>
|
||||||
|
|
||||||
[example_sdl2_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_vulkan/) <BR>
|
[example_sdl2_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_vulkan/) <BR>
|
||||||
@@ -149,6 +149,30 @@ SDL2 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
|||||||
This is quite long and tedious, because: Vulkan. <BR>
|
This is quite long and tedious, because: Vulkan. <BR>
|
||||||
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.
|
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.
|
||||||
|
|
||||||
|
[example_sdl3_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_metal/) <BR>
|
||||||
|
SDL3 + Metal example (Mac). <BR>
|
||||||
|
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_metal.mm <BR>
|
||||||
|
|
||||||
|
[example_sdl3_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_opengl3/) <BR>
|
||||||
|
SDL3 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR>
|
||||||
|
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_opengl3.cpp <BR>
|
||||||
|
This uses more modern GL calls and custom shaders. <BR>
|
||||||
|
This support building with Emscripten and targeting WebGL.<BR>
|
||||||
|
|
||||||
|
[example_sdl3_sdlgpu3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_sdlgpu3/) <BR>
|
||||||
|
SDL3 (Win32, Mac, Linux, etc.) + SDL_GPU for SDL3 example.<BR>
|
||||||
|
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp <BR>
|
||||||
|
|
||||||
|
[example_sdl3_sdlrenderer3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_sdlrenderer3/) <BR>
|
||||||
|
SDL3 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL3 example.<BR>
|
||||||
|
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp <BR>
|
||||||
|
|
||||||
|
[example_sdl3_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_vulkan/) <BR>
|
||||||
|
SDL3 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
||||||
|
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_vulkan.cpp <BR>
|
||||||
|
This is quite long and tedious, because: Vulkan. <BR>
|
||||||
|
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.
|
||||||
|
|
||||||
[example_win32_directx9/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx9/) <BR>
|
[example_win32_directx9/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx9/) <BR>
|
||||||
DirectX9 example, Windows only. <BR>
|
DirectX9 example, Windows only. <BR>
|
||||||
= main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp
|
= main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp
|
||||||
@@ -167,15 +191,19 @@ DirectX12 example, Windows only. <BR>
|
|||||||
This is quite long and tedious, because: DirectX12.
|
This is quite long and tedious, because: DirectX12.
|
||||||
|
|
||||||
[example_win32_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_opengl3/) <BR>
|
[example_win32_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_opengl3/) <BR>
|
||||||
Raw Windows + OpenGL3 + example (modern, programmable pipeline) <BR>
|
Raw Windows + OpenGL3 example (modern, programmable pipeline) <BR>
|
||||||
= main.cpp + imgui_impl_win32.cpp + imgui_impl_opengl3.cpp <BR>
|
= main.cpp + imgui_impl_win32.cpp + imgui_impl_opengl3.cpp <BR>
|
||||||
|
|
||||||
|
[example_win32_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_vulkan/) <BR>
|
||||||
|
Raw Windows + Vulkan example <BR>
|
||||||
|
= main.cpp + imgui_impl_win32.cpp + imgui_impl_vulkan.cpp <BR>
|
||||||
|
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
**Building**
|
**Building**
|
||||||
|
|
||||||
Unfortunately nowadays it is still tedious to create and maintain portable build files using external
|
Unfortunately, nowadays it is still tedious to create and maintain portable build files using external
|
||||||
libraries (the kind we're using here to create a window and render 3D triangles) without relying on
|
libraries (the kind we're using here to create a window and render 3D triangles) without relying on
|
||||||
third party software and build systems. For most examples here we choose to provide:
|
third party software and build systems. For most examples here we choose to provide:
|
||||||
- Makefiles for Linux/OSX
|
- Makefiles for Linux/OSX
|
||||||
@@ -191,22 +219,22 @@ If you are interested in using Cmake to build and links examples, see:
|
|||||||
|
|
||||||
**About mouse cursor latency**
|
**About mouse cursor latency**
|
||||||
|
|
||||||
Dear ImGui has no particular extra lag for most behaviors,
|
Dear ImGui does not introduce significant extra lag for most behaviors,
|
||||||
e.g. the last value passed to 'io.AddMousePosEvent()' before NewFrame() will result in windows being moved
|
e.g. the last value passed to 'io.AddMousePosEvent()' before NewFrame() will result in windows being moved
|
||||||
to the right spot at the time of EndFrame()/Render(). At 60 FPS your experience should be pleasant.
|
to the right spot at the time of EndFrame()/Render(). At 60 FPS your experience should be pleasant.
|
||||||
|
|
||||||
However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated
|
However, consider that OS mouse cursors are typically rendered through a very specific hardware-accelerated
|
||||||
path and will feel smoother than the majority of contents rendered via regular graphics API (including,
|
path, which makes them feel smoother than the majority of content rendered via regular graphics API (including,
|
||||||
but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane
|
but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane
|
||||||
as the mouse, that disconnect may be jarring to particularly sensitive users.
|
as the mouse, that disconnect may be jarring to particularly sensitive users.
|
||||||
You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor
|
You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor
|
||||||
using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a
|
using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a
|
||||||
regularly rendered software cursor.
|
regularly rendered software cursor.
|
||||||
However, rendering a mouse cursor at 60 FPS will feel sluggish so you likely won't want to enable that at
|
However, rendering a mouse cursor at 60 FPS will feel sluggish, so you likely won't want to enable that at
|
||||||
all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_
|
all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_
|
||||||
when an interactive drag is in progress.
|
when an interactive drag is in progress.
|
||||||
|
|
||||||
Note that some setup or GPU drivers are likely to be causing extra display lag depending on their settings.
|
Note that some setup configurations or GPU drivers may introduce additional display lag depending on their settings.
|
||||||
If you feel that dragging windows feels laggy and you are not sure what the cause is: try to build a simple
|
If you notice that dragging windows is laggy and you are not sure what the cause is: try drawing a simple
|
||||||
drawing a flat 2D shape directly under the mouse cursor!
|
2D shape directly under the mouse cursor to help identify the issue!
|
||||||
|
|
||||||
|
|||||||
180
docs/FAQ.md
180
docs/FAQ.md
@@ -19,12 +19,13 @@ or view this file with any Markdown viewer.
|
|||||||
| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-my-application)** |
|
| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-my-application)** |
|
||||||
| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) |
|
| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) |
|
||||||
| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) |
|
| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) |
|
||||||
|
| [How can I create my own backend?](q-how-can-i-create-my-own-backend)
|
||||||
| [I integrated Dear ImGui in my engine and little squares are showing instead of text...](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) |
|
| [I integrated Dear ImGui in my engine and little squares are showing instead of text...](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) |
|
||||||
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
|
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
|
||||||
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
|
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
|
||||||
| **Q&A: Usage** |
|
| **Q&A: Usage** |
|
||||||
| **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>Why is the wrong widget reacting when I click on one?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** |
|
| **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<br>Why is the wrong widget reacting when I click on one?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?<br>How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** |
|
||||||
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
|
| [How can I display an image?](#q-how-can-i-display-an-image)<br>[What are ImTextureID/ImTextureRef?](#q-what-are-imtextureidimtextureref)|
|
||||||
| [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) |
|
| [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) |
|
||||||
| [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) |
|
| [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) |
|
||||||
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
|
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
|
||||||
@@ -92,8 +93,8 @@ Many projects are using this branch and it is kept in sync with master regularly
|
|||||||
### Q: How to get started?
|
### Q: How to get started?
|
||||||
|
|
||||||
Read [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). <BR>
|
Read [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started). <BR>
|
||||||
Read [EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md). <BR>
|
Read [docs/EXAMPLES.md](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md). <BR>
|
||||||
Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md). <BR>
|
Read [docs/BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md). <BR>
|
||||||
Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR>
|
Read `PROGRAMMER GUIDE` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp). <BR>
|
||||||
The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links.
|
The [Wiki](https://github.com/ocornut/imgui/wiki) is a hub to many resources and links.
|
||||||
|
|
||||||
@@ -159,9 +160,18 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Q: How can I create my own backend?
|
||||||
|
- See [docs/BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md).
|
||||||
|
- See Documentation at the top of imgui.cpp.
|
||||||
|
|
||||||
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
|
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
|
||||||
Your renderer backend is not using the font texture correctly or it hasn't been uploaded to the GPU.
|
Your renderer backend is not using the font texture correctly or it hasn't been uploaded to the GPU.
|
||||||
- If this happens using the standard backends: A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which **can if your texture atlas is too big**. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
|
- If this happens using standard backends (before 1.92): A) have you modified the font atlas after `ImGui_ImplXXX_NewFrame()`? B) maybe the texture failed to upload, which **can if your texture atlas is too big**. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
|
||||||
|
- If this happens using standard backends (after 1.92): please report.
|
||||||
- If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states.
|
- If this happens with a custom backend: make sure you have uploaded the font texture to the GPU, that all shaders are rendering states are setup properly (e.g. texture is bound). Compare your code to existing backends and use a graphics debugger such as [RenderDoc](https://renderdoc.org) to debug your rendering states.
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
@@ -233,7 +243,7 @@ for (int n = 0; n < 3; n++)
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
</pre>
|
</pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
A primer on labels and the ID Stack...
|
A primer on labels and the ID Stack...
|
||||||
@@ -375,41 +385,92 @@ node open/closed state differently. See what makes more sense in your situation!
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Q: How can I display an image? What is ImTextureID, how does it work?
|
### Q: How can I display an image?
|
||||||
|
### Q: What are ImTextureID/ImTextureRef?
|
||||||
|
|
||||||
Short explanation:
|
**Short explanation:**
|
||||||
- Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki).
|
|
||||||
- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures.
|
- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures.
|
||||||
- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as ImTextureID (void*) value.
|
- To load and display your own textures, refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki).
|
||||||
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason).
|
- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as an opaque ImTextureID value.
|
||||||
|
- By default ImTextureID can store up to 64-bits. You may `#define` it to a custom type/structure if you need.
|
||||||
|
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason), but the examples linked above may be useful references.
|
||||||
|
|
||||||
|
**Details:**
|
||||||
|
|
||||||
|
1.92 introduced `ImTextureRef` in June 2025.
|
||||||
|
- All drawing functions using `ImTextureID` were changed to use `ImTextureRef`.
|
||||||
|
- You can trivially create a `ImTextureRef` from a `ImTextureID`.
|
||||||
|
- **If you use Image functions with textures that you have loaded/created yourself, you will mostly likely only ever store/manipulate `ImTextureID` and then pass them as `ImTextureRef`.**
|
||||||
|
- You only NEED to manipulate `ImTextureRef` when dealing with textures managed by the backend itself, aka mainly the atlas texture for now.
|
||||||
|
- We intentionally do not provide an implicit `ImTextureRef` -> `ImTextureID` cast operator because it is technically lossy to convert ImTextureRef to ImTextureID before rendering.
|
||||||
|
|
||||||
|
**ImTextureID = backend specific, low-level identifier for a texture uploaded in GPU/graphics system.**
|
||||||
|
```cpp
|
||||||
|
#ifndef ImTextureID
|
||||||
|
typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or integer). A majority of backends are ok with that.
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
- When a Rendered Backend creates a texture, it store its native identifier into a ImTextureID value (e.g. Used by DX11 backend to a `ID3D11ShaderResourceView*`; Used by OpenGL backends to store `GLuint`; Used by SDLGPU backend to store a `SDL_GPUTextureSamplerBinding*`, etc.).
|
||||||
|
- User may submit their own textures to e.g. `ImGui::Image()` function by passing this value.
|
||||||
|
- During the rendering loop, the Renderer Backend retrieve the ImTextureID, which stored inside a ImTextureRef, which is stored inside ImDrawCmd.
|
||||||
|
- Compile-time type configuration:
|
||||||
|
- To use something other than a 64-bit value: add '#define ImTextureID MyTextureType*' in your imconfig.h file.
|
||||||
|
- This can be whatever to you want it to be! read the FAQ entry about textures for details.
|
||||||
|
- You may decide to store a higher-level structure containing texture, sampler, shader etc. with various constructors if you like. You will need to implement ==/!= operators.
|
||||||
|
|
||||||
|
**ImTextureRef = higher-level identifier for a texture.**
|
||||||
|
```cpp
|
||||||
|
// Store a ImTextureID _or_ a ImTextureData*.
|
||||||
|
struct ImTextureRef
|
||||||
|
{
|
||||||
|
ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; }
|
||||||
|
ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; }
|
||||||
|
inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; }
|
||||||
|
|
||||||
|
// Members (either are set, never both!)
|
||||||
|
ImTextureData* _TexData; // A texture, generally owned by a ImFontAtlas. Will convert to ImTextureID during render loop, after texture has been uploaded.
|
||||||
|
ImTextureID _TexID; // _OR_ Low-level backend texture identifier, if already uploaded or created by user/app. Generally provided to e.g. ImGui::Image() calls.
|
||||||
|
};
|
||||||
|
```
|
||||||
|
- The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||||
|
- This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||||
|
- This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||||
|
- When a texture is created by user code (e.g. custom images), we directly store the low-level `ImTextureID`.
|
||||||
|
- Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||||
|
- When a texture is created by the backend, we store a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened.
|
||||||
|
- To create a `ImTextureRef` from a `ImTextureData*` you can use `ImTextureData::GetTexRef()`.
|
||||||
|
We intentionally do not provide an `ImTextureRef` constructor for this: we don't expect this to be frequently useful to the end-user, and it would be erroneously called by many legacy code.
|
||||||
|
- There is no constructor to create a `ImTextureRef` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||||
|
- If you want to bind the current atlas when using custom rectangles, you can use `io.Fonts->TexRef`.
|
||||||
|
- Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }`
|
||||||
|
|
||||||
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
|
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
|
||||||
|
|
||||||
Long explanation:
|
Long explanation:
|
||||||
- Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame, those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder, we provide functions for popular graphics APIs (OpenGL, DirectX, etc.).
|
- Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame, those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder, we provide functions for popular graphics APIs (OpenGL, DirectX, etc.).
|
||||||
- Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API.
|
- Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API.
|
||||||
We carry the information to identify a "texture" in the ImTextureID type.
|
We carry the information to identify a "texture" in the ImTextureID type, which itself tends to be stored inside a ImTextureRef.
|
||||||
ImTextureID is nothing more than a void*, aka 4/8 bytes worth of data: just enough to store one pointer or integer of your choice.
|
ImTextureID default to ImU64 aka 8 bytes worth of data: just enough to store one pointer or integer of your choice.
|
||||||
Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely passes ImTextureID values until they reach your rendering function.
|
Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely passes values until they reach your rendering function.
|
||||||
- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using:
|
- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using:
|
||||||
```cpp
|
```cpp
|
||||||
OpenGL:
|
OpenGL:
|
||||||
- ImTextureID = GLuint
|
- ImTextureID should contains 'GLuint' (GL texture identifier).
|
||||||
- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp
|
- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp
|
||||||
```
|
```
|
||||||
```cpp
|
```cpp
|
||||||
DirectX9:
|
DirectX9:
|
||||||
- ImTextureID = LPDIRECT3DTEXTURE9
|
- ImTextureID should contain a 'LPDIRECT3DTEXTURE9' (pointer).
|
||||||
- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp
|
- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp
|
||||||
```
|
```
|
||||||
```cpp
|
```cpp
|
||||||
DirectX11:
|
DirectX11:
|
||||||
- ImTextureID = ID3D11ShaderResourceView*
|
- ImTextureID should contain a 'ID3D11ShaderResourceView*' (pointer)
|
||||||
- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp
|
- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp
|
||||||
```
|
```
|
||||||
```cpp
|
```cpp
|
||||||
DirectX12:
|
DirectX12:
|
||||||
- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE
|
- ImTextureID should contain a 'D3D12_GPU_DESCRIPTOR_HANDLE' (always 64-bits)
|
||||||
- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp
|
- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp
|
||||||
```
|
```
|
||||||
For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID.
|
For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID.
|
||||||
@@ -421,14 +482,14 @@ If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a
|
|||||||
|
|
||||||
User code may do:
|
User code may do:
|
||||||
```cpp
|
```cpp
|
||||||
// Cast our texture type to ImTextureID / void*
|
// Cast our texture type to ImTextureID
|
||||||
MyTexture* texture = g_CoffeeTableTexture;
|
MyTexture* texture = g_CoffeeTableTexture;
|
||||||
ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height));
|
ImGui::Image((ImTextureID)(intptr_t)texture, ImVec2(texture->Width, texture->Height));
|
||||||
```
|
```
|
||||||
The renderer function called after ImGui::Render() will receive that same value that the user code passed:
|
The renderer function called after ImGui::Render() will receive that same value that the user code passed:
|
||||||
```cpp
|
```cpp
|
||||||
// Cast ImTextureID / void* stored in the draw command as our texture type
|
// Cast ImTextureID stored in the draw command as our texture type
|
||||||
MyTexture* texture = (MyTexture*)pcmd->GetTexID();
|
MyTexture* texture = (MyTexture*)(intptr_t)pcmd->GetTexID();
|
||||||
MyEngineBindTexture2D(texture);
|
MyEngineBindTexture2D(texture);
|
||||||
```
|
```
|
||||||
Once you understand this design, you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui.
|
Once you understand this design, you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui.
|
||||||
@@ -437,19 +498,19 @@ If you want to display an image file (e.g. PNG file) on the screen, please refer
|
|||||||
|
|
||||||
Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11.
|
Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11.
|
||||||
|
|
||||||
C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTextureID / void*, and vice-versa.
|
C/C++ tip: a u64 is 8 bytes. You may safely store any pointer or integer into it by casting your value to ImTextureID, and vice-versa.
|
||||||
Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID / void*.
|
Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID.
|
||||||
Here are some examples:
|
Here are some examples:
|
||||||
```cpp
|
```cpp
|
||||||
GLuint my_tex = XXX;
|
GLuint my_tex = XXX;
|
||||||
void* my_void_ptr;
|
ImTextureID my_imtexid;
|
||||||
my_void_ptr = (void*)(intptr_t)my_tex; // cast a GLuint into a void* (we don't take its address! we literally store the value inside the pointer)
|
my_imtexid = (ImTextureID)(intptr_t)my_tex; // cast a GLuint into a ImTextureID (we don't take its address! we just copy the address)
|
||||||
my_tex = (GLuint)(intptr_t)my_void_ptr; // cast a void* into a GLuint
|
my_tex = (GLuint)(intptr_t)my_imtexid; // cast a ImTextureID into a GLuint
|
||||||
|
|
||||||
ID3D11ShaderResourceView* my_dx11_srv = XXX;
|
ID3D11ShaderResourceView* my_dx11_srv = XXX;
|
||||||
void* my_void_ptr;
|
ImTextureID my_imtexid;
|
||||||
my_void_ptr = (void*)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque void*
|
my_imtexid = (ImTextureID)(intptr_t)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque ImTextureID
|
||||||
my_dx11_srv = (ID3D11ShaderResourceView*)my_void_ptr; // cast a void* into a ID3D11ShaderResourceView*
|
my_dx11_srv = (ID3D11ShaderResourceView*)(intptr_t)_my_imtexid; // cast a ImTextureID into a ID3D11ShaderResourceView*
|
||||||
```
|
```
|
||||||
Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated.
|
Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated.
|
||||||
|
|
||||||
@@ -538,30 +599,50 @@ ImGui::End();
|
|||||||
|
|
||||||
### Q: How should I handle DPI in my application?
|
### Q: How should I handle DPI in my application?
|
||||||
|
|
||||||
The short answer is: obtain the desired DPI scale, load your fonts resized with that scale (always round down fonts size to the nearest integer), and scale your Style structure accordingly using `style.ScaleAllSizes()`.
|
Since 1.92 (June 2025) fonts may be dynamically used at any size.
|
||||||
|
|
||||||
Your application may want to detect DPI change and reload the fonts and reset style between frames.
|
**Scaling fonts**
|
||||||
|
|
||||||
Your ui code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
|
To change font size:
|
||||||
|
```cpp
|
||||||
|
ImGui::PushFont(NULL, 42.0f);
|
||||||
|
```
|
||||||
|
To change font and font size:
|
||||||
|
```cpp
|
||||||
|
ImGui::PushFont(new_font, 42.0f);
|
||||||
|
```
|
||||||
|
To scale all fonts:
|
||||||
|
```cpp
|
||||||
|
style.FontScaleDpi = 2.0f;
|
||||||
|
```
|
||||||
|
In `docking` branch or with multi-viewports:
|
||||||
|
```cpp
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
||||||
Down the line Dear ImGui will provide a variety of standardized reference values to facilitate using this.
|
**Scaling style** (paddings, spacings, thicknesses)
|
||||||
|
|
||||||
Applications in the `examples/` folder are not DPI aware partly because they are unable to load a custom font from the file-system (may change that in the future).
|
This is still massively work in progress, expect turbulence.
|
||||||
|
Style values are currently not easily scalable dynamically.
|
||||||
|
For single viewport application you can call once:
|
||||||
|
```cpp
|
||||||
|
style.ScaleAllSizes(factor); // call once!
|
||||||
|
```
|
||||||
|
If you need to change the scaling factor, it is currently most practical to reset the style and call this again with a new value.
|
||||||
|
|
||||||
The reason DPI is not auto-magically solved in stock examples is that we don't yet have a satisfying solution for the "multi-dpi" problem (using the `docking` branch: when multiple viewport windows are over multiple monitors using different DPI scales). The current way to handle this on the application side is:
|
Your UI code should avoid using hardcoded constants for size and positioning. Prefer to express values as multiple of reference values such as `ImGui::GetFontSize()` or `ImGui::GetFrameHeight()`. So e.g. instead of seeing a hardcoded height of 500 for a given item/window, you may want to use `30*ImGui::GetFontSize()` instead.
|
||||||
- Create and maintain one font atlas per active DPI scale (e.g. by iterating `platform_io.Monitors[]` before `NewFrame()`).
|
|
||||||
- Hook `platform_io.OnChangedViewport()` to detect when a `Begin()` call makes a Dear ImGui window change monitor (and therefore DPI).
|
|
||||||
- In the hook: swap atlas, swap style with correctly sized one, and remap the current font from one atlas to the other (you may need to maintain a remapping table of your fonts at varying DPI scales).
|
|
||||||
|
|
||||||
This approach is relatively easy and functional but comes with two issues:
|
Down the line Dear ImGui will provide a variety of standardized reference values to facilitate using this. This is expected to happen during subsequent 1.92.x releases.
|
||||||
- It's not possibly to reliably size or position a window ahead of `Begin()` without knowing on which monitor it'll land.
|
|
||||||
- Style override may be lost during the `Begin()` call crossing monitor boundaries. You may need to do some custom scaling mumbo-jumbo if you want your `OnChangedViewport()` handler to preserve style overrides.
|
|
||||||
|
|
||||||
Please note that if you are not using multi-viewports with multi-monitors using different DPI scales, you can ignore that and use the simpler technique recommended at the top.
|
Applications in the `examples/` folder are partly DPI aware but they are unable to load a custom font from the file-system, so they look ugly (may change that in the future).
|
||||||
|
|
||||||
On Windows, in addition to scaling the font size (make sure to round to an integer) and using `style.ScaleAllSizes()`, you will need to inform Windows that your application is DPI aware. If this is not done, Windows will scale the application window and the UI text will be blurry. Potential solutions to indicate DPI awareness on Windows are:
|
The reason DPI is not auto-magically solved in stock examples is that we don't yet have a satisfying solution for the "multi-dpi" problem (using the `docking` branch: when multiple viewport windows are over multiple monitors using different DPI scales) specifically for the `ImGuiStyle` structure. Fonts are however now perfectly scalable.
|
||||||
|
|
||||||
- For SDL: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()``.
|
**On Windows, you need to inform Windows that your application is DPI aware!**
|
||||||
|
If this is not done, Windows will scale the application window and the UI text will be blurry. Potential solutions to indicate DPI awareness on Windows are:
|
||||||
|
- For SDL2: the flag `SDL_WINDOW_ALLOW_HIGHDPI` needs to be passed to `SDL_CreateWindow()` + call `::SetProcessDPIAware()`.
|
||||||
|
- For SDL3: the flag `SDL_WINDOW_HIGH_PIXEL_DENSITY` needs to be passed to `SDL_CreateWindow()`.
|
||||||
- For GLFW: this is done automatically.
|
- For GLFW: this is done automatically.
|
||||||
- For other Windows projects with other backends, or wrapper projects:
|
- For other Windows projects with other backends, or wrapper projects:
|
||||||
- We provide a `ImGui_ImplWin32_EnableDpiAwareness()` helper method in the Win32 backend.
|
- We provide a `ImGui_ImplWin32_EnableDpiAwareness()` helper method in the Win32 backend.
|
||||||
@@ -613,9 +694,12 @@ Use the font atlas to pack them into a single texture. Read [docs/FONTS.md](http
|
|||||||
---
|
---
|
||||||
|
|
||||||
### Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
### Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
|
||||||
When loading a font, pass custom Unicode ranges to specify the glyphs to load.
|
|
||||||
|
|
||||||
|
Since 1.92 (June 2025) and with an updated backend, it is not necessary to specify glyph ranges at all.
|
||||||
|
|
||||||
|
Before 1.92, when loading a font, pass custom Unicode ranges to specify the glyphs to load.
|
||||||
```cpp
|
```cpp
|
||||||
|
// [BEFORE 1.92]
|
||||||
// Add default Japanese ranges
|
// Add default Japanese ranges
|
||||||
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
||||||
|
|
||||||
@@ -639,8 +723,8 @@ Text input: it is up to your application to pass the right character code by cal
|
|||||||
The applications in examples/ are doing that.
|
The applications in examples/ are doing that.
|
||||||
Windows: you can use the WM_CHAR or WM_UNICHAR or WM_IME_CHAR message (depending if your app is built using Unicode or MultiByte mode).
|
Windows: you can use the WM_CHAR or WM_UNICHAR or WM_IME_CHAR message (depending if your app is built using Unicode or MultiByte mode).
|
||||||
You may also use `MultiByteToWideChar()` or `ToUnicode()` to retrieve Unicode codepoints from MultiByte characters or keyboard state.
|
You may also use `MultiByteToWideChar()` or `ToUnicode()` to retrieve Unicode codepoints from MultiByte characters or keyboard state.
|
||||||
Windows: if your language is relying on an Input Method Editor (IME), you can write your HWND to ImGui::GetMainViewport()->PlatformHandleRaw
|
Windows: if your language is relying on an Input Method Editor (IME), you can write your HWND to `ImGui::GetMainViewport()->PlatformHandleRaw`
|
||||||
for the default implementation of GetPlatformIO().Platform_SetImeDataFn() to set your Microsoft IME position correctly.
|
for the default implementation of `GetPlatformIO().Platform_SetImeDataFn()` to set your Microsoft IME position correctly.
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
@@ -665,7 +749,7 @@ You may take a look at:
|
|||||||
|
|
||||||
Yes. People have written game editors, data browsers, debuggers, profilers, and all sorts of non-trivial tools with the library. In my experience, the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library.
|
Yes. People have written game editors, data browsers, debuggers, profilers, and all sorts of non-trivial tools with the library. In my experience, the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library.
|
||||||
|
|
||||||
Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient, and powerful.
|
Dear ImGui is very programmer-centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient, and powerful.
|
||||||
|
|
||||||
Dear ImGui is built to be efficient and scalable toward the needs for AAA-quality applications running all day. The IMGUI paradigm offers different opportunities for optimization than the more typical RMGUI paradigm.
|
Dear ImGui is built to be efficient and scalable toward the needs for AAA-quality applications running all day. The IMGUI paradigm offers different opportunities for optimization than the more typical RMGUI paradigm.
|
||||||
|
|
||||||
|
|||||||
154
docs/FONTS.md
154
docs/FONTS.md
@@ -2,7 +2,7 @@ _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/FONTS
|
|||||||
|
|
||||||
## Dear ImGui: Using Fonts
|
## Dear ImGui: Using Fonts
|
||||||
|
|
||||||
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer),
|
The code in imgui.cpp embeds a copy of [ProggyClean.ttf](http://proggyfonts.net) (by Tristan Grimmer),
|
||||||
a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions.
|
a 13 pixels high, pixel-perfect font used by default. We embed it in the source code so you can use Dear ImGui without any file system access. ProggyClean does not scale smoothly, therefore it is recommended that you load your own file when using Dear ImGui in an application aiming to look nice and wanting to support multiple resolutions.
|
||||||
|
|
||||||
You may also load external .TTF/.OTF files.
|
You may also load external .TTF/.OTF files.
|
||||||
@@ -12,11 +12,13 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
|
|||||||
|
|
||||||
## Index
|
## Index
|
||||||
- [Troubleshooting](#troubleshooting)
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [New! Dynamic Fonts system in 1.92 (June 2025)](#new-dynamic-fonts-system-in-192-june-2025)
|
||||||
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
|
- [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application)
|
||||||
- [Fonts Loading Instructions](#fonts-loading-instructions)
|
- [Fonts Loading Instructions](#fonts-loading-instructions)
|
||||||
- [Loading Font Data from Memory](#loading-font-data-from-memory)
|
- [Loading Font Data from Memory](#loading-font-data-from-memory)
|
||||||
- [Loading Font Data Embedded In Source Code](#loading-font-data-embedded-in-source-code)
|
- [Loading Font Data Embedded In Source Code](#loading-font-data-embedded-in-source-code)
|
||||||
- [Using Icon Fonts](#using-icon-fonts)
|
- [Using Icon Fonts](#using-icon-fonts)
|
||||||
|
- [Excluding Overlapping Ranges](#excluding-overlapping-ranges)
|
||||||
- [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype)
|
- [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype)
|
||||||
- [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis)
|
- [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis)
|
||||||
- [Using Custom Glyph Ranges](#using-custom-glyph-ranges)
|
- [Using Custom Glyph Ranges](#using-custom-glyph-ranges)
|
||||||
@@ -35,7 +37,7 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
|
|||||||
|
|
||||||
### (1) Invalid filename due to use of `\` or unexpected working directory.
|
### (1) Invalid filename due to use of `\` or unexpected working directory.
|
||||||
|
|
||||||
See [About Filenames](#about-filenames). AddFontXXX functions should assert if the filename is incorrect.
|
See [About Filenames](#about-filenames). AddFontXXX() functions should assert if the filename is incorrect.
|
||||||
|
|
||||||
### (2) Invalid UTF-8 encoding of your non-ASCII strings.
|
### (2) Invalid UTF-8 encoding of your non-ASCII strings.
|
||||||
|
|
||||||
@@ -43,14 +45,18 @@ See [About UTF-8 Encoding](#about-utf-8-encoding). Use the encoding viewer to co
|
|||||||
|
|
||||||
### (3) Missing glyph ranges.
|
### (3) Missing glyph ranges.
|
||||||
|
|
||||||
You need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges.
|
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary.**
|
||||||
|
|
||||||
This is a current constraint of Dear ImGui (which we will lift in the future): when loading a font you need to specify which characters glyphs to load.
|
⏪ Before 1.92: you need to load a font with explicit glyph ranges if you want to use non-ASCII characters. See [Fonts Loading Instructions](#fonts-loading-instructions). Use [Debug Tools](#debug-tools) confirm loaded fonts and loaded glyph ranges.
|
||||||
|
|
||||||
|
This was a previous constraint of Dear ImGui (lifted in 1.92): when loading a font you need to specify which characters glyphs to load.
|
||||||
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
|
All loaded fonts glyphs are rendered into a single texture atlas ahead of time. Calling either of `io.Fonts->GetTexDataAsAlpha8()`, `io.Fonts->GetTexDataAsRGBA32()` or `io.Fonts->Build()` will build the atlas. This is generally called by the Renderer backend, e.g. `ImGui_ImplDX11_NewFrame()` calls it. **If you use custom glyphs ranges, make sure the array is persistent** and available during the calls to `GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build()`.
|
||||||
|
|
||||||
### (4) Font atlas texture fails to upload to GPU.
|
### (4) Font atlas texture fails to upload to GPU.
|
||||||
|
|
||||||
This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty white rectangles.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
|
🆕 **Since 1.92, with an up to date backend: atlas is built incrementally and dynamically resized, this is less likely to happen**
|
||||||
|
|
||||||
|
:rewind: This is often of byproduct of point 3. If you have large number of glyphs or multiple fonts, the texture may become too big for your graphics API. **The typical result of failing to upload a texture is if every glyph or everything appears as empty white rectangles.** Mind the fact that some graphics drivers have texture size limitation. If you are building a PC application, mind the fact that your users may use hardware with lower limitations than yours.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -60,9 +66,22 @@ Some solutions:
|
|||||||
- Reduce glyphs ranges by calculating them from source localization data.
|
- Reduce glyphs ranges by calculating them from source localization data.
|
||||||
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
|
You can use the `ImFontGlyphRangesBuilder` for this purpose and rebuilding your atlas between frames when new characters are needed. This will be the biggest win!
|
||||||
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
|
- Set `io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight;` to disable rounding the texture height to the next power of two.
|
||||||
- Set `io.Fonts.TexDesiredWidth` to specify a texture width to reduce maximum texture height (see comment in `ImFontAtlas::Build()` function).
|
|
||||||
|
|
||||||
Future versions of Dear ImGui should solve this problem.
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
## New! Dynamic Fonts system in 1.92 (June 2025)
|
||||||
|
|
||||||
|
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.
|
||||||
|
- `PushFont(NULL, new_size)` may be used anytime to change font size.
|
||||||
|
- 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.
|
||||||
|
- It is possible to plug a custom loader/backend to any font source.
|
||||||
|
|
||||||
|
See [#8465](https://github.com/ocornut/imgui/issues/8465) for more details.
|
||||||
|
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
@@ -85,6 +104,13 @@ io.Fonts->AddFontDefault();
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Load .TTF/.OTF file with:**
|
**Load .TTF/.OTF file with:**
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: passing a size is not necessary**
|
||||||
|
```cpp
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontFromFileTTF("font.ttf");
|
||||||
|
```
|
||||||
|
:rewind: **Before 1.92, or without an up to date backend:**
|
||||||
```cpp
|
```cpp
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
|
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
|
||||||
@@ -95,14 +121,14 @@ If you get an assert stating "Could not load font file!", your font filename is
|
|||||||
```cpp
|
```cpp
|
||||||
// Init
|
// Init
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
|
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf",);
|
||||||
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
|
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf");
|
||||||
```
|
```
|
||||||
|
|
||||||
In your application loop, select which font to use:
|
In your application loop, select which font to use:
|
||||||
```cpp
|
```cpp
|
||||||
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
|
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
|
||||||
ImGui::PushFont(font2);
|
ImGui::PushFont(font2, 0.0f); // change font, keep current size
|
||||||
ImGui::Text("Hello with another font");
|
ImGui::Text("Hello with another font");
|
||||||
ImGui::PopFont();
|
ImGui::PopFont();
|
||||||
```
|
```
|
||||||
@@ -110,13 +136,22 @@ ImGui::PopFont();
|
|||||||
**For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):**
|
**For advanced options create a ImFontConfig structure and pass it to the AddFont() function (it will be copied internally):**
|
||||||
```cpp
|
```cpp
|
||||||
ImFontConfig config;
|
ImFontConfig config;
|
||||||
config.OversampleH = 2;
|
config.OversampleH = 1.0f;
|
||||||
config.OversampleV = 1;
|
|
||||||
config.GlyphExtraSpacing.x = 1.0f;
|
|
||||||
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
|
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
|
||||||
```
|
```
|
||||||
|
|
||||||
**Combine multiple fonts into one:**
|
**Combine multiple fonts into one:**
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary.**
|
||||||
|
```cpp
|
||||||
|
// Load a first font
|
||||||
|
ImFont* font = io.Fonts->AddFontDefault();
|
||||||
|
ImFontConfig config;
|
||||||
|
config.MergeMode = true;
|
||||||
|
io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 0.0f, &config); // Merge into first font to add e.g. Asian characters
|
||||||
|
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 0.0f, &config); // Merge into first font to add Icons
|
||||||
|
```
|
||||||
|
:rewind: **Before 1.92, or without an up to date backend:**
|
||||||
```cpp
|
```cpp
|
||||||
// Load a first font
|
// Load a first font
|
||||||
ImFont* font = io.Fonts->AddFontDefault();
|
ImFont* font = io.Fonts->AddFontDefault();
|
||||||
@@ -134,6 +169,7 @@ io.Fonts->Build();
|
|||||||
|
|
||||||
**Add a fourth parameter to bake specific font ranges only:**
|
**Add a fourth parameter to bake specific font ranges only:**
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary. All the GetGlyphRangesXXX() functions are marked obsolete.**
|
||||||
```cpp
|
```cpp
|
||||||
// Basic Latin, Extended Latin
|
// Basic Latin, Extended Latin
|
||||||
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, nullptr, io.Fonts->GetGlyphRangesDefault());
|
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, nullptr, io.Fonts->GetGlyphRangesDefault());
|
||||||
@@ -148,10 +184,18 @@ See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create yo
|
|||||||
|
|
||||||
**Example loading and using a Japanese font:**
|
**Example loading and using a Japanese font:**
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend:**
|
||||||
|
```cpp
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf");
|
||||||
|
```
|
||||||
|
|
||||||
|
:rewind: **Before 1.92, or without an up to date backend:**
|
||||||
```cpp
|
```cpp
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
io.Fonts->AddFontFromFileTTF("NotoSansCJKjp-Medium.otf", 20.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
||||||
```
|
```
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
ImGui::Text(u8"こんにちは!テスト %d", 123);
|
ImGui::Text(u8"こんにちは!テスト %d", 123);
|
||||||
if (ImGui::Button(u8"ロード"))
|
if (ImGui::Button(u8"ロード"))
|
||||||
@@ -218,12 +262,24 @@ To refer to the icon UTF-8 codepoints from your C++ code, you may use those head
|
|||||||
|
|
||||||
So you can use `ICON_FA_SEARCH` as a string that will render as a "Search" icon.
|
So you can use `ICON_FA_SEARCH` as a string that will render as a "Search" icon.
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary. You can omit this parameter.**
|
||||||
Example Setup:
|
Example Setup:
|
||||||
```cpp
|
```cpp
|
||||||
// Merge icons into default tool font
|
// Merge icons into default tool font
|
||||||
#include "IconsFontAwesome.h"
|
#include "IconsFontAwesome.h"
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->AddFontDefault();
|
io.Fonts->AddFontDefault();
|
||||||
|
ImFontConfig config;
|
||||||
|
config.MergeMode = true;
|
||||||
|
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
|
||||||
|
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config);
|
||||||
|
```
|
||||||
|
:rewind: **Before 1.92:**
|
||||||
|
```cpp
|
||||||
|
// Merge icons into default tool font
|
||||||
|
#include "IconsFontAwesome.h"
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.Fonts->AddFontDefault();
|
||||||
|
|
||||||
ImFontConfig config;
|
ImFontConfig config;
|
||||||
config.MergeMode = true;
|
config.MergeMode = true;
|
||||||
@@ -243,7 +299,8 @@ See Links below for other icons fonts and related tools.
|
|||||||
|
|
||||||
**Monospace Icons?**
|
**Monospace Icons?**
|
||||||
|
|
||||||
To make your icon look more monospace and facilitate alignment, you may want to set the ImFontConfig::GlyphMinAdvanceX value when loading an icon font.
|
To make your icon look more monospace and facilitate alignment, you may want to set the `ImFontConfig::GlyphMinAdvanceX` value when loading an icon font.
|
||||||
|
If you `GlyphMinAdvanceX` you need to pass a `font_size` to `AddFontXXX()` calls, as the MinAdvanceX value will be specified for the given size and scaled otherwise.
|
||||||
|
|
||||||
**Screenshot**
|
**Screenshot**
|
||||||
|
|
||||||
@@ -254,11 +311,49 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
|
|||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
### Excluding Overlapping Ranges
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: glyphs ranges are ignored**: when loading a glyph, input fonts in the merge list are queried in order. The first font which has the glyph loads it.
|
||||||
|
<BR>‼️ **If you are merging several fonts, you may have undesirable overlapping ranges.** You can use `ImFontConfig::GlyphExcludeRanges[] `to specify ranges to ignore in a given Input.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Add Font Source 1 but ignore ICON_MIN_FA..ICON_MAX_FA range
|
||||||
|
static ImWchar exclude_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||||
|
ImFontConfig cfg1;
|
||||||
|
cfg1.GlyphExcludeRanges = exclude_ranges;
|
||||||
|
io.Fonts->AddFontFromFileTTF("segoeui.ttf", 0.0f, &cfg1);
|
||||||
|
|
||||||
|
// Add Font Source 2, which expects to use the range above
|
||||||
|
ImFontConfig cfg2;
|
||||||
|
cfg2.MergeMode = true;
|
||||||
|
io.Fonts->AddFontFromFileTTF("FontAwesome4.ttf", 0.0f, &cfg2);
|
||||||
|
```
|
||||||
|
Another (silly) example:
|
||||||
|
```cpp
|
||||||
|
// Remove 'A'-'Z' from first font
|
||||||
|
static ImWchar exclude_ranges[] = { 'A', 'Z', 0 };
|
||||||
|
ImFontConfig cfg1;
|
||||||
|
cfg1.GlyphExcludeRanges = exclude_ranges;
|
||||||
|
io.Fonts->AddFontFromFileTTF("segoeui.ttf", 0.0f, &cfg1);
|
||||||
|
|
||||||
|
// Load another font to fill the gaps
|
||||||
|
ImFontConfig cfg2;
|
||||||
|
cfg2.MergeMode = true;
|
||||||
|
io.Fonts->AddFontFromFileTTF("Roboto-Medium.ttf", 0.0f, &cfg2);
|
||||||
|
```
|
||||||
|

|
||||||
|
|
||||||
|
You can use `Metrics/Debugger->Fonts->Font->Input Glyphs Overlap Detection Tool` to see list of glyphs available in multiple font sources. This can facilitate understanding which font input is providing which glyph.
|
||||||
|
|
||||||
|
##### [Return to Index](#index)
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
## Using FreeType Rasterizer (imgui_freetype)
|
## Using FreeType Rasterizer (imgui_freetype)
|
||||||
|
|
||||||
- Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read.
|
- Dear ImGui uses [stb_truetype.h](https://github.com/nothings/stb/) to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read.
|
||||||
- There is an implementation of the ImFontAtlas builder using FreeType that you can use in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
|
- You can however use `imgui_freetype.cpp` from the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder. Compile with this file and add `#define IMGUI_ENABLE_FREETYPE` to your imconfig.h file or build system to automatically activate it.
|
||||||
- FreeType supports auto-hinting which tends to improve the readability of small fonts.
|
- FreeType supports auto-hinting which tends to improve the readability of small fonts. It makes a big difference especially at smaller resolutions.
|
||||||
- Read documentation in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
|
- Read documentation in the [misc/freetype/](https://github.com/ocornut/imgui/tree/master/misc/freetype) folder.
|
||||||
- Correct sRGB space blending will have an important effect on your font rendering quality.
|
- Correct sRGB space blending will have an important effect on your font rendering quality.
|
||||||
|
|
||||||
@@ -280,10 +375,9 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com):
|
|||||||
io.Fonts->AddFontFromFileTTF("../../../imgui_dev/data/fonts/NotoSans-Regular.ttf", 16.0f);
|
io.Fonts->AddFontFromFileTTF("../../../imgui_dev/data/fonts/NotoSans-Regular.ttf", 16.0f);
|
||||||
static ImWchar ranges[] = { 0x1, 0x1FFFF, 0 };
|
static ImWchar ranges[] = { 0x1, 0x1FFFF, 0 };
|
||||||
static ImFontConfig cfg;
|
static ImFontConfig cfg;
|
||||||
cfg.OversampleH = cfg.OversampleV = 1;
|
|
||||||
cfg.MergeMode = true;
|
cfg.MergeMode = true;
|
||||||
cfg.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_LoadColor;
|
cfg.FontLoaderFlags |= ImGuiFreeTypeLoaderFlags_LoadColor;
|
||||||
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ranges);
|
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg);
|
||||||
```
|
```
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
@@ -292,7 +386,9 @@ io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ra
|
|||||||
|
|
||||||
## Using Custom Glyph Ranges
|
## Using Custom Glyph Ranges
|
||||||
|
|
||||||
You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
|
🆕 **Since 1.92, with an up to date backend: specifying glyph ranges is unnecessary. Therefore this is not really useful any more.**
|
||||||
|
|
||||||
|
:rewind: You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
|
||||||
```cpp
|
```cpp
|
||||||
ImVector<ImWchar> ranges;
|
ImVector<ImWchar> ranges;
|
||||||
ImFontGlyphRangesBuilder builder;
|
ImFontGlyphRangesBuilder builder;
|
||||||
@@ -311,10 +407,19 @@ io.Fonts->Build(); // Build the atlas while
|
|||||||
|
|
||||||
## Using Custom Colorful Icons
|
## Using Custom Colorful Icons
|
||||||
|
|
||||||
|
🆕 **Since 1.92, with an up to date backend: this system has been revamped.**
|
||||||
|
|
||||||
|
TL;DR; With the new system, it is recommended that you create a custom `ImFontLoader` and register your fonts with it.
|
||||||
|
`AddCustomRectFontGlyph()` has been obsoleted because its API does not make much sense with resizable fonts.
|
||||||
|
|
||||||
|
You can ask questions in [#8466](https://github.com/ocornut/imgui/issues/8466).
|
||||||
|
|
||||||
|
:rewind: **Before 1.92:**
|
||||||
|
|
||||||
As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)**
|
As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)**
|
||||||
|
|
||||||
- You can use the `ImFontAtlas::AddCustomRect()` and `ImFontAtlas::AddCustomRectFontGlyph()` api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build()`.
|
- You can use the `ImFontAtlas::AddCustomRect()` and `ImFontAtlas::AddCustomRectFontGlyph()` api to register rectangles that will be packed into the font atlas texture. Register them before building the atlas, then call Build()`.
|
||||||
- You can then use `ImFontAtlas::GetCustomRectByIndex(int)` to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles.
|
- You can then use `ImFontAtlas::GetCustomRect(int)` to query the position/size of your rectangle within the texture, and blit/copy any graphics data of your choice into those rectangles.
|
||||||
- This API is beta because it is likely to change in order to support multi-dpi (multiple viewports on multiple monitors with varying DPI scale).
|
- This API is beta because it is likely to change in order to support multi-dpi (multiple viewports on multiple monitors with varying DPI scale).
|
||||||
|
|
||||||
#### Pseudo-code:
|
#### Pseudo-code:
|
||||||
@@ -334,9 +439,7 @@ int tex_width, tex_height;
|
|||||||
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height);
|
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height);
|
||||||
|
|
||||||
for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
|
for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
|
||||||
{
|
if (const ImTextureRect* rect = io.Fonts->GetCustomRect(rect_ids[rect_n]))
|
||||||
int rect_id = rect_ids[rect_n];
|
|
||||||
if (const ImFontAtlasCustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id))
|
|
||||||
{
|
{
|
||||||
// Fill the custom rectangle with red pixels (in reality you would draw/copy your bitmap data here!)
|
// Fill the custom rectangle with red pixels (in reality you would draw/copy your bitmap data here!)
|
||||||
for (int y = 0; y < rect->Height; y++)
|
for (int y = 0; y < rect->Height; y++)
|
||||||
@@ -346,7 +449,6 @@ for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
|
|||||||
*p++ = IM_COL32(255, 0, 0, 255);
|
*p++ = IM_COL32(255, 0, 0, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### [Return to Index](#index)
|
##### [Return to Index](#index)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Businesses: support continued development and maintenance via invoiced sponsorin
|
|||||||
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Getting Started & Integration](#getting-started--integration) |
|
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Getting Started & Integration](#getting-started--integration) |
|
||||||
:----------------------------------------------------------: |
|
:----------------------------------------------------------: |
|
||||||
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) |
|
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) |
|
||||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Languages bindings & frameworks backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Language bindings & framework backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||||
|
|
||||||
### The Pitch
|
### The Pitch
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
|
|||||||
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
||||||
|
|
||||||
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
|
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-20240105.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20240105.zip) (Windows, 1.90.1 WIP, built 2024/01/05, master) or [older binaries](https://www.dearimgui.com/binaries).
|
- [imgui-demo-binaries-20250625.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20250625.zip) (Windows, 1.92.0, built 2025/06/25, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||||
|
|
||||||
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
|
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
|
||||||
|
|
||||||
@@ -120,10 +120,10 @@ See the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started)
|
|||||||
|
|
||||||
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so.
|
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so.
|
||||||
|
|
||||||
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide it should in theory takes you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
|
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide it should in theory take you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
|
||||||
|
|
||||||
Officially maintained backends/bindings (in repository):
|
Officially maintained backends/bindings (in repository):
|
||||||
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU.
|
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_GPU, SDL_Renderer2/3, Vulkan, WebGPU.
|
||||||
- Platforms: GLFW, SDL2/SDL3, Win32, Glut, OSX, Android.
|
- Platforms: GLFW, SDL2/SDL3, Win32, Glut, OSX, Android.
|
||||||
- Frameworks: Allegro5, Emscripten.
|
- Frameworks: Allegro5, Emscripten.
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ How to help
|
|||||||
- See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues).
|
- See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues).
|
||||||
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||||
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
|
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
|
||||||
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: omar AT dearimgui DOT com).
|
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: contact AT dearimgui DOT com).
|
||||||
|
|
||||||
Sponsors
|
Sponsors
|
||||||
--------
|
--------
|
||||||
@@ -196,7 +196,7 @@ Ongoing Dear ImGui development is and has been financially supported by users an
|
|||||||
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
|
**THANK YOU to all past and present supporters for helping to keep this project alive and thriving!**
|
||||||
|
|
||||||
Dear ImGui is using software and services provided free of charge for open source projects:
|
Dear ImGui is using software and services provided free of charge for open source projects:
|
||||||
- [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis.
|
- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) for static analysis (supports C/C++/C#/Java).
|
||||||
- [GitHub actions](https://github.com/features/actions) for continuous integration systems.
|
- [GitHub actions](https://github.com/features/actions) for continuous integration systems.
|
||||||
- [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis.
|
- [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis.
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.co
|
|||||||
Embeds [ProggyClean.ttf](https://www.proggyfonts.net) font by Tristan Grimmer (MIT license).
|
Embeds [ProggyClean.ttf](https://www.proggyfonts.net) font by Tristan Grimmer (MIT license).
|
||||||
<br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
|
<br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
|
||||||
|
|
||||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Special thanks to Alex Evans, Patrick Doane, Marco Koegler for kindly helping. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- doc: add a proper documentation system (maybe relying on automation? #435)
|
- doc: add a proper documentation system (maybe relying on automation? #435)
|
||||||
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
|
- doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.).
|
||||||
- doc/tips: tips of the day: website? applet in imgui_club?
|
- doc/tips: tips of the day: website? applet in imgui_club?
|
||||||
- doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki
|
|
||||||
|
|
||||||
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
|
- window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #.
|
||||||
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
|
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
|
||||||
@@ -23,13 +22,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
|
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
|
||||||
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
|
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
|
||||||
- window: investigate better auto-positioning for new windows.
|
- window: investigate better auto-positioning for new windows.
|
||||||
- window: top most window flag? more z-order contrl? (#2574)
|
- window: top most window flag? more z-order control? (#2574)
|
||||||
- window/size: manually triggered auto-fit (double-click on grip) shouldn't resize window down to viewport size?
|
- window/size: manually triggered auto-fit (double-click on grip) shouldn't resize window down to viewport size?
|
||||||
- window/size: how to allow to e.g. auto-size vertically to fit contents, but be horizontally resizable? Assuming SetNextWindowSize() is modified to treat -1.0f on each axis as "keep as-is" (would be good but might break erroneous code): Problem is UpdateWindowManualResize() and lots of code treat (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) together.
|
- window/size: how to allow to e.g. auto-size vertically to fit contents, but be horizontally resizable? Assuming SetNextWindowSize() is modified to treat -1.0f on each axis as "keep as-is" (would be good but might break erroneous code): Problem is UpdateWindowManualResize() and lots of code treat (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) together.
|
||||||
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false.
|
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false.
|
||||||
- window/child: background options for child windows, border option (disable rounding).
|
|
||||||
- window/child: allow resizing of child windows (possibly given min/max for each axis?.)
|
|
||||||
- window/child: allow SetNextWindowContentSize() to work on child windows.
|
|
||||||
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
|
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
|
||||||
- window/tabbing: add a way to signify that a window or docked window requires attention (e.g. blinking title bar, trying to click behind a modal).
|
- window/tabbing: add a way to signify that a window or docked window requires attention (e.g. blinking title bar, trying to click behind a modal).
|
||||||
- window/id_stack: add e.g. window->GetIDFromPath() with support for leading / and ../ (#1390, #331) -> model from test engine.
|
- window/id_stack: add e.g. window->GetIDFromPath() with support for leading / and ../ (#1390, #331) -> model from test engine.
|
||||||
@@ -44,7 +40,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
|
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch)
|
||||||
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
||||||
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
|
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
|
||||||
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API).
|
- drawlist: callback: add an extra void* in ImDrawCallback to expose render state instead of pulling from Renderer_RenderState (would break API).
|
||||||
- drawlist: AddRect vs AddLine position confusing (#2441)
|
- drawlist: AddRect vs AddLine position confusing (#2441)
|
||||||
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
|
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
|
||||||
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
|
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
|
||||||
@@ -58,7 +54,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- widgets: start exposing PushItemFlag() and ImGuiItemFlags
|
- widgets: start exposing PushItemFlag() and ImGuiItemFlags
|
||||||
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
|
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
|
||||||
- widgets: activate by identifier (trigger button, focus given id)
|
- widgets: activate by identifier (trigger button, focus given id)
|
||||||
- widgets: custom glyph/shapes replacements for stock sapes. (also #6090 #2431 #2235 #6517)
|
- widgets: custom glyph/shapes replacements for stock shapes. (also #6090 #2431 #2235 #6517)
|
||||||
- widgets: coloredit: keep reporting as active when picker is on?
|
- widgets: coloredit: keep reporting as active when picker is on?
|
||||||
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
|
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
|
||||||
- selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
|
- selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported.
|
||||||
@@ -166,7 +162,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- image/image button: misalignment on padded/bordered button?
|
- image/image button: misalignment on padded/bordered button?
|
||||||
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
|
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
|
||||||
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
|
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
|
||||||
- slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate.
|
- slider: add dragging-based widgets to edit values with mouse (on 2 axes), saving screen real-estate.
|
||||||
- slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign)
|
- slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign)
|
||||||
- slider: relative dragging? + precision dragging
|
- slider: relative dragging? + precision dragging
|
||||||
- slider: step option (#1183)
|
- slider: step option (#1183)
|
||||||
@@ -242,7 +238,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
|
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
|
||||||
- log: obsolete LogButtons().... (was: LogButtons() options for specifying depth and/or hiding depth slider)
|
- log: obsolete LogButtons().... (was: LogButtons() options for specifying depth and/or hiding depth slider)
|
||||||
|
|
||||||
- filters: set a current filter that certains items (e.g. tree node) can automatically query to hide themselves
|
- filters: set a current filter that certain items (e.g. tree node) can automatically query to hide themselves
|
||||||
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
|
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
|
||||||
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
|
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
|
||||||
|
|
||||||
@@ -273,22 +269,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
|
|
||||||
- font: arbitrary line spacing. (#2945)
|
- font: arbitrary line spacing. (#2945)
|
||||||
- font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype)
|
- font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype)
|
||||||
- font: free the Alpha buffer if user only requested RGBA.
|
- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
|
||||||
!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
|
|
||||||
- font: for the purpose of RenderTextEllipsis(), it might be useful that CalcTextSizeA() can ignore the trailing padding?
|
- font: for the purpose of RenderTextEllipsis(), it might be useful that CalcTextSizeA() can ignore the trailing padding?
|
||||||
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y
|
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y
|
||||||
- font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
|
- font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
|
||||||
- font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data
|
|
||||||
- font: remove ID from CustomRect registration, it seems unnecessary!
|
|
||||||
- font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575)
|
- font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575)
|
||||||
- font: PushFontSize API (#1018)
|
|
||||||
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
|
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
|
||||||
- font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width
|
- font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width
|
||||||
- font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs.
|
|
||||||
- font/demo: demonstrate use of ImFontGlyphRangesBuilder.
|
- font/demo: demonstrate use of ImFontGlyphRangesBuilder.
|
||||||
- font/atlas: add a missing Glyphs.reserve()
|
|
||||||
- font/atlas: incremental updates
|
|
||||||
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
|
|
||||||
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
|
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
|
||||||
- font/draw: need to be able to specify wrap start position.
|
- font/draw: need to be able to specify wrap start position.
|
||||||
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349.
|
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines). also see #3349.
|
||||||
@@ -297,20 +285,18 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
|
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
|
||||||
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
|
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
|
||||||
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
|
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
|
||||||
- font: fix AddRemapChar() to work before atlas has been built.
|
|
||||||
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
|
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
|
||||||
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
|
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
|
||||||
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
|
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
|
||||||
|
|
||||||
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
|
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
|
||||||
! nav: never clear NavId on some setup (e.g. gamepad centric)
|
|
||||||
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
|
|
||||||
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
|
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
|
||||||
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
|
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
|
||||||
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
|
- nav: expose wrap around flags/logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
|
||||||
- nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch)
|
- nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch)
|
||||||
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
|
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
|
||||||
- nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem
|
- nav: SetItemDefaultFocus() level of priority, so widgets like Selectable when inside a popup could claim a low-priority default focus on the first selected item
|
||||||
|
- nav: holding space to repeat a button doesn't show button activated during hold.
|
||||||
- nav: NavFlattened: init requests don't work properly on flattened siblings.
|
- nav: NavFlattened: init requests don't work properly on flattened siblings.
|
||||||
- nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings.
|
- nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings.
|
||||||
- nav: NavFlattened: ESC on a flattened child should select something.
|
- nav: NavFlattened: ESC on a flattened child should select something.
|
||||||
@@ -329,7 +315,7 @@ 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
|
- 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
|
- 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.
|
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: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front.
|
||||||
@@ -338,6 +324,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- 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: 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: 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: 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: 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 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: no refresh of monitor/display (SDL doesn't seem to have an event for it).
|
||||||
@@ -373,7 +360,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- backends: opengl: explicitly disable GL_STENCIL_TEST in bindings.
|
- backends: opengl: explicitly disable GL_STENCIL_TEST in bindings.
|
||||||
- backends: vulkan: viewport: support for synchronized swapping of multiple swap chains.
|
- backends: vulkan: viewport: support for synchronized swapping of multiple swap chains.
|
||||||
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
|
- backends: bgfx: https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
|
||||||
- backends: emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
- backends: emscripten: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
|
||||||
|
|
||||||
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) (--> use https://github.com/dearimgui/dear_bindings)
|
- bindings: ways to use clang ast dump to generate bindings or helpers for bindings? (e.g. clang++ -Xclang -ast-dump=json imgui.h) (--> use https://github.com/dearimgui/dear_bindings)
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ You may install Allegro using vcpkg:
|
|||||||
git clone https://github.com/Microsoft/vcpkg
|
git clone https://github.com/Microsoft/vcpkg
|
||||||
cd vcpkg
|
cd vcpkg
|
||||||
bootstrap-vcpkg.bat
|
bootstrap-vcpkg.bat
|
||||||
vcpkg install allegro5 --triplet=x86-windows ; for win32
|
vcpkg install allegro5 --triplet=x86-windows ; for win32
|
||||||
vcpkg install allegro5 --triplet=x64-windows ; for win64
|
vcpkg install allegro5 --triplet=x64-windows ; for win64
|
||||||
vcpkg integrate install ; register include / libs in Visual Studio
|
vcpkg integrate install ; register include / libs in Visual Studio
|
||||||
```
|
```
|
||||||
|
|
||||||
Build:
|
Build:
|
||||||
|
|||||||
@@ -53,16 +53,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
bool show_demo_window = true;
|
bool show_demo_window = true;
|
||||||
|
|||||||
@@ -42,5 +42,5 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ void android_main(struct android_app* app)
|
|||||||
struct android_poll_source* out_data;
|
struct android_poll_source* out_data;
|
||||||
|
|
||||||
// Poll all events. If the app is not visible, this loop blocks until g_Initialized == true.
|
// Poll all events. If the app is not visible, this loop blocks until g_Initialized == true.
|
||||||
while (ALooper_pollAll(g_Initialized ? 0 : -1, nullptr, &out_events, (void**)&out_data) >= 0)
|
while (ALooper_pollOnce(g_Initialized ? 0 : -1, nullptr, &out_events, (void**)&out_data) >= 0)
|
||||||
{
|
{
|
||||||
// Process one event
|
// Process one event
|
||||||
if (out_data != nullptr)
|
if (out_data != nullptr)
|
||||||
@@ -154,7 +154,6 @@ void Init(struct android_app* app)
|
|||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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.
|
||||||
@@ -181,7 +180,7 @@ void Init(struct android_app* app)
|
|||||||
//font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 15.0f);
|
//font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 15.0f);
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
//font_data_size = GetAssetData("ArialUni.ttf", &font_data);
|
//font_data_size = GetAssetData("ArialUni.ttf", &font_data);
|
||||||
//font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//font = io.Fonts->AddFontFromMemoryTTF(font_data, font_data_size, 18.0f);
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Arbitrary scale-up
|
// Arbitrary scale-up
|
||||||
|
|||||||
21
examples/example_apple_metal/Makefile
Normal file
21
examples/example_apple_metal/Makefile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Makefile for example_apple_metal, for macOS only (**not iOS**)
|
||||||
|
CXX = clang++
|
||||||
|
EXE = example_apple_metal
|
||||||
|
IMGUI_DIR = ../../
|
||||||
|
SOURCES = main.mm
|
||||||
|
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||||
|
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_osx.mm $(IMGUI_DIR)/backends/imgui_impl_metal.mm
|
||||||
|
|
||||||
|
CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
|
FRAMEWORKS = -framework AppKit -framework Metal -framework MetalKit -framework QuartzCore -framework GameController
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
|
||||||
|
$(EXE): $(SOURCES)
|
||||||
|
$(CXX) $(CXXFLAGS) $^ $(FRAMEWORKS) -o $@
|
||||||
|
|
||||||
|
run: all
|
||||||
|
./$(EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) *.o
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 48;
|
objectVersion = 54;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
@@ -222,7 +222,8 @@
|
|||||||
8307E7B620E9F9C700473790 /* Project object */ = {
|
8307E7B620E9F9C700473790 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1200;
|
BuildIndependentTargetsInParallel = YES;
|
||||||
|
LastUpgradeCheck = 1530;
|
||||||
ORGANIZATIONNAME = "Warren Moore";
|
ORGANIZATIONNAME = "Warren Moore";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
8307E7C320E9F9C900473790 = {
|
8307E7C320E9F9C900473790 = {
|
||||||
@@ -340,9 +341,11 @@
|
|||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@@ -396,9 +399,11 @@
|
|||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -418,8 +423,11 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
||||||
PRODUCT_NAME = example_apple_metal;
|
PRODUCT_NAME = example_apple_metal;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -435,8 +443,11 @@
|
|||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
INFOPLIST_FILE = "$(SRCROOT)/iOS/Info-iOS.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-ios";
|
||||||
PRODUCT_NAME = example_apple_metal;
|
PRODUCT_NAME = example_apple_metal;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -452,10 +463,14 @@
|
|||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
||||||
PRODUCT_NAME = example_apple_metal;
|
PRODUCT_NAME = example_apple_metal;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
@@ -469,10 +484,14 @@
|
|||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
INFOPLIST_FILE = "$(SRCROOT)/macOS/Info-macOS.plist";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
"$(inherited)",
|
||||||
|
"@executable_path/../Frameworks",
|
||||||
|
);
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.imgui.example.apple-metal-macos";
|
||||||
PRODUCT_NAME = example_apple_metal;
|
PRODUCT_NAME = example_apple_metal;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
|||||||
@@ -82,16 +82,16 @@
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
if (renderPassDescriptor == nil)
|
if (renderPassDescriptor == nil)
|
||||||
{
|
{
|
||||||
[commandBuffer commit];
|
[commandBuffer commit];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the Dear ImGui frame
|
// Start the Dear ImGui frame
|
||||||
@@ -202,7 +202,7 @@
|
|||||||
[renderEncoder popDebugGroup];
|
[renderEncoder popDebugGroup];
|
||||||
[renderEncoder endEncoding];
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
// Present
|
// Present
|
||||||
[commandBuffer presentDrawable:view.currentDrawable];
|
[commandBuffer presentDrawable:view.currentDrawable];
|
||||||
[commandBuffer commit];
|
[commandBuffer commit];
|
||||||
|
|
||||||
@@ -336,9 +336,20 @@
|
|||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int, const char**)
|
||||||
{
|
{
|
||||||
return NSApplicationMain(argc, argv);
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
|
AppDelegate *appDelegate = [[AppDelegate alloc] init]; // creates window
|
||||||
|
[NSApp setDelegate:appDelegate];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
[NSApp run];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
21
examples/example_apple_opengl2/Makefile
Normal file
21
examples/example_apple_opengl2/Makefile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Makefile for example_apple_metal, for macOS only (**not iOS**)
|
||||||
|
CXX = clang++
|
||||||
|
EXE = example_apple_opengl2
|
||||||
|
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_opengl2.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
|
||||||
@@ -289,7 +289,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
USER_HEADER_SEARCH_PATHS = ../..;
|
USER_HEADER_SEARCH_PATHS = ../..;
|
||||||
};
|
};
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
USER_HEADER_SEARCH_PATHS = ../..;
|
USER_HEADER_SEARCH_PATHS = ../..;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
// - 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.
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <OpenGL/gl.h>
|
#import <OpenGL/gl.h>
|
||||||
#import <OpenGL/glu.h>
|
#import <OpenGL/glu.h>
|
||||||
@@ -70,16 +72,16 @@
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,16 +52,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Setup window
|
// Setup window
|
||||||
|
|||||||
@@ -77,16 +77,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -32,8 +32,12 @@ EMS =
|
|||||||
##---------------------------------------------------------------------
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only)
|
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only)
|
||||||
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
# Note: For glfw, we use emscripten-glfw port (contrib.glfw3) instead of ('-s USE_GLFW=3' in LDFLAGS) to get a better support for High DPI displays.
|
||||||
LDFLAGS += -s USE_GLFW=3 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
EMS += -s DISABLE_EXCEPTION_CATCHING=1 --use-port=contrib.glfw3
|
||||||
|
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
||||||
|
|
||||||
|
# Build as single file (binary text encoded in .html file)
|
||||||
|
#LDFLAGS += -sSINGLE_FILE
|
||||||
|
|
||||||
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
||||||
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
||||||
|
|||||||
@@ -43,11 +43,17 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Decide GL+GLSL versions
|
// Decide GL+GLSL versions
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
// GL ES 2.0 + GLSL 100
|
// GL ES 2.0 + GLSL 100 (WebGL 1.0)
|
||||||
const char* glsl_version = "#version 100";
|
const char* glsl_version = "#version 100";
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||||
|
// GL ES 3.0 + GLSL 300 es (WebGL 2.0)
|
||||||
|
const char* glsl_version = "#version 300 es";
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// GL 3.2 + GLSL 150
|
// GL 3.2 + GLSL 150
|
||||||
const char* glsl_version = "#version 150";
|
const char* glsl_version = "#version 150";
|
||||||
@@ -65,7 +71,8 @@ int main(int, char**)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create window with graphics context
|
// Create window with graphics context
|
||||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", nullptr, nullptr);
|
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
|
||||||
|
GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+OpenGL3 example", nullptr, nullptr);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
return 1;
|
return 1;
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
@@ -86,8 +93,16 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// Setup scaling
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
#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)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
style.WindowRounding = 0.0f;
|
style.WindowRounding = 0.0f;
|
||||||
@@ -105,17 +120,17 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DVK_PROTOTYPES")
|
|||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVK_PROTOTYPES")
|
||||||
|
|
||||||
# GLFW
|
# GLFW
|
||||||
set(GLFW_DIR ../../../glfw) # Set this to point to an up-to-date GLFW repo
|
if(NOT GLFW_DIR)
|
||||||
|
set(GLFW_DIR ../../../glfw) # Set this to point to an up-to-date GLFW repo
|
||||||
|
endif()
|
||||||
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
|
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" OFF)
|
||||||
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
|
option(GLFW_BUILD_TESTS "Build the GLFW test programs" OFF)
|
||||||
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
|
option(GLFW_BUILD_DOCS "Build the GLFW documentation" OFF)
|
||||||
@@ -42,4 +44,4 @@ file(GLOB sources *.cpp)
|
|||||||
|
|
||||||
add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp)
|
add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp)
|
||||||
target_link_libraries(example_glfw_vulkan ${LIBRARIES})
|
target_link_libraries(example_glfw_vulkan ${LIBRARIES})
|
||||||
target_compile_definitions(example_glfw_vulkan PUBLIC -DImTextureID=ImU64)
|
|
||||||
|
|||||||
83
examples/example_glfw_vulkan/Makefile
Normal file
83
examples/example_glfw_vulkan/Makefile
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#
|
||||||
|
# Cross Platform Makefile
|
||||||
|
# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X
|
||||||
|
#
|
||||||
|
# You will need GLFW (http://www.glfw.org):
|
||||||
|
# Linux:
|
||||||
|
# apt-get install libglfw-dev
|
||||||
|
# Mac OS X:
|
||||||
|
# brew install glfw
|
||||||
|
# MSYS2:
|
||||||
|
# pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-glfw
|
||||||
|
#
|
||||||
|
|
||||||
|
#CXX = g++
|
||||||
|
#CXX = clang++
|
||||||
|
|
||||||
|
EXE = example_glfw_vulkan
|
||||||
|
IMGUI_DIR = ../..
|
||||||
|
SOURCES = main.cpp
|
||||||
|
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_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_vulkan.cpp
|
||||||
|
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
LINUX_GL_LIBS = -lGL
|
||||||
|
|
||||||
|
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
|
CXXFLAGS += -g -Wall -Wformat
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
## BUILD FLAGS PER PLATFORM
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S), Linux) #LINUX
|
||||||
|
ECHO_MESSAGE = "Linux"
|
||||||
|
LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3 vulkan`
|
||||||
|
|
||||||
|
CXXFLAGS += `pkg-config --cflags glfw3 vulkan`
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||||
|
ECHO_MESSAGE = "Mac OS X"
|
||||||
|
LIBS += -framework Cocoa -framework IOKit -framework CoreVideo
|
||||||
|
LIBS += `pkg-config --libs glfw3 vulkan`
|
||||||
|
LIBS += -L/usr/local/lib -L/opt/local/lib -L/opt/homebrew/lib
|
||||||
|
#LIBS += -lglfw3
|
||||||
|
|
||||||
|
LIBS += `pkg-config --cflags glfw3 vulkan`
|
||||||
|
CXXFLAGS += -I/usr/local/include -I/opt/local/include -I/opt/homebrew/include
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(OS), Windows_NT)
|
||||||
|
ECHO_MESSAGE = "MinGW"
|
||||||
|
LIBS += -lgdi32 -limm32
|
||||||
|
LIBS += `pkg-config --libs glfw3 vulkan`
|
||||||
|
|
||||||
|
CXXFLAGS += `pkg-config --cflags glfw3 vulkan`
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
## BUILD RULES
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
|
%.o:%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/backends/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
@echo Build complete for $(ECHO_MESSAGE)
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
@set OUT_DIR=Debug
|
@set OUT_DIR=Debug
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
|
|
||||||
@set OUT_DIR=Release
|
@set OUT_DIR=Release
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
@REM Build for Visual Studio compiler. Run your copy of amd64/vcvars32.bat to setup 64-bit command-line compiler.
|
@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 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 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 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
|
@set OUT_DIR=Debug
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
|
|
||||||
@set OUT_DIR=Release
|
@set OUT_DIR=Release
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
|
|||||||
@@ -91,7 +91,7 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
//#define APP_USE_UNLIMITED_FRAME_RATE
|
//#define APP_USE_UNLIMITED_FRAME_RATE
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define APP_USE_VULKAN_DEBUG_REPORT
|
#define APP_USE_VULKAN_DEBUG_REPORT
|
||||||
|
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
@@ -47,12 +48,11 @@ static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
|
|||||||
static VkDevice g_Device = VK_NULL_HANDLE;
|
static VkDevice g_Device = VK_NULL_HANDLE;
|
||||||
static uint32_t g_QueueFamily = (uint32_t)-1;
|
static uint32_t g_QueueFamily = (uint32_t)-1;
|
||||||
static VkQueue g_Queue = VK_NULL_HANDLE;
|
static VkQueue g_Queue = VK_NULL_HANDLE;
|
||||||
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
|
|
||||||
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
||||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
static ImGui_ImplVulkanH_Window g_MainWindowData;
|
static ImGui_ImplVulkanH_Window g_MainWindowData;
|
||||||
static int g_MinImageCount = 2;
|
static uint32_t g_MinImageCount = 2;
|
||||||
static bool g_SwapChainRebuild = false;
|
static bool g_SwapChainRebuild = false;
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
@@ -61,7 +61,7 @@ static void glfw_error_callback(int error, const char* description)
|
|||||||
}
|
}
|
||||||
static void check_vk_result(VkResult err)
|
static void check_vk_result(VkResult err)
|
||||||
{
|
{
|
||||||
if (err == 0)
|
if (err == VK_SUCCESS)
|
||||||
return;
|
return;
|
||||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -85,35 +85,6 @@ static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properti
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
|
|
||||||
{
|
|
||||||
uint32_t gpu_count;
|
|
||||||
VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
|
|
||||||
check_vk_result(err);
|
|
||||||
IM_ASSERT(gpu_count > 0);
|
|
||||||
|
|
||||||
ImVector<VkPhysicalDevice> gpus;
|
|
||||||
gpus.resize(gpu_count);
|
|
||||||
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data);
|
|
||||||
check_vk_result(err);
|
|
||||||
|
|
||||||
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
|
|
||||||
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
|
|
||||||
// dedicated GPUs) is out of scope of this sample.
|
|
||||||
for (VkPhysicalDevice& device : gpus)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties properties;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &properties);
|
|
||||||
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use first GPU (Integrated) is a Discrete one is not available.
|
|
||||||
if (gpu_count > 0)
|
|
||||||
return gpus[0];
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetupVulkan(ImVector<const char*> instance_extensions)
|
static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
@@ -177,23 +148,12 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select Physical Device (GPU)
|
// Select Physical Device (GPU)
|
||||||
g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice();
|
g_PhysicalDevice = ImGui_ImplVulkanH_SelectPhysicalDevice(g_Instance);
|
||||||
|
IM_ASSERT(g_PhysicalDevice != VK_NULL_HANDLE);
|
||||||
|
|
||||||
// Select graphics queue family
|
// Select graphics queue family
|
||||||
{
|
g_QueueFamily = ImGui_ImplVulkanH_SelectQueueFamilyIndex(g_PhysicalDevice);
|
||||||
uint32_t count;
|
IM_ASSERT(g_QueueFamily != (uint32_t)-1);
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, nullptr);
|
|
||||||
VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues);
|
|
||||||
for (uint32_t i = 0; i < count; i++)
|
|
||||||
if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
||||||
{
|
|
||||||
g_QueueFamily = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(queues);
|
|
||||||
IM_ASSERT(g_QueueFamily != (uint32_t)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Logical Device (with 1 queue)
|
// Create Logical Device (with 1 queue)
|
||||||
{
|
{
|
||||||
@@ -229,17 +189,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create Descriptor Pool
|
// Create Descriptor Pool
|
||||||
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
|
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
|
||||||
// If you wish to load e.g. additional textures you may need to alter pools sizes.
|
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_sizes[] =
|
VkDescriptorPoolSize pool_sizes[] =
|
||||||
{
|
{
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo pool_info = {};
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
pool_info.maxSets = 1;
|
pool_info.maxSets = 0;
|
||||||
|
for (VkDescriptorPoolSize& pool_size : pool_sizes)
|
||||||
|
pool_info.maxSets += pool_size.descriptorCount;
|
||||||
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.pPoolSizes = pool_sizes;
|
pool_info.pPoolSizes = pool_sizes;
|
||||||
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
||||||
@@ -302,17 +263,15 @@ static void CleanupVulkanWindow()
|
|||||||
|
|
||||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
VkResult err;
|
|
||||||
|
|
||||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||||
{
|
|
||||||
g_SwapChainRebuild = true;
|
g_SwapChainRebuild = true;
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
return;
|
return;
|
||||||
}
|
if (err != VK_SUBOPTIMAL_KHR)
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||||
{
|
{
|
||||||
@@ -381,11 +340,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
|||||||
info.pImageIndices = &wd->FrameIndex;
|
info.pImageIndices = &wd->FrameIndex;
|
||||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||||
{
|
|
||||||
g_SwapChainRebuild = true;
|
g_SwapChainRebuild = true;
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
return;
|
return;
|
||||||
}
|
if (err != VK_SUBOPTIMAL_KHR)
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,6 +408,7 @@ int main(int, char**)
|
|||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||||
|
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||||
init_info.Instance = g_Instance;
|
init_info.Instance = g_Instance;
|
||||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||||
init_info.Device = g_Device;
|
init_info.Device = g_Device;
|
||||||
@@ -469,16 +429,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -32,10 +32,14 @@ EMS =
|
|||||||
##---------------------------------------------------------------------
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only)
|
# ("EMS" options gets added to both CPPFLAGS and LDFLAGS, whereas some options are for linker only)
|
||||||
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
# Note: For glfw, we use emscripten-glfw port (contrib.glfw3) instead of (-s USE_GLFW=3) to get a better support for High DPI displays.
|
||||||
LDFLAGS += -s USE_GLFW=3 -s USE_WEBGPU=1
|
EMS += -s DISABLE_EXCEPTION_CATCHING=1 --use-port=contrib.glfw3
|
||||||
|
LDFLAGS += -s USE_WEBGPU=1
|
||||||
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
||||||
|
|
||||||
|
# Build as single file (binary text encoded in .html file)
|
||||||
|
#LDFLAGS += -sSINGLE_FILE
|
||||||
|
|
||||||
# Emscripten allows preloading a file or folder to be accessible at runtime.
|
# Emscripten allows preloading a file or folder to be accessible at runtime.
|
||||||
# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts"
|
# The Makefile for this example project suggests embedding the misc/fonts/ folder into our application, it will then be accessible as "/fonts"
|
||||||
# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html
|
# See documentation for more details: https://emscripten.org/docs/porting/files/packaging_files.html
|
||||||
|
|||||||
@@ -115,19 +115,19 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf", 10.0f);
|
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -83,16 +83,16 @@ int main(int argc, char** argv)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
// Build atlas
|
// Build atlas
|
||||||
unsigned char* tex_pixels = nullptr;
|
//unsigned char* tex_pixels = nullptr;
|
||||||
int tex_w, tex_h;
|
//int tex_w, tex_h;
|
||||||
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h);
|
//io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_w, &tex_h);
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures;
|
||||||
|
|
||||||
for (int n = 0; n < 20; n++)
|
for (int n = 0; n < 20; n++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ int main(int, char**)
|
|||||||
// Setup SDL
|
// Setup SDL
|
||||||
// (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
|
// (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
|
||||||
// depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to the latest version of SDL is recommended!)
|
// depending on whether SDL_INIT_GAMECONTROLLER is enabled or disabled.. updating to the latest version of SDL is recommended!)
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: %s\n", SDL_GetError());
|
printf("Error: %s\n", SDL_GetError());
|
||||||
@@ -45,8 +48,9 @@ int main(int, char**)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Setup window
|
// Setup window
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
@@ -80,8 +84,14 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// Setup scaling
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||||
|
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||||
|
|
||||||
|
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
style.WindowRounding = 0.0f;
|
style.WindowRounding = 0.0f;
|
||||||
@@ -96,16 +106,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -43,16 +43,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
|
|||||||
@@ -17,11 +17,17 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h> // SetProcessDPIAware()
|
||||||
|
#endif
|
||||||
|
|
||||||
// Main code
|
// Main code
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: %s\n", SDL_GetError());
|
printf("Error: %s\n", SDL_GetError());
|
||||||
@@ -39,8 +45,9 @@ int main(int, char**)
|
|||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
@@ -66,8 +73,14 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// Setup scaling
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||||
|
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||||
|
|
||||||
|
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
style.WindowRounding = 0.0f;
|
style.WindowRounding = 0.0f;
|
||||||
@@ -82,16 +95,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ EMS += -s USE_SDL=2
|
|||||||
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
||||||
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
||||||
|
|
||||||
|
# Build as single file (binary text encoded in .html file)
|
||||||
|
#LDFLAGS += -sSINGLE_FILE
|
||||||
|
|
||||||
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
||||||
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
||||||
#EMS += -s SAFE_HEAP=1 ## Adds overhead
|
#EMS += -s SAFE_HEAP=1 ## Adds overhead
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
#else
|
#else
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h> // SetProcessDPIAware()
|
||||||
|
#endif
|
||||||
|
|
||||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
@@ -27,6 +30,9 @@
|
|||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: %s\n", SDL_GetError());
|
printf("Error: %s\n", SDL_GetError());
|
||||||
@@ -35,12 +41,19 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Decide GL+GLSL versions
|
// Decide GL+GLSL versions
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
// GL ES 2.0 + GLSL 100
|
// GL ES 2.0 + GLSL 100 (WebGL 1.0)
|
||||||
const char* glsl_version = "#version 100";
|
const char* glsl_version = "#version 100";
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||||
|
// GL ES 3.0 + GLSL 300 es (WebGL 2.0)
|
||||||
|
const char* glsl_version = "#version 300 es";
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// GL 3.2 Core + GLSL 150
|
// GL 3.2 Core + GLSL 150
|
||||||
const char* glsl_version = "#version 150";
|
const char* glsl_version = "#version 150";
|
||||||
@@ -66,8 +79,9 @@ int main(int, char**)
|
|||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
@@ -75,6 +89,12 @@ int main(int, char**)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||||
|
if (gl_context == nullptr)
|
||||||
|
{
|
||||||
|
printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GL_MakeCurrent(window, gl_context);
|
SDL_GL_MakeCurrent(window, gl_context);
|
||||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||||
|
|
||||||
@@ -93,8 +113,14 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// Setup scaling
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||||
|
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||||
|
|
||||||
|
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
style.WindowRounding = 0.0f;
|
style.WindowRounding = 0.0f;
|
||||||
@@ -109,17 +135,17 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
#include "imgui_impl_sdlrenderer2.h"
|
#include "imgui_impl_sdlrenderer2.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h> // SetProcessDPIAware()
|
||||||
|
#endif
|
||||||
|
|
||||||
#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
|
||||||
@@ -24,6 +27,9 @@
|
|||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: %s\n", SDL_GetError());
|
printf("Error: %s\n", SDL_GetError());
|
||||||
@@ -36,8 +42,9 @@ int main(int, char**)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create window with SDL_Renderer graphics context
|
// Create window with SDL_Renderer graphics context
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
@@ -65,6 +72,13 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||||
|
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||||
ImGui_ImplSDLRenderer2_Init(renderer);
|
ImGui_ImplSDLRenderer2_Init(renderer);
|
||||||
@@ -73,16 +87,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
80
examples/example_sdl2_vulkan/Makefile
Normal file
80
examples/example_sdl2_vulkan/Makefile
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#
|
||||||
|
# Cross Platform Makefile
|
||||||
|
# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X
|
||||||
|
#
|
||||||
|
# You will need SDL2 (http://www.libsdl.org):
|
||||||
|
# Linux:
|
||||||
|
# apt-get install libsdl2-dev
|
||||||
|
# Mac OS X:
|
||||||
|
# brew install sdl2
|
||||||
|
# MSYS2:
|
||||||
|
# pacman -S mingw-w64-i686-SDL2
|
||||||
|
#
|
||||||
|
|
||||||
|
#CXX = g++
|
||||||
|
#CXX = clang++
|
||||||
|
|
||||||
|
EXE = example_sdl2_vulkan
|
||||||
|
IMGUI_DIR = ../..
|
||||||
|
SOURCES = main.cpp
|
||||||
|
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_sdl2.cpp $(IMGUI_DIR)/backends/imgui_impl_vulkan.cpp
|
||||||
|
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
|
||||||
|
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
|
CXXFLAGS += -g -Wall -Wformat
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
## BUILD FLAGS PER PLATFORM
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S), Linux) #LINUX
|
||||||
|
ECHO_MESSAGE = "Linux"
|
||||||
|
LIBS += -lGL -ldl
|
||||||
|
LIBS += `pkg-config --libs sdl2 vulkan`
|
||||||
|
CXXFLAGS += `pkg-config --cflags sdl2 vulkan`
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||||
|
ECHO_MESSAGE = "Mac OS X"
|
||||||
|
LIBS += -framework Cocoa -framework IOKit -framework CoreVideo
|
||||||
|
LIBS += `pkg-config --libs sdl2 vulkan`
|
||||||
|
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||||
|
|
||||||
|
CXXFLAGS += `pkg-config --cflags sdl2 vulkan`
|
||||||
|
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(OS), Windows_NT)
|
||||||
|
ECHO_MESSAGE = "MinGW"
|
||||||
|
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2 vulkan`
|
||||||
|
|
||||||
|
CXXFLAGS += `pkg-config --cflags sdl2 vulkan`
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
## BUILD RULES
|
||||||
|
##---------------------------------------------------------------------
|
||||||
|
|
||||||
|
%.o:%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/backends/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
@echo Build complete for $(ECHO_MESSAGE)
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
||||||
@@ -7,4 +7,8 @@
|
|||||||
|
|
||||||
@set OUT_DIR=Debug
|
@set OUT_DIR=Debug
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||||
|
|
||||||
|
@set OUT_DIR=Release
|
||||||
|
@REM mkdir %OUT_DIR%
|
||||||
|
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||||
|
|||||||
14
examples/example_sdl2_vulkan/build_win64.bat
Normal file
14
examples/example_sdl2_vulkan/build_win64.bat
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup command-line compiler.
|
||||||
|
|
||||||
|
@set OUT_EXE=example_sdl2_vulkan
|
||||||
|
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include /I %VULKAN_SDK%\include
|
||||||
|
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl2.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\imgui*.cpp
|
||||||
|
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x64 /libpath:%VULKAN_SDK%\lib SDL2.lib SDL2main.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% /subsystem:console
|
||||||
|
|
||||||
|
@set OUT_DIR=Release
|
||||||
|
@REM mkdir %OUT_DIR%
|
||||||
|
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -148,7 +148,7 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -187,4 +187,4 @@
|
|||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -20,6 +20,9 @@
|
|||||||
#include <stdlib.h> // abort
|
#include <stdlib.h> // abort
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_vulkan.h>
|
#include <SDL_vulkan.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h> // SetProcessDPIAware()
|
||||||
|
#endif
|
||||||
|
|
||||||
// Volk headers
|
// Volk headers
|
||||||
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||||
@@ -30,6 +33,7 @@
|
|||||||
//#define APP_USE_UNLIMITED_FRAME_RATE
|
//#define APP_USE_UNLIMITED_FRAME_RATE
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define APP_USE_VULKAN_DEBUG_REPORT
|
#define APP_USE_VULKAN_DEBUG_REPORT
|
||||||
|
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
@@ -39,7 +43,6 @@ static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE;
|
|||||||
static VkDevice g_Device = VK_NULL_HANDLE;
|
static VkDevice g_Device = VK_NULL_HANDLE;
|
||||||
static uint32_t g_QueueFamily = (uint32_t)-1;
|
static uint32_t g_QueueFamily = (uint32_t)-1;
|
||||||
static VkQueue g_Queue = VK_NULL_HANDLE;
|
static VkQueue g_Queue = VK_NULL_HANDLE;
|
||||||
static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE;
|
|
||||||
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
|
||||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ static bool g_SwapChainRebuild = false;
|
|||||||
|
|
||||||
static void check_vk_result(VkResult err)
|
static void check_vk_result(VkResult err)
|
||||||
{
|
{
|
||||||
if (err == 0)
|
if (err == VK_SUCCESS)
|
||||||
return;
|
return;
|
||||||
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -73,35 +76,6 @@ static bool IsExtensionAvailable(const ImVector<VkExtensionProperties>& properti
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice()
|
|
||||||
{
|
|
||||||
uint32_t gpu_count;
|
|
||||||
VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr);
|
|
||||||
check_vk_result(err);
|
|
||||||
IM_ASSERT(gpu_count > 0);
|
|
||||||
|
|
||||||
ImVector<VkPhysicalDevice> gpus;
|
|
||||||
gpus.resize(gpu_count);
|
|
||||||
err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data);
|
|
||||||
check_vk_result(err);
|
|
||||||
|
|
||||||
// If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers
|
|
||||||
// most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple
|
|
||||||
// dedicated GPUs) is out of scope of this sample.
|
|
||||||
for (VkPhysicalDevice& device : gpus)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties properties;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &properties);
|
|
||||||
if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use first GPU (Integrated) is a Discrete one is not available.
|
|
||||||
if (gpu_count > 0)
|
|
||||||
return gpus[0];
|
|
||||||
return VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetupVulkan(ImVector<const char*> instance_extensions)
|
static void SetupVulkan(ImVector<const char*> instance_extensions)
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
@@ -165,23 +139,12 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Select Physical Device (GPU)
|
// Select Physical Device (GPU)
|
||||||
g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice();
|
g_PhysicalDevice = ImGui_ImplVulkanH_SelectPhysicalDevice(g_Instance);
|
||||||
|
IM_ASSERT(g_PhysicalDevice != VK_NULL_HANDLE);
|
||||||
|
|
||||||
// Select graphics queue family
|
// Select graphics queue family
|
||||||
{
|
g_QueueFamily = ImGui_ImplVulkanH_SelectQueueFamilyIndex(g_PhysicalDevice);
|
||||||
uint32_t count;
|
IM_ASSERT(g_QueueFamily != (uint32_t)-1);
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, nullptr);
|
|
||||||
VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues);
|
|
||||||
for (uint32_t i = 0; i < count; i++)
|
|
||||||
if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
||||||
{
|
|
||||||
g_QueueFamily = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(queues);
|
|
||||||
IM_ASSERT(g_QueueFamily != (uint32_t)-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create Logical Device (with 1 queue)
|
// Create Logical Device (with 1 queue)
|
||||||
{
|
{
|
||||||
@@ -217,17 +180,18 @@ static void SetupVulkan(ImVector<const char*> instance_extensions)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create Descriptor Pool
|
// Create Descriptor Pool
|
||||||
// The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that)
|
// If you wish to load e.g. additional textures you may need to alter pools sizes and maxSets.
|
||||||
// If you wish to load e.g. additional textures you may need to alter pools sizes.
|
|
||||||
{
|
{
|
||||||
VkDescriptorPoolSize pool_sizes[] =
|
VkDescriptorPoolSize pool_sizes[] =
|
||||||
{
|
{
|
||||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 },
|
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE },
|
||||||
};
|
};
|
||||||
VkDescriptorPoolCreateInfo pool_info = {};
|
VkDescriptorPoolCreateInfo pool_info = {};
|
||||||
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
pool_info.maxSets = 1;
|
pool_info.maxSets = 0;
|
||||||
|
for (VkDescriptorPoolSize& pool_size : pool_sizes)
|
||||||
|
pool_info.maxSets += pool_size.descriptorCount;
|
||||||
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||||
pool_info.pPoolSizes = pool_sizes;
|
pool_info.pPoolSizes = pool_sizes;
|
||||||
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool);
|
||||||
@@ -256,7 +220,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
|||||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||||
|
|
||||||
// Select Present Mode
|
// Select Present Mode
|
||||||
#ifdef APP_UNLIMITED_FRAME_RATE
|
#ifdef APP_USE_UNLIMITED_FRAME_RATE
|
||||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||||
#else
|
#else
|
||||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR };
|
||||||
@@ -290,17 +254,15 @@ static void CleanupVulkanWindow()
|
|||||||
|
|
||||||
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
VkResult err;
|
|
||||||
|
|
||||||
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore;
|
||||||
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore;
|
||||||
err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
VkResult err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||||
{
|
|
||||||
g_SwapChainRebuild = true;
|
g_SwapChainRebuild = true;
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
return;
|
return;
|
||||||
}
|
if (err != VK_SUBOPTIMAL_KHR)
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
|
|
||||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||||
{
|
{
|
||||||
@@ -369,11 +331,11 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
|||||||
info.pImageIndices = &wd->FrameIndex;
|
info.pImageIndices = &wd->FrameIndex;
|
||||||
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
VkResult err = vkQueuePresentKHR(g_Queue, &info);
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||||
{
|
|
||||||
g_SwapChainRebuild = true;
|
g_SwapChainRebuild = true;
|
||||||
|
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
return;
|
return;
|
||||||
}
|
if (err != VK_SUBOPTIMAL_KHR)
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,6 +343,9 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd)
|
|||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
// Setup SDL
|
// Setup SDL
|
||||||
|
#ifdef _WIN32
|
||||||
|
::SetProcessDPIAware();
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||||
{
|
{
|
||||||
printf("Error: %s\n", SDL_GetError());
|
printf("Error: %s\n", SDL_GetError());
|
||||||
@@ -393,8 +358,9 @@ int main(int, char**)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Create window with Vulkan graphics context
|
// Create window with Vulkan graphics context
|
||||||
|
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
@@ -438,8 +404,14 @@ int main(int, char**)
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// Setup scaling
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||||
|
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||||
|
|
||||||
|
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
{
|
{
|
||||||
style.WindowRounding = 0.0f;
|
style.WindowRounding = 0.0f;
|
||||||
@@ -449,6 +421,7 @@ int main(int, char**)
|
|||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplSDL2_InitForVulkan(window);
|
ImGui_ImplSDL2_InitForVulkan(window);
|
||||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||||
|
//init_info.ApiVersion = VK_API_VERSION_1_3; // Pass in your value of VkApplicationInfo::apiVersion, otherwise will default to header version.
|
||||||
init_info.Instance = g_Instance;
|
init_info.Instance = g_Instance;
|
||||||
init_info.PhysicalDevice = g_PhysicalDevice;
|
init_info.PhysicalDevice = g_PhysicalDevice;
|
||||||
init_info.Device = g_Device;
|
init_info.Device = g_Device;
|
||||||
@@ -469,16 +442,16 @@ int main(int, char**)
|
|||||||
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
|
|
||||||
// - 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.
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
//io.Fonts->AddFontDefault();
|
//io.Fonts->AddFontDefault();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
//IM_ASSERT(font != nullptr);
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
// Our state
|
// Our state
|
||||||
|
|||||||
48
examples/example_sdl3_metal/Makefile
Normal file
48
examples/example_sdl3_metal/Makefile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#
|
||||||
|
# You will need SDL3 (http://www.libsdl.org):
|
||||||
|
# brew install sdl3
|
||||||
|
#
|
||||||
|
|
||||||
|
#CXX = g++
|
||||||
|
#CXX = clang++
|
||||||
|
|
||||||
|
EXE = example_sdl3_metal
|
||||||
|
IMGUI_DIR = ../..
|
||||||
|
SOURCES = main.mm
|
||||||
|
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||||
|
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm
|
||||||
|
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||||
|
|
||||||
|
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
|
||||||
|
LIBS += `pkg-config --libs sdl3`
|
||||||
|
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||||
|
|
||||||
|
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||||
|
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||||
|
CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
|
CXXFLAGS += -Wall -Wformat
|
||||||
|
CFLAGS = $(CXXFLAGS)
|
||||||
|
|
||||||
|
%.o:%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/backends/%.cpp
|
||||||
|
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:%.mm
|
||||||
|
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
|
||||||
|
|
||||||
|
%.o:$(IMGUI_DIR)/backends/%.mm
|
||||||
|
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
@echo Build complete
|
||||||
|
|
||||||
|
$(EXE): $(OBJS)
|
||||||
|
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) $(OBJS)
|
||||||
208
examples/example_sdl3_metal/main.mm
Normal file
208
examples/example_sdl3_metal/main.mm
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
// Dear ImGui: standalone example application for SDL3 + Metal
|
||||||
|
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||||
|
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_impl_sdl3.h"
|
||||||
|
#include "imgui_impl_metal.h"
|
||||||
|
#include <stdio.h> // printf, fprintf
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
|
// Main code
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
// Setup SDL
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||||
|
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||||
|
{
|
||||||
|
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create SDL window graphics context
|
||||||
|
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||||
|
SDL_WindowFlags window_flags = SDL_WINDOW_METAL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||||
|
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Metal example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||||
|
if (window == nullptr)
|
||||||
|
{
|
||||||
|
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||||
|
SDL_ShowWindow(window);
|
||||||
|
|
||||||
|
// Create Metal device _before_ creating the view/layer
|
||||||
|
id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
|
||||||
|
if (!metalDevice)
|
||||||
|
{
|
||||||
|
printf("Error: failed to create Metal device.\n");
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
SDL_MetalView view = SDL_Metal_CreateView(window);
|
||||||
|
CAMetalLayer* layer = (__bridge CAMetalLayer*)SDL_Metal_GetLayer(view);
|
||||||
|
layer.device = metalDevice;
|
||||||
|
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
|
|
||||||
|
id<MTLCommandQueue> commandQueue = [layer.device newCommandQueue];
|
||||||
|
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new];
|
||||||
|
|
||||||
|
// Setup Dear ImGui context
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
|
|
||||||
|
// Setup Dear ImGui style
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
//ImGui::StyleColorsLight();
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||||
|
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||||
|
|
||||||
|
// Setup Platform/Renderer backends
|
||||||
|
ImGui_ImplMetal_Init(layer.device);
|
||||||
|
ImGui_ImplSDL3_InitForMetal(window);
|
||||||
|
|
||||||
|
// Load Fonts
|
||||||
|
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
|
||||||
|
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||||
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||||
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//style.FontSizeBase = 20.0f;
|
||||||
|
//io.Fonts->AddFontDefault();
|
||||||
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||||
|
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||||
|
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||||
|
//IM_ASSERT(font != nullptr);
|
||||||
|
|
||||||
|
// Our state
|
||||||
|
bool show_demo_window = true;
|
||||||
|
bool show_another_window = false;
|
||||||
|
float clear_color[4] = { 0.45f, 0.55f, 0.60f, 1.00f };
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
bool done = false;
|
||||||
|
while (!done)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
|
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||||
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||||
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||||
|
SDL_Event event;
|
||||||
|
while (SDL_PollEvent(&event))
|
||||||
|
{
|
||||||
|
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||||
|
if (event.type == SDL_EVENT_QUIT)
|
||||||
|
done = true;
|
||||||
|
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||||
|
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||||
|
{
|
||||||
|
SDL_Delay(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width, height;
|
||||||
|
SDL_GetWindowSizeInPixels(window, &width, &height);
|
||||||
|
|
||||||
|
layer.drawableSize = CGSizeMake(width, height);
|
||||||
|
id<CAMetalDrawable> drawable = [layer nextDrawable];
|
||||||
|
|
||||||
|
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
|
||||||
|
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]);
|
||||||
|
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
||||||
|
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
|
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
|
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||||
|
[renderEncoder pushDebugGroup:@"ImGui demo"];
|
||||||
|
|
||||||
|
// Start the Dear ImGui frame
|
||||||
|
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
|
||||||
|
ImGui_ImplSDL3_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
||||||
|
if (show_demo_window)
|
||||||
|
ImGui::ShowDemoWindow(&show_demo_window);
|
||||||
|
|
||||||
|
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
||||||
|
{
|
||||||
|
static float f = 0.0f;
|
||||||
|
static int counter = 0;
|
||||||
|
|
||||||
|
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
||||||
|
|
||||||
|
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
||||||
|
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
||||||
|
ImGui::Checkbox("Another Window", &show_another_window);
|
||||||
|
|
||||||
|
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||||
|
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||||
|
|
||||||
|
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
||||||
|
counter++;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("counter = %d", counter);
|
||||||
|
|
||||||
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Show another simple window.
|
||||||
|
if (show_another_window)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
||||||
|
ImGui::Text("Hello from another window!");
|
||||||
|
if (ImGui::Button("Close Me"))
|
||||||
|
show_another_window = false;
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rendering
|
||||||
|
ImGui::Render();
|
||||||
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
|
ImGui_ImplMetal_RenderDrawData(draw_data, commandBuffer, renderEncoder);
|
||||||
|
|
||||||
|
[renderEncoder popDebugGroup];
|
||||||
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
|
[commandBuffer presentDrawable:drawable];
|
||||||
|
[commandBuffer commit];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||||
|
ImGui_ImplMetal_Shutdown();
|
||||||
|
ImGui_ImplSDL3_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -45,20 +45,21 @@ endif
|
|||||||
|
|
||||||
ifeq ($(UNAME_S), Darwin) #APPLE
|
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||||
ECHO_MESSAGE = "Mac OS X"
|
ECHO_MESSAGE = "Mac OS X"
|
||||||
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl3-config --libs`
|
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
||||||
|
LIBS += `pkg-config --libs sdl3`
|
||||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||||
|
|
||||||
CXXFLAGS += `pkg-config sdl3 --cflags`
|
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||||
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||||
CFLAGS = $(CXXFLAGS)
|
CFLAGS = $(CXXFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OS), Windows_NT)
|
ifeq ($(OS), Windows_NT)
|
||||||
ECHO_MESSAGE = "MinGW"
|
ECHO_MESSAGE = "MinGW"
|
||||||
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl3`
|
LIBS += -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl3`
|
||||||
|
|
||||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||||
CFLAGS = $(CXXFLAGS)
|
CFLAGS = $(CXXFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
##---------------------------------------------------------------------
|
##---------------------------------------------------------------------
|
||||||
|
|||||||
@@ -40,6 +40,9 @@ EMS += -s USE_SDL=2
|
|||||||
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
EMS += -s DISABLE_EXCEPTION_CATCHING=1
|
||||||
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
LDFLAGS += -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=0 -s ASSERTIONS=1
|
||||||
|
|
||||||
|
# Build as single file (binary text encoded in .html file)
|
||||||
|
#LDFLAGS += -sSINGLE_FILE
|
||||||
|
|
||||||
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
# Uncomment next line to fix possible rendering bugs with Emscripten version older then 1.39.0 (https://github.com/ocornut/imgui/issues/2877)
|
||||||
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
#EMS += -s BINARYEN_TRAP_MODE=clamp
|
||||||
#EMS += -s SAFE_HEAP=1 ## Adds overhead
|
#EMS += -s SAFE_HEAP=1 ## Adds overhead
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
@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 or vcvarsall.bat to setup command-line compiler.
|
||||||
@set OUT_DIR=Debug
|
|
||||||
@set OUT_EXE=example_sdl3_opengl3
|
@set OUT_EXE=example_sdl3_opengl3
|
||||||
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include
|
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include
|
||||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
|
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
|
||||||
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib opengl32.lib shell32.lib
|
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib opengl32.lib shell32.lib
|
||||||
|
|
||||||
|
@set OUT_DIR=Debug
|
||||||
mkdir %OUT_DIR%
|
mkdir %OUT_DIR%
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||||
|
|
||||||
|
@set OUT_DIR=Release
|
||||||
|
@REM mkdir %OUT_DIR%
|
||||||
|
@REM cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user