mirror of
https://github.com/Drezil/imgui.git
synced 2025-11-09 09:31:05 +01:00
Compare commits
1429 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f337378066 | ||
|
|
8639a2f9f8 | ||
|
|
64519c6875 | ||
|
|
7b0d58c5e5 | ||
|
|
fa2b318dd6 | ||
|
|
5659db5529 | ||
|
|
a61ca097a7 | ||
|
|
dca527be1b | ||
|
|
9948535118 | ||
|
|
29d462ebce | ||
|
|
421e73e6db | ||
|
|
d9e60d29e1 | ||
|
|
5c8f8d0311 | ||
|
|
2dfa71fad5 | ||
|
|
7ff41a78f9 | ||
|
|
8d3906365d | ||
|
|
b6b8f6634e | ||
|
|
5854da10e6 | ||
|
|
71f98dd056 | ||
|
|
1e14cc5cae | ||
|
|
955aacfbc5 | ||
|
|
4691fa0ed5 | ||
|
|
aa79d0cd2f | ||
|
|
88de982071 | ||
|
|
aa86800092 | ||
|
|
97b1abd6dd | ||
|
|
1ee252772a | ||
|
|
c71a50deb5 | ||
|
|
033538731c | ||
|
|
e52bb147a7 | ||
|
|
732bc2058e | ||
|
|
40fd163a3b | ||
|
|
2554b512c0 | ||
|
|
c6cab1f352 | ||
|
|
c39192ba64 | ||
|
|
31762a8173 | ||
|
|
5017602752 | ||
|
|
37958ca1b5 | ||
|
|
8eb8689391 | ||
|
|
c1ab3c406f | ||
|
|
d378e4088f | ||
|
|
43177324c0 | ||
|
|
6f73dbea80 | ||
|
|
35e197f413 | ||
|
|
551ab84c2d | ||
|
|
422902dbda | ||
|
|
08350e53e7 | ||
|
|
64d910ad37 | ||
|
|
27004aca70 | ||
|
|
49e38a5b32 | ||
|
|
d5f0d45ae4 | ||
|
|
9def2b04d7 | ||
|
|
5429f0f6b5 | ||
|
|
c906c65cac | ||
|
|
718daa153d | ||
|
|
075f4ac661 | ||
|
|
8555335935 | ||
|
|
f1a073186c | ||
|
|
08f3aa8972 | ||
|
|
4caf1e9b59 | ||
|
|
b17b2fb732 | ||
|
|
cda3db1449 | ||
|
|
dd6a44abb1 | ||
|
|
4fb0c1f963 | ||
|
|
cff0342454 | ||
|
|
c2db4c2462 | ||
|
|
69b697378b | ||
|
|
26e59c8742 | ||
|
|
3e0d6ec895 | ||
|
|
62d6be3747 | ||
|
|
5ea47d9560 | ||
|
|
39c3412f91 | ||
|
|
3d85433748 | ||
|
|
9f8c599ca7 | ||
|
|
f33bb99821 | ||
|
|
6e63fcaca3 | ||
|
|
ceb26bac48 | ||
|
|
29f104319e | ||
|
|
19471da3fd | ||
|
|
7ad42ff431 | ||
|
|
26d04c948f | ||
|
|
97b1ffcb3b | ||
|
|
91ae56af45 | ||
|
|
673f5e588d | ||
|
|
e278277d53 | ||
|
|
1338eb31f7 | ||
|
|
007a427e0a | ||
|
|
8567a4cca3 | ||
|
|
90a6961638 | ||
|
|
7374b96f5c | ||
|
|
b8e56dce83 | ||
|
|
b6582a471a | ||
|
|
92c4ff1c2f | ||
|
|
0755767440 | ||
|
|
eb823655af | ||
|
|
f84c93d834 | ||
|
|
45c4365ec3 | ||
|
|
6188e94108 | ||
|
|
ec1e57ed4a | ||
|
|
553b04883e | ||
|
|
e51a0a80ca | ||
|
|
9551635684 | ||
|
|
0647ba3bad | ||
|
|
200a8f1ea2 | ||
|
|
98ce013242 | ||
|
|
bf4de2a46b | ||
|
|
7f8a89c25c | ||
|
|
457d4b7b72 | ||
|
|
290c51735e | ||
|
|
0818a42396 | ||
|
|
96186a93b9 | ||
|
|
956e03009a | ||
|
|
acfc7798fd | ||
|
|
e8172fdfbc | ||
|
|
9ce0f35ef3 | ||
|
|
b2e2cc44c2 | ||
|
|
ef681e7019 | ||
|
|
790132a672 | ||
|
|
1797135db5 | ||
|
|
ee436aa803 | ||
|
|
da1864d79e | ||
|
|
1bfe4a75be | ||
|
|
fe646ea591 | ||
|
|
ecd212c01d | ||
|
|
746c9f76e4 | ||
|
|
bf08c13e9b | ||
|
|
3b66929301 | ||
|
|
afffcd5810 | ||
|
|
100ede5764 | ||
|
|
4d023bd7fe | ||
|
|
704ab1114a | ||
|
|
de36ff043e | ||
|
|
29a8ee0826 | ||
|
|
1cbfe93520 | ||
|
|
2706c9d66e | ||
|
|
3a90dc3893 | ||
|
|
04bc0b0bb8 | ||
|
|
28eabcb099 | ||
|
|
206b9ead8f | ||
|
|
c5a3cae83a | ||
|
|
efa50f72a7 | ||
|
|
afb1180d7d | ||
|
|
b0a6cd6305 | ||
|
|
2402958aec | ||
|
|
92d7869fc7 | ||
|
|
83d22f4e48 | ||
|
|
9c8f288d1a | ||
|
|
2aa9959553 | ||
|
|
41e39ea6e1 | ||
|
|
dbeea7220f | ||
|
|
89a28209e8 | ||
|
|
980deb4c9e | ||
|
|
15b4a064f9 | ||
|
|
512c54bbc0 | ||
|
|
612b787b0d | ||
|
|
4bad852a78 | ||
|
|
0636f9adac | ||
|
|
d9bc1e44af | ||
|
|
0cdc4a9565 | ||
|
|
4a43dcb940 | ||
|
|
06d5f9297d | ||
|
|
248ed1b01d | ||
|
|
1c4066cd9e | ||
|
|
cd36acc88b | ||
|
|
389982eb5a | ||
|
|
48f263336b | ||
|
|
a528398c77 | ||
|
|
11638fdf7d | ||
|
|
0e8c199e87 | ||
|
|
d7350668d1 | ||
|
|
1b6b8602c1 | ||
|
|
f71ee5203e | ||
|
|
b720f1f03c | ||
|
|
8a9fe26866 | ||
|
|
747f7fdbba | ||
|
|
f605351307 | ||
|
|
c801799218 | ||
|
|
a8e1dde357 | ||
|
|
e31d116d37 | ||
|
|
e03383d088 | ||
|
|
bdd2a94315 | ||
|
|
072caa4a90 | ||
|
|
270d4d0855 | ||
|
|
0647cf434c | ||
|
|
a19815dc6b | ||
|
|
c80e8b964c | ||
|
|
b38af0f522 | ||
|
|
fc198fe1db | ||
|
|
c1b70e0391 | ||
|
|
657073a650 | ||
|
|
20e040c858 | ||
|
|
926addbfe2 | ||
|
|
027a7ba3eb | ||
|
|
a76bc52da5 | ||
|
|
6e141a9cae | ||
|
|
eea836135a | ||
|
|
aa41f16589 | ||
|
|
06e4f4e370 | ||
|
|
23ef6c149e | ||
|
|
1dc3af381a | ||
|
|
da3a36eefd | ||
|
|
c122c0ef89 | ||
|
|
b16f738d04 | ||
|
|
78c6435dbb | ||
|
|
5c388c39f4 | ||
|
|
bf80204e63 | ||
|
|
8733ca49b0 | ||
|
|
6afcfe3442 | ||
|
|
848d21b6b5 | ||
|
|
5b1a70aa2d | ||
|
|
1ab3007752 | ||
|
|
5f5ba8eb11 | ||
|
|
440824d431 | ||
|
|
f087a5b856 | ||
|
|
c5db276521 | ||
|
|
9d704d99d3 | ||
|
|
66f0fb986c | ||
|
|
5ccb66794b | ||
|
|
cb5c73f64a | ||
|
|
65f4be1a10 | ||
|
|
5ac25e7c7a | ||
|
|
719d931304 | ||
|
|
ea83d040e6 | ||
|
|
4d9a3b19d5 | ||
|
|
7f38773b73 | ||
|
|
764f9e606d | ||
|
|
b50b22d787 | ||
|
|
a3667f462a | ||
|
|
2080d12bd9 | ||
|
|
3fde445b91 | ||
|
|
d80a9123b7 | ||
|
|
2c29e391dd | ||
|
|
f8a806ad9f | ||
|
|
dc8c3618e8 | ||
|
|
7cd3cfa58a | ||
|
|
cad790d43b | ||
|
|
e790fc0e79 | ||
|
|
a9ea1ae854 | ||
|
|
eb02dcf87f | ||
|
|
8ce23b3ccd | ||
|
|
bce1ba400f | ||
|
|
ebac375791 | ||
|
|
b17dffffb3 | ||
|
|
1a7526dcd4 | ||
|
|
f01a6d3e8f | ||
|
|
c1d2793580 | ||
|
|
32779c5b64 | ||
|
|
64daeddf6f | ||
|
|
6a7e2c74fb | ||
|
|
93cccd27f6 | ||
|
|
cd1b5f7883 | ||
|
|
b409df34db | ||
|
|
0b4edf4e94 | ||
|
|
14466a6d19 | ||
|
|
978598b174 | ||
|
|
d1eb7b5757 | ||
|
|
eb654f1bad | ||
|
|
b1a68d899c | ||
|
|
a67f7dce31 | ||
|
|
8d361c47fb | ||
|
|
8361ed1f54 | ||
|
|
19c72cd52a | ||
|
|
c363b6df2b | ||
|
|
0f2898ea88 | ||
|
|
99552420a2 | ||
|
|
126a6f894f | ||
|
|
9c78fc928a | ||
|
|
2318c764cf | ||
|
|
39b99072fb | ||
|
|
ad3f54ff1a | ||
|
|
bac748fa95 | ||
|
|
19c3773cc0 | ||
|
|
bbd5119a26 | ||
|
|
05877c14df | ||
|
|
9b59455184 | ||
|
|
e3bd9434b1 | ||
|
|
13cdf2ff0e | ||
|
|
29653273c1 | ||
|
|
be03b8ff93 | ||
|
|
1b215ecb01 | ||
|
|
55d35d8387 | ||
|
|
75c54e6384 | ||
|
|
ba5c105c01 | ||
|
|
44f801186f | ||
|
|
ec6ca06898 | ||
|
|
dde31030e9 | ||
|
|
30a6873a44 | ||
|
|
31d033c9d8 | ||
|
|
fbe78b1a3a | ||
|
|
1780579403 | ||
|
|
25332fa5ac | ||
|
|
2de96c4bd5 | ||
|
|
e443ea139d | ||
|
|
30db674147 | ||
|
|
164a86d3b0 | ||
|
|
677fe33990 | ||
|
|
8f495e5543 | ||
|
|
835a5344b0 | ||
|
|
65ad63de84 | ||
|
|
fc4988ffb0 | ||
|
|
24a77824f2 | ||
|
|
bbb95a5e06 | ||
|
|
ca097c2c68 | ||
|
|
fba756176d | ||
|
|
62b17f928e | ||
|
|
d7260104b1 | ||
|
|
15fe7ba31f | ||
|
|
30546bc0e7 | ||
|
|
15132217a3 | ||
|
|
fa0a314f59 | ||
|
|
bc3d267c51 | ||
|
|
c6ca327fb2 | ||
|
|
ddddabdccf | ||
|
|
2cffcbdc64 | ||
|
|
3973de7933 | ||
|
|
2d0a6a4969 | ||
|
|
66cd21db88 | ||
|
|
d366694062 | ||
|
|
4f10fe0a27 | ||
|
|
c58fb46411 | ||
|
|
e7cc534367 | ||
|
|
29828d0469 | ||
|
|
7b8bc864e9 | ||
|
|
8dfb52245b | ||
|
|
82754561e2 | ||
|
|
5d95e7eef9 | ||
|
|
92a39f78b9 | ||
|
|
17a7084b57 | ||
|
|
79d39b190b | ||
|
|
6b77668171 | ||
|
|
9a49c1ddbd | ||
|
|
6b1e094cfb | ||
|
|
cfb837203c | ||
|
|
321b84f01f | ||
|
|
40caab4748 | ||
|
|
fa9fc05ac6 | ||
|
|
d9b427cce0 | ||
|
|
755bf985d2 | ||
|
|
607ad8c949 | ||
|
|
bd6c9e99fc | ||
|
|
0a154b30ad | ||
|
|
ade4c15eea | ||
|
|
528104a89b | ||
|
|
5ee40c8d34 | ||
|
|
dff15acdb5 | ||
|
|
3d9d3b49ae | ||
|
|
73a5e82e04 | ||
|
|
a735a8c084 | ||
|
|
ee351d3548 | ||
|
|
7b913db1ce | ||
|
|
53589092b2 | ||
|
|
eb6c16d3dd | ||
|
|
03ce17f0a5 | ||
|
|
dedb381c51 | ||
|
|
7c4ffe490d | ||
|
|
4aea1c5adb | ||
|
|
66102880a3 | ||
|
|
333807b483 | ||
|
|
11103f8253 | ||
|
|
0eb45a0577 | ||
|
|
bb6a60b1ff | ||
|
|
ccfb20095e | ||
|
|
4351febe9f | ||
|
|
20a1edef89 | ||
|
|
b08ed61907 | ||
|
|
84890a3074 | ||
|
|
4c31c98d22 | ||
|
|
80ed4eba87 | ||
|
|
58f5092c53 | ||
|
|
780c1ee265 | ||
|
|
2b0bd40b99 | ||
|
|
f8bad7e1e3 | ||
|
|
4a7c21d330 | ||
|
|
e652527313 | ||
|
|
51d841dcf3 | ||
|
|
4c22b3e5d9 | ||
|
|
0608887fb5 | ||
|
|
68f428b449 | ||
|
|
6afe9bbb45 | ||
|
|
e23bee353c | ||
|
|
0649f750b4 | ||
|
|
e3e1fbcf02 | ||
|
|
d79ca9b0b6 | ||
|
|
e6ffc04291 | ||
|
|
6bd447c885 | ||
|
|
47fb332fb2 | ||
|
|
32d4f6c5d9 | ||
|
|
2e01952b35 | ||
|
|
f969e68c10 | ||
|
|
5a7d18a441 | ||
|
|
9c3359ef39 | ||
|
|
0b06c4b2b0 | ||
|
|
80b5fb51ed | ||
|
|
f9b5168fb3 | ||
|
|
7bfc379a23 | ||
|
|
3d5dc0d939 | ||
|
|
a11f36811f | ||
|
|
eb6f4b1a6a | ||
|
|
cd4cc9ff0d | ||
|
|
9e8e5ac363 | ||
|
|
6136b3844b | ||
|
|
0a8ab75e4b | ||
|
|
36a0d1028c | ||
|
|
0f7eb00f67 | ||
|
|
682447306d | ||
|
|
ac35b4bba2 | ||
|
|
cce307a2be | ||
|
|
afabb2f3d8 | ||
|
|
9b417b26d9 | ||
|
|
90deb0959a | ||
|
|
db0338a1f2 | ||
|
|
4161a67b38 | ||
|
|
865b2ca6f9 | ||
|
|
a44d4da87c | ||
|
|
16abfa5eb6 | ||
|
|
f53db3541a | ||
|
|
5e528d9eea | ||
|
|
f03ab2a5c5 | ||
|
|
fa1f540e6c | ||
|
|
91704b773e | ||
|
|
1ad1429c6d | ||
|
|
1b435ae3e0 | ||
|
|
105d82d134 | ||
|
|
86c2b609ef | ||
|
|
2cdfcb8fd2 | ||
|
|
31290807dc | ||
|
|
33cdbe97b8 | ||
|
|
34d4bc620d | ||
|
|
76902c482f | ||
|
|
e5efa01920 | ||
|
|
3f16a524c8 | ||
|
|
646c873598 | ||
|
|
e87dd0e65d | ||
|
|
539de4387b | ||
|
|
65cd14502c | ||
|
|
6ddcdbe3e8 | ||
|
|
9251eac585 | ||
|
|
3ed07a8f0b | ||
|
|
0e0a783b8c | ||
|
|
5991851eb9 | ||
|
|
a4adf60576 | ||
|
|
b79b1cb9c0 | ||
|
|
d7051928d9 | ||
|
|
b305953bd1 | ||
|
|
e7577d570e | ||
|
|
ca34c81ce9 | ||
|
|
085cff2fe5 | ||
|
|
b17bfdd6f4 | ||
|
|
81e0b18e38 | ||
|
|
b202fa9063 | ||
|
|
2231e1a369 | ||
|
|
256594575d | ||
|
|
cfe83c4b44 | ||
|
|
0157502eab | ||
|
|
f1bf642e8f | ||
|
|
4b9bc49020 | ||
|
|
d5a4d53000 | ||
|
|
705f082674 | ||
|
|
80533ea5e1 | ||
|
|
6aee4bcdc5 | ||
|
|
b794ecc079 | ||
|
|
732cd837a9 | ||
|
|
839ecce571 | ||
|
|
3ec14186cb | ||
|
|
a4e4f57cb0 | ||
|
|
ffa863a3ba | ||
|
|
3d75f438bc | ||
|
|
7180e9ac66 | ||
|
|
239d09804d | ||
|
|
04f7ea818d | ||
|
|
ee59d7a266 | ||
|
|
3607c42bec | ||
|
|
2a5eaf239f | ||
|
|
6f5f80a544 | ||
|
|
7a516a266d | ||
|
|
73ccb7e4b8 | ||
|
|
1a3af8cb4c | ||
|
|
862bfc53d3 | ||
|
|
fa55b0cb60 | ||
|
|
22d9a61b33 | ||
|
|
84e8802891 | ||
|
|
577e7cb493 | ||
|
|
cff8162454 | ||
|
|
376c88a864 | ||
|
|
bb26751b94 | ||
|
|
ebbb98d519 | ||
|
|
9e4956d86b | ||
|
|
388ca563db | ||
|
|
70703da782 | ||
|
|
b11518d7d7 | ||
|
|
7b53551032 | ||
|
|
06e87014f2 | ||
|
|
dd4ca70b0d | ||
|
|
657589ab47 | ||
|
|
c1ffac2fee | ||
|
|
4da92b89ed | ||
|
|
3dcbcd8bf0 | ||
|
|
cecf6b4209 | ||
|
|
b2a91dc390 | ||
|
|
ac08593b96 | ||
|
|
e3ac52630a | ||
|
|
455c21df71 | ||
|
|
d3a80d9f1b | ||
|
|
b26f1530b7 | ||
|
|
bae2240eda | ||
|
|
042a3b01d2 | ||
|
|
682249396f | ||
|
|
958e58b06b | ||
|
|
c49330fc52 | ||
|
|
fa004ae79a | ||
|
|
42575d4a99 | ||
|
|
6bc526676c | ||
|
|
e230ec5a01 | ||
|
|
770c995365 | ||
|
|
78f753ffff | ||
|
|
aa8e09d7f1 | ||
|
|
36c331ff74 | ||
|
|
8dacb4da20 | ||
|
|
fc625d249f | ||
|
|
34077c0140 | ||
|
|
600b8f60b4 | ||
|
|
e9053515bb | ||
|
|
30f0900b1c | ||
|
|
831e2c920e | ||
|
|
cf312545e8 | ||
|
|
d6f3a8848d | ||
|
|
9d20a5f0a5 | ||
|
|
ad8fdc917f | ||
|
|
05bc204dbd | ||
|
|
b36d1d465d | ||
|
|
25a9209b75 | ||
|
|
a9626e1162 | ||
|
|
a5ba26806f | ||
|
|
dbc70f21a9 | ||
|
|
85a661d276 | ||
|
|
acf043a675 | ||
|
|
2c13a74a9d | ||
|
|
de1588928b | ||
|
|
70fa37527d | ||
|
|
3d4af15d1d | ||
|
|
cba52b66af | ||
|
|
f79f0e42f7 | ||
|
|
cbade7b16d | ||
|
|
b626dd57d3 | ||
|
|
cb1d578470 | ||
|
|
4f5aac319e | ||
|
|
fc9d6b6cb5 | ||
|
|
4bdbea8375 | ||
|
|
2b9d88196e | ||
|
|
90ea7e2f2f | ||
|
|
ddabfc3477 | ||
|
|
f4f04cb5ec | ||
|
|
d7ef56dca2 | ||
|
|
5628416bd3 | ||
|
|
7538bbabb6 | ||
|
|
e1d7e14717 | ||
|
|
a616ff5d4a | ||
|
|
76e40fe5d1 | ||
|
|
20d61f5f62 | ||
|
|
2665288b30 | ||
|
|
8baa4ccff5 | ||
|
|
5d472c4895 | ||
|
|
0fe5170bc4 | ||
|
|
615e9ae345 | ||
|
|
3b3af6b731 | ||
|
|
e4d8267188 | ||
|
|
1cd32d3afe | ||
|
|
03ea87ea28 | ||
|
|
c46b79846c | ||
|
|
6636cb9f2f | ||
|
|
1e7672acf4 | ||
|
|
8596f2b0fc | ||
|
|
538d28e29e | ||
|
|
574ff0a280 | ||
|
|
51e568f9dc | ||
|
|
582f4db59b | ||
|
|
5116eee108 | ||
|
|
7ddc1adefb | ||
|
|
266dff9bed | ||
|
|
7f8b076f2b | ||
|
|
36ac557df0 | ||
|
|
013013737f | ||
|
|
b8e2b2bd6b | ||
|
|
71eb4034eb | ||
|
|
c142540705 | ||
|
|
3930472f34 | ||
|
|
6d03f93067 | ||
|
|
0e884304ee | ||
|
|
9085c2cae2 | ||
|
|
e8568f3ec9 | ||
|
|
16a9488c13 | ||
|
|
ea0399414c | ||
|
|
1abb02fb67 | ||
|
|
fbaf65b8f6 | ||
|
|
f2c7f3b200 | ||
|
|
1b579a110d | ||
|
|
7e00cde8a9 | ||
|
|
1ecc1db226 | ||
|
|
a7ace918fe | ||
|
|
91ac93f9a6 | ||
|
|
05c3e0b898 | ||
|
|
103c5edaaa | ||
|
|
75de34e281 | ||
|
|
f032ad6b1f | ||
|
|
871727dd2f | ||
|
|
3ff13edad9 | ||
|
|
7d80a8f4f5 | ||
|
|
3c80d57dc7 | ||
|
|
bb1e6f8af6 | ||
|
|
8432d1bfc7 | ||
|
|
7e2d172ae5 | ||
|
|
3bde375078 | ||
|
|
365b639981 | ||
|
|
d4fc525614 | ||
|
|
5be649e082 | ||
|
|
4b4be11fd2 | ||
|
|
e7bfcb970e | ||
|
|
7794b104c5 | ||
|
|
3b828e6f96 | ||
|
|
bbe946fb6c | ||
|
|
377f730054 | ||
|
|
f5528001f6 | ||
|
|
f68075b333 | ||
|
|
f1b5c742ff | ||
|
|
7e068da2bd | ||
|
|
44174b1fa1 | ||
|
|
861f786d81 | ||
|
|
f6951bb67d | ||
|
|
3b1b5266e5 | ||
|
|
c163b856d7 | ||
|
|
07eb7adbb4 | ||
|
|
4c108d22f0 | ||
|
|
c706ff6f3a | ||
|
|
992736dc5d | ||
|
|
927580d4a8 | ||
|
|
a1e4af62d3 | ||
|
|
28dd8d7efd | ||
|
|
4dff49b2f1 | ||
|
|
71a58261f6 | ||
|
|
8d1b82d596 | ||
|
|
3096e7a9cd | ||
|
|
1c3a9c8e74 | ||
|
|
813e0c18e6 | ||
|
|
3a82994429 | ||
|
|
106184bbea | ||
|
|
3895363432 | ||
|
|
a1e43c682a | ||
|
|
c3fd4ae473 | ||
|
|
69b5c2f541 | ||
|
|
a704614b3e | ||
|
|
6024051a2f | ||
|
|
b3e94f5de8 | ||
|
|
32380a0112 | ||
|
|
664fb38e39 | ||
|
|
0cbb96895a | ||
|
|
7b77cb3bb8 | ||
|
|
6faad0c34f | ||
|
|
05c1f2795a | ||
|
|
7feccf9ab2 | ||
|
|
bf4880f6a2 | ||
|
|
e0c0e53edf | ||
|
|
6994bf10bc | ||
|
|
3233d85d2f | ||
|
|
13f00331da | ||
|
|
af93c21cf9 | ||
|
|
cf98290873 | ||
|
|
1ca6ff974c | ||
|
|
575df6f192 | ||
|
|
0bdc145343 | ||
|
|
d049a7988c | ||
|
|
a4af3cc814 | ||
|
|
a89a3cd2f1 | ||
|
|
09780b8b3d | ||
|
|
9e294be5c5 | ||
|
|
a01d149369 | ||
|
|
483534b525 | ||
|
|
e1fca8d982 | ||
|
|
10a202422a | ||
|
|
27431dcc6b | ||
|
|
d8f9f6ba2a | ||
|
|
72090b646f | ||
|
|
aedcd2fb1a | ||
|
|
76ccbb899d | ||
|
|
5d87ee8d82 | ||
|
|
451c756b01 | ||
|
|
3aa9aae0be | ||
|
|
967073ba3d | ||
|
|
b8d8355f10 | ||
|
|
07c52a25ff | ||
|
|
cb2de62bb1 | ||
|
|
949a9fa2cb | ||
|
|
a1164399b0 | ||
|
|
e5b905481d | ||
|
|
7c183dc6a1 | ||
|
|
7fbd72b735 | ||
|
|
969278fc0b | ||
|
|
efc4c0fe9d | ||
|
|
81b24bd728 | ||
|
|
db2581bee9 | ||
|
|
75136d3bea | ||
|
|
0e6a096afd | ||
|
|
6f8d34768d | ||
|
|
9cda3035fd | ||
|
|
47f5ad32b7 | ||
|
|
9f35ba8546 | ||
|
|
7fd34d4f30 | ||
|
|
bb2aa5e770 | ||
|
|
56e10f1c35 | ||
|
|
718e15c7de | ||
|
|
8bc6d976cb | ||
|
|
dd80db87a6 | ||
|
|
1f54c16f52 | ||
|
|
50d421fa19 | ||
|
|
adbbd17cb6 | ||
|
|
3e8eebfbec | ||
|
|
2cbc0f1287 | ||
|
|
e2c1f0a7cd | ||
|
|
ca43436cd3 | ||
|
|
b27fd87177 | ||
|
|
07d3083279 | ||
|
|
d3d998a885 | ||
|
|
5f409c6fcc | ||
|
|
63310acd58 | ||
|
|
e6850891cc | ||
|
|
440ad0b440 | ||
|
|
5cdd788f30 | ||
|
|
596d81a973 | ||
|
|
84f3ecc231 | ||
|
|
cc48f1e5dd | ||
|
|
8dc04a4c9f | ||
|
|
c72040a715 | ||
|
|
c7c1bf177b | ||
|
|
5b0e59d9d5 | ||
|
|
7c06d9f043 | ||
|
|
511e32e8ca | ||
|
|
e5dfa0855f | ||
|
|
afad952450 | ||
|
|
fda1365c15 | ||
|
|
04022114d9 | ||
|
|
1575a3fbcd | ||
|
|
7e772f6a51 | ||
|
|
2e5860b5a0 | ||
|
|
4158cba1ff | ||
|
|
b955e485f1 | ||
|
|
02d6d2d487 | ||
|
|
b668726a38 | ||
|
|
835a8b2c9b | ||
|
|
239c8732d7 | ||
|
|
9bf3f910c8 | ||
|
|
e6c982509d | ||
|
|
9ddb8493d5 | ||
|
|
76e61958fd | ||
|
|
4f22a45cb5 | ||
|
|
825b61e4ba | ||
|
|
7e67aba286 | ||
|
|
a649d904d7 | ||
|
|
dfb82d5c22 | ||
|
|
d0fb547dc1 | ||
|
|
20f0cb0281 | ||
|
|
03b64defa5 | ||
|
|
655ebe4eaf | ||
|
|
b89202824e | ||
|
|
f70eacee8e | ||
|
|
433a7556c7 | ||
|
|
712203dbcb | ||
|
|
800fb26606 | ||
|
|
224f087a5f | ||
|
|
092426bed2 | ||
|
|
c6f1b7b92a | ||
|
|
328e4fa7e7 | ||
|
|
f3110a57cd | ||
|
|
cf029b3e1c | ||
|
|
7056032483 | ||
|
|
50ceb25003 | ||
|
|
9c364b16ff | ||
|
|
d61caf5714 | ||
|
|
e70f866ed2 | ||
|
|
9acb158990 | ||
|
|
1ba79baab5 | ||
|
|
01de69de36 | ||
|
|
8ec24036d7 | ||
|
|
29269d2aa8 | ||
|
|
43a85dd02e | ||
|
|
9ba64f9fe3 | ||
|
|
49fb8e6c45 | ||
|
|
9bf6509c6e | ||
|
|
5af385ea78 | ||
|
|
47219dd5c6 | ||
|
|
b6ae8a0dca | ||
|
|
a33d45d7cd | ||
|
|
5a665e423c | ||
|
|
fc95da8aa3 | ||
|
|
fd5859ed04 | ||
|
|
75e3793f4d | ||
|
|
8d4b5fef1d | ||
|
|
04a9ce3a18 | ||
|
|
87883abd86 | ||
|
|
f20725eada | ||
|
|
26646f2450 | ||
|
|
f208fd7ebb | ||
|
|
9350158d61 | ||
|
|
7a5196601e | ||
|
|
c7619d4a6a | ||
|
|
7ba774a440 | ||
|
|
b1af4d36ce | ||
|
|
c3f20f6b81 | ||
|
|
e7dca4fec2 | ||
|
|
9afb849e16 | ||
|
|
e1acb0b1fa | ||
|
|
3ead9820f7 | ||
|
|
f7db4fad31 | ||
|
|
cf4fcc4735 | ||
|
|
3eedb542a6 | ||
|
|
ecf7666624 | ||
|
|
d77d3416d3 | ||
|
|
5ce93bc0cc | ||
|
|
54a129a2e2 | ||
|
|
bdf60dac6a | ||
|
|
bbb543fc16 | ||
|
|
28d8eb220b | ||
|
|
0a6c5bc234 | ||
|
|
e91d275b10 | ||
|
|
8b8ab1db5b | ||
|
|
e02d6014bf | ||
|
|
8414c0bb09 | ||
|
|
49eb5f0280 | ||
|
|
7a536f1bd2 | ||
|
|
ff0c6c2bde | ||
|
|
4eecf80a4b | ||
|
|
104294c7e4 | ||
|
|
6b43a314bf | ||
|
|
8915f7933a | ||
|
|
87ded34f9f | ||
|
|
ff0f9aa856 | ||
|
|
9dc02464a4 | ||
|
|
7573d10a4a | ||
|
|
5412cdf2c8 | ||
|
|
3de440fda2 | ||
|
|
5bf9029bf9 | ||
|
|
09c9bf2edb | ||
|
|
b46076458c | ||
|
|
8691b56136 | ||
|
|
7f6a025c93 | ||
|
|
2cada3c143 | ||
|
|
4a3a895be9 | ||
|
|
f6fbb99a9c | ||
|
|
be107ba8f8 | ||
|
|
f902435a53 | ||
|
|
80d51c692a | ||
|
|
7227454dca | ||
|
|
f087359621 | ||
|
|
e215809c4d | ||
|
|
03b0266b59 | ||
|
|
d1c45c0d76 | ||
|
|
e30babef09 | ||
|
|
a608156da3 | ||
|
|
65a2350a5f | ||
|
|
cbf24a9151 | ||
|
|
f906d53f7d | ||
|
|
1f2bdd37b3 | ||
|
|
dc8ff68871 | ||
|
|
5536edede9 | ||
|
|
578e15f006 | ||
|
|
e1143377c2 | ||
|
|
8563ef3ce4 | ||
|
|
37fb531d1c | ||
|
|
86d3bba157 | ||
|
|
2ccc6d2ed1 | ||
|
|
13a5f5ba8b | ||
|
|
737a3644fc | ||
|
|
07ff47bf1b | ||
|
|
0737433c71 | ||
|
|
0bda7f196d | ||
|
|
9f96fcff3c | ||
|
|
bfacbac7c4 | ||
|
|
86fce79a6c | ||
|
|
c81a5a6070 | ||
|
|
0947fa3de0 | ||
|
|
cb9a6b8a8b | ||
|
|
2d21a64fed | ||
|
|
f94af2f5c5 | ||
|
|
8079344cee | ||
|
|
82e31d34f0 | ||
|
|
acdb4823dd | ||
|
|
b5144e477f | ||
|
|
e9c625a1dc | ||
|
|
d1851ed6b7 | ||
|
|
32c4e01267 | ||
|
|
2f9bae140b | ||
|
|
8a45c56c2c | ||
|
|
9391a97fbf | ||
|
|
79d497edae | ||
|
|
515ad62335 | ||
|
|
73353fad64 | ||
|
|
ff4bd758ca | ||
|
|
e24674fc0e | ||
|
|
529fccd9c2 | ||
|
|
4ee4f65c70 | ||
|
|
7cc86d4bc9 | ||
|
|
8011197c50 | ||
|
|
c96aaef132 | ||
|
|
6b32570644 | ||
|
|
5af930f97a | ||
|
|
515ecbddc2 | ||
|
|
7f7e8eeecd | ||
|
|
4e98d4329b | ||
|
|
5278da98d2 | ||
|
|
e1ed27aeaa | ||
|
|
c8349d3305 | ||
|
|
606175b98f | ||
|
|
05bc323be0 | ||
|
|
599a52629a | ||
|
|
c3efccaa9c | ||
|
|
b26f16a27f | ||
|
|
a0c2e55e8c | ||
|
|
5aebfedfad | ||
|
|
ce1626a51e | ||
|
|
0cabe4dedf | ||
|
|
0d6e3ab2b0 | ||
|
|
cfcad42b89 | ||
|
|
4a6f95acc8 | ||
|
|
5305c32242 | ||
|
|
951c9dd68b | ||
|
|
4ea9fdbbea | ||
|
|
e194219f2e | ||
|
|
a71d3c8cb3 | ||
|
|
238321c159 | ||
|
|
e181b0c3fc | ||
|
|
9d0bc3f9ab | ||
|
|
afe9c5c5f7 | ||
|
|
81a2546cea | ||
|
|
ee5560a958 | ||
|
|
62cfdceac1 | ||
|
|
d9fda22763 | ||
|
|
8dd83c5fe8 | ||
|
|
5794c0491a | ||
|
|
e043b89814 | ||
|
|
8fc19d2194 | ||
|
|
02501f07c3 | ||
|
|
a0e5bb9532 | ||
|
|
088ef6623a | ||
|
|
9c916cdaf9 | ||
|
|
ac9512e095 | ||
|
|
5d20da1b36 | ||
|
|
9b09c7597f | ||
|
|
2a1e903f43 | ||
|
|
e50894c95e | ||
|
|
991b16cc6a | ||
|
|
2886e0b6f5 | ||
|
|
067b691fd8 | ||
|
|
c40feabe4d | ||
|
|
2d4018aa89 | ||
|
|
e6439e1a16 | ||
|
|
26b9e2d0a5 | ||
|
|
3a5e758ee3 | ||
|
|
f768727284 | ||
|
|
a03846bd9e | ||
|
|
f3a0b17bb8 | ||
|
|
ac52d9d44c | ||
|
|
e2082a675c | ||
|
|
b94f0241f1 | ||
|
|
b96b1f2412 | ||
|
|
6644f1ff64 | ||
|
|
8cac70d8af | ||
|
|
5105c6c0d0 | ||
|
|
3a678d48b1 | ||
|
|
8bac6d428d | ||
|
|
2da200fc16 | ||
|
|
f6b6ad1959 | ||
|
|
3e84f7cd1d | ||
|
|
ac10889bde | ||
|
|
89a530b442 | ||
|
|
65e579e558 | ||
|
|
34e18ef771 | ||
|
|
8289e5f6b4 | ||
|
|
025e00cccc | ||
|
|
f78b5a0cdb | ||
|
|
ec49a486c7 | ||
|
|
afeefadb4e | ||
|
|
a423f032ee | ||
|
|
4ef06f5aa2 | ||
|
|
753223bd7b | ||
|
|
f663277591 | ||
|
|
1c7be88a1a | ||
|
|
3c114b280a | ||
|
|
2fbbcaa339 | ||
|
|
36cbe1e521 | ||
|
|
19d17ed274 | ||
|
|
01f940dc9a | ||
|
|
19c4fa8dd5 | ||
|
|
3bcc25f588 | ||
|
|
4cadb57c46 | ||
|
|
99c32ed4a5 | ||
|
|
c08b4b46f4 | ||
|
|
e138a5fcb5 | ||
|
|
fc16e54612 | ||
|
|
4575354bc0 | ||
|
|
3f51c831de | ||
|
|
962dcb466d | ||
|
|
b8d9c5c130 | ||
|
|
1a0d2578a1 | ||
|
|
12a1e7d04e | ||
|
|
4a8efd7e68 | ||
|
|
66cfbbff5e | ||
|
|
d23c69d319 | ||
|
|
1e7b50aeae | ||
|
|
c93e92671a | ||
|
|
ddc3f8f069 | ||
|
|
5261e5a6ba | ||
|
|
379733aba1 | ||
|
|
131de7ab62 | ||
|
|
d8ab2c1ac9 | ||
|
|
862781b195 | ||
|
|
cae4d020dc | ||
|
|
1f78e08427 | ||
|
|
760c1d95b9 | ||
|
|
510f0e505c | ||
|
|
d9c54826bb | ||
|
|
2515413080 | ||
|
|
d87b80c6c1 | ||
|
|
4a43f347bb | ||
|
|
dcbf976a8e | ||
|
|
f2d577c33f | ||
|
|
ae34241f8b | ||
|
|
1546153ca2 | ||
|
|
a3d6554e8e | ||
|
|
565af90958 | ||
|
|
797f2044cd | ||
|
|
5ea08394f5 | ||
|
|
9ee86f22b7 | ||
|
|
52ca91ca57 | ||
|
|
168af9b377 | ||
|
|
1a6eea012d | ||
|
|
50f6e12d31 | ||
|
|
c547b2e8ee | ||
|
|
56ba60ee68 | ||
|
|
f270c81c49 | ||
|
|
745fda081e | ||
|
|
5f8c9ae0ef | ||
|
|
056af2b1af | ||
|
|
5f79a28a07 | ||
|
|
69db792bf0 | ||
|
|
8b956216b7 | ||
|
|
e6cc547a94 | ||
|
|
e73217d6f7 | ||
|
|
2eaf5b03df | ||
|
|
c398153b40 | ||
|
|
33994bbfa1 | ||
|
|
7525637804 | ||
|
|
15ec78e9d8 | ||
|
|
3a7828de6b | ||
|
|
7b3433c68b | ||
|
|
84507cc744 | ||
|
|
cb76c086e0 | ||
|
|
407822e6a5 | ||
|
|
4e30698706 | ||
|
|
2dd8338e7d | ||
|
|
059560d28b | ||
|
|
d348d86df4 | ||
|
|
1d3862b6b3 | ||
|
|
bd82539ad5 | ||
|
|
83f55c9de5 | ||
|
|
33b88a0339 | ||
|
|
44bfa24cc3 | ||
|
|
2cff3f6a65 | ||
|
|
b48ed9ebc0 | ||
|
|
4e717b524c | ||
|
|
ae657a349a | ||
|
|
ed3c015f4e | ||
|
|
9cfc40c2cc | ||
|
|
6ebc63d3ef | ||
|
|
1ae0a1e658 | ||
|
|
46dff42239 | ||
|
|
35d1fb7b34 | ||
|
|
876a3299fc | ||
|
|
93896d550e | ||
|
|
18ffb7dd86 | ||
|
|
c0a89f8f4e | ||
|
|
c6193d0605 | ||
|
|
6cc380fc41 | ||
|
|
4053d9d638 | ||
|
|
45731cca19 | ||
|
|
dc92431328 | ||
|
|
d3e8e5731a | ||
|
|
53a5d32df1 | ||
|
|
85e1e2b0c8 | ||
|
|
9960ccddb2 | ||
|
|
4021776d0f | ||
|
|
fa0ce4b7d5 | ||
|
|
2a5ce1849a | ||
|
|
ae4b838840 | ||
|
|
79c075ca09 | ||
|
|
1127804109 | ||
|
|
67be485e24 | ||
|
|
fda57f48d5 | ||
|
|
840652830d | ||
|
|
5eabf44021 | ||
|
|
599d5f185c | ||
|
|
7abc368927 | ||
|
|
b57baa5ba0 | ||
|
|
3e47978a80 | ||
|
|
e647f89c33 | ||
|
|
82978fc88f | ||
|
|
95d49c3b98 | ||
|
|
455dc6e229 | ||
|
|
291bfe6841 | ||
|
|
35032d41fa | ||
|
|
28094b7cea | ||
|
|
b55b9aee9b | ||
|
|
0f1c21a6c9 | ||
|
|
175bab4f5f | ||
|
|
ba7b68798d | ||
|
|
e32256b4b4 | ||
|
|
132d8c5a99 | ||
|
|
b85f345369 | ||
|
|
85a3fb3bef | ||
|
|
6d91055462 | ||
|
|
136fc56af0 | ||
|
|
c355ed1267 | ||
|
|
1cefc48f13 | ||
|
|
211a9c8fd2 | ||
|
|
f29b3b4033 | ||
|
|
df65d4a14f | ||
|
|
c4e26f4b92 | ||
|
|
416918429d | ||
|
|
d5692bff00 | ||
|
|
dcef0c0237 | ||
|
|
a68c98bb67 | ||
|
|
b872aa5c8e | ||
|
|
a82be53407 | ||
|
|
49533bc86e | ||
|
|
e381f22ac1 | ||
|
|
9ac1e93aa1 | ||
|
|
bd5b38e232 | ||
|
|
5adcb9ce6d | ||
|
|
2ec135c9f7 | ||
|
|
58d46e1fe6 | ||
|
|
c039a77d21 | ||
|
|
741bdf151a | ||
|
|
5070c769b8 | ||
|
|
52e0de84a9 | ||
|
|
b974fffea0 | ||
|
|
a2616c79fe | ||
|
|
31b5b18611 | ||
|
|
8601c39571 | ||
|
|
af27ec296b | ||
|
|
a848807847 | ||
|
|
bdb30d7145 | ||
|
|
897e5c6231 | ||
|
|
1007873d94 | ||
|
|
fd201a90f1 | ||
|
|
a52ce7ac8b | ||
|
|
fd90afef43 | ||
|
|
5207afa0dd | ||
|
|
0699310b9c | ||
|
|
0c24fe276c | ||
|
|
c83391262e | ||
|
|
00262d51ad | ||
|
|
d7c04ccbfb | ||
|
|
b1f263b34b | ||
|
|
a58e4dfd0f | ||
|
|
18d6490dbd | ||
|
|
346f83e014 | ||
|
|
fefcc77f13 | ||
|
|
b6cdfef442 | ||
|
|
172e426ba9 | ||
|
|
f74d9ec7f7 | ||
|
|
9093166eea | ||
|
|
f5ed5478e1 | ||
|
|
9a4234ea8e | ||
|
|
af002dc861 | ||
|
|
adeb993122 | ||
|
|
81bc4265e5 | ||
|
|
a44c5f7afe | ||
|
|
66b51940bd | ||
|
|
d4e49a2697 | ||
|
|
521405488b | ||
|
|
24dfa0c957 | ||
|
|
158a65c98f | ||
|
|
6caf074bd5 | ||
|
|
905e14f384 | ||
|
|
4be79a8955 | ||
|
|
2d952504ed | ||
|
|
43219d36a6 | ||
|
|
99b27488e7 | ||
|
|
18972c5513 | ||
|
|
e312363007 | ||
|
|
6c34bffbb5 | ||
|
|
36b2f64051 | ||
|
|
705ff49400 | ||
|
|
f81caac459 | ||
|
|
0ada716184 | ||
|
|
e9c849884a | ||
|
|
a4191857c1 | ||
|
|
9d7480774f | ||
|
|
5d630c930d | ||
|
|
9852649e97 | ||
|
|
1722a31155 | ||
|
|
e5f2295398 | ||
|
|
8ef0ca9765 | ||
|
|
c031ea088a | ||
|
|
9824bf1ba1 | ||
|
|
0095b7a0ea | ||
|
|
6b4f6cd2c5 | ||
|
|
1b646a4440 | ||
|
|
f22024cb19 | ||
|
|
049c515840 | ||
|
|
352695bc57 | ||
|
|
74077491ce | ||
|
|
23b67e6ff5 | ||
|
|
7b4fbf4301 | ||
|
|
b8b74970d7 | ||
|
|
defbf1c4b3 | ||
|
|
16c6734bcb | ||
|
|
ee98a069f0 | ||
|
|
b30b82835a | ||
|
|
d107146687 | ||
|
|
88df66ec83 | ||
|
|
ce18371d1b | ||
|
|
9dea27b273 | ||
|
|
140ece0aeb | ||
|
|
7abf72ec78 | ||
|
|
574185426c | ||
|
|
dd61c4802a | ||
|
|
14cef31467 | ||
|
|
6277781e83 | ||
|
|
770cba0bd0 | ||
|
|
c38fe6b0e1 | ||
|
|
d3ee3e7ab5 | ||
|
|
ce500f8727 | ||
|
|
9a5f742e63 | ||
|
|
7e6700d261 | ||
|
|
c71522adc5 | ||
|
|
70b0bd13aa | ||
|
|
087ab2acbf | ||
|
|
24aeca3d0c | ||
|
|
9660657e95 | ||
|
|
13a3a2d0f3 | ||
|
|
ff4f40de41 | ||
|
|
24fc7c30dd | ||
|
|
06aa9d8d9a | ||
|
|
8c374512fd | ||
|
|
77d51ebf24 | ||
|
|
93b032ea92 | ||
|
|
03c8a78f04 | ||
|
|
002e513b82 | ||
|
|
ed84b2aaeb | ||
|
|
1176460e44 | ||
|
|
01429e7d16 | ||
|
|
4c35e00f49 | ||
|
|
7f960616e0 | ||
|
|
1cafdb5b46 | ||
|
|
b0fb340b57 | ||
|
|
85f3ba844c | ||
|
|
090eb437ed | ||
|
|
d574604a5d | ||
|
|
6eacddb50f | ||
|
|
4ff23d3306 | ||
|
|
c7687fc1d6 | ||
|
|
c47d34cf70 | ||
|
|
cd51f37fc0 | ||
|
|
da70c837da | ||
|
|
f1ae07e532 | ||
|
|
d9cd494eaf | ||
|
|
5979233a3c | ||
|
|
0b1d6a0d52 | ||
|
|
7b433605f9 | ||
|
|
3b9b1956cd | ||
|
|
7a41e0b1ea | ||
|
|
cc882b0723 | ||
|
|
6d6580f6be | ||
|
|
7684f53328 | ||
|
|
e3e4b7bdf5 | ||
|
|
679f4882a5 | ||
|
|
cb78e62df9 | ||
|
|
376f2aec54 | ||
|
|
010757266e | ||
|
|
d268471285 | ||
|
|
423577e14e | ||
|
|
f1c31ebc67 | ||
|
|
4433ce4312 | ||
|
|
456bbffcc4 | ||
|
|
17a7f352b5 | ||
|
|
637d9c42bf | ||
|
|
1c385c2ca4 | ||
|
|
25f25d546d | ||
|
|
6ac50634e3 | ||
|
|
50e453a3e2 | ||
|
|
4649bf042e | ||
|
|
2bd0ee27f0 | ||
|
|
0d16492eb7 | ||
|
|
2ae19801a9 | ||
|
|
950539b768 | ||
|
|
f270d6c52c | ||
|
|
22d6f00110 | ||
|
|
38e357ef10 | ||
|
|
0b7f3edc26 | ||
|
|
285269ef55 | ||
|
|
e25da4230b | ||
|
|
8be6f40ae1 | ||
|
|
83bd3595a4 | ||
|
|
32ee0a3947 | ||
|
|
7ddc22b326 | ||
|
|
0d5042f0f3 | ||
|
|
0eaddb4dcd | ||
|
|
74a11e2087 | ||
|
|
d4dd448511 | ||
|
|
56ad2a2d74 | ||
|
|
f421e73b40 | ||
|
|
72899318e6 | ||
|
|
84c6ea0cee | ||
|
|
c23b5463c7 | ||
|
|
9d8bc79025 | ||
|
|
0cad274b87 | ||
|
|
ac8931b2e9 | ||
|
|
4f112f898e | ||
|
|
e5ba982be0 | ||
|
|
200754b013 | ||
|
|
42ad3c1dd3 | ||
|
|
172570acae | ||
|
|
c29971cf72 | ||
|
|
ccc9a22db3 | ||
|
|
c00523dba4 | ||
|
|
9d5ec05150 | ||
|
|
2fecd332fc | ||
|
|
0e09032750 | ||
|
|
46b61427e1 | ||
|
|
bcf4ed28a9 | ||
|
|
6cfc9e6256 | ||
|
|
1ab236d9df | ||
|
|
2e1ac0f683 | ||
|
|
8364d1ca6c | ||
|
|
09d8943967 | ||
|
|
6e58a95a01 | ||
|
|
207ad45983 | ||
|
|
83ef61fa56 | ||
|
|
d0e0b106f0 | ||
|
|
98b66a5fc9 | ||
|
|
921bb92eec | ||
|
|
c50198debe | ||
|
|
6371474031 | ||
|
|
8657201257 | ||
|
|
b88492746e | ||
|
|
f6fc28dfd2 | ||
|
|
cdeef65b05 | ||
|
|
1e81a53e75 | ||
|
|
5e63711084 | ||
|
|
a2fbcc9ad4 | ||
|
|
10030ff3ec | ||
|
|
648735a4cf | ||
|
|
a4629b0b36 | ||
|
|
64cbbed152 | ||
|
|
43f375b2f2 | ||
|
|
1eb89d7e3b | ||
|
|
4d46383100 | ||
|
|
aa3fe81c87 | ||
|
|
9ea16e344a | ||
|
|
d8719cf59b | ||
|
|
9dcc07422e | ||
|
|
52c78820aa | ||
|
|
19b92751b9 | ||
|
|
f318f2d5ea | ||
|
|
21ff03978a | ||
|
|
25fd9d6132 | ||
|
|
3637193556 | ||
|
|
8e3274e137 | ||
|
|
c4a158656e | ||
|
|
e026c8d3b7 | ||
|
|
cab41d954e | ||
|
|
e0cbfd74d7 | ||
|
|
426930e028 | ||
|
|
e9fa17e1bf | ||
|
|
b807347e94 | ||
|
|
7113fc7dee | ||
|
|
e0f283cfcb | ||
|
|
7b968b098e | ||
|
|
e927a6ac4a | ||
|
|
9da475e4e8 | ||
|
|
5b282bdd48 | ||
|
|
fc80f2b41a | ||
|
|
68e9ef9885 | ||
|
|
296db2ed33 | ||
|
|
3171d61dfc | ||
|
|
00b9e70ba2 | ||
|
|
57e9f61852 | ||
|
|
cf365ed00b | ||
|
|
d98a5d54aa | ||
|
|
8074d56bdd | ||
|
|
fc3c3de70d | ||
|
|
997d1bd0eb | ||
|
|
baef79415b | ||
|
|
cb601d79e8 | ||
|
|
4cee46f909 | ||
|
|
25349b31d7 | ||
|
|
735267d27c | ||
|
|
b5ced477f4 | ||
|
|
67319a71e5 | ||
|
|
184a6f1198 | ||
|
|
b32bb4e6e3 | ||
|
|
0e62b7d68a | ||
|
|
a761779b12 | ||
|
|
29510fcb83 | ||
|
|
3f335b0d42 | ||
|
|
ffda84cfae | ||
|
|
e6bc840f6f | ||
|
|
0b26387a2b | ||
|
|
f7ef10e547 | ||
|
|
91cadc1130 | ||
|
|
47d1360124 | ||
|
|
f67699456c | ||
|
|
387f724d33 | ||
|
|
bcdfd5d61c | ||
|
|
e660d92fa5 | ||
|
|
9fdf72e42b | ||
|
|
df9051ded2 | ||
|
|
230c5ca735 | ||
|
|
3bd3693fb7 | ||
|
|
45cbebad64 | ||
|
|
6d0f9244b8 | ||
|
|
80a8aea7e3 | ||
|
|
4f0db01f7c | ||
|
|
6cd4e30b58 | ||
|
|
19540479d4 | ||
|
|
90dffb5a06 | ||
|
|
ef521d1e0b | ||
|
|
42c32bf00c | ||
|
|
c8a9969511 | ||
|
|
b0a8734c92 | ||
|
|
8d0723c2c3 |
8
.github/issue_template.md
vendored
8
.github/issue_template.md
vendored
@@ -1,12 +1,12 @@
|
||||
(Click "Preview" above ^ to turn URL into clickable links)
|
||||
|
||||
1. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md)
|
||||
1. FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING or LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
|
||||
|
||||
2. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261)
|
||||
2. PLEASE CAREFULLY READ: [FAQ](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md)
|
||||
|
||||
3. FOR FIRST-TIME USERS ISSUES COMPILING/LINKING/RUNNING/LOADING FONTS, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
|
||||
3. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261)
|
||||
|
||||
4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the link provided in (1) (2).
|
||||
4. PLEASE MAKE SURE that you have: read the FAQ; explored the contents of `ShowDemoWindow()` including the Examples menu; searched among Issues; used your IDE to search for keywords in all sources and text files; and read the links above.
|
||||
|
||||
5. 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.
|
||||
|
||||
|
||||
6
.github/pull_request_template.md
vendored
6
.github/pull_request_template.md
vendored
@@ -1,6 +1,6 @@
|
||||
(Click "Preview" to turn any http URL into a clickable link)
|
||||
|
||||
PLEASE CAREFULLY READ:
|
||||
https://github.com/ocornut/imgui/issues/2261
|
||||
1. PLEASE CAREFULLY READ: [Issue Submitting Guidelines](https://github.com/ocornut/imgui/issues/2261)
|
||||
|
||||
2. Clear this template before submitting your PR.
|
||||
|
||||
(Clear this template before submitting your PR)
|
||||
|
||||
103
.github/workflows/build.yml
vendored
103
.github/workflows/build.yml
vendored
@@ -37,20 +37,30 @@ jobs:
|
||||
- name: Fix Projects
|
||||
shell: powershell
|
||||
run: |
|
||||
# WARNING: This will need updating if toolset/sdk change in project files!
|
||||
# CI workers do not supporter older Visual Studio versions. Fix projects to target newer available version.
|
||||
gci -recurse -filter "*.vcxproj" | ForEach-Object {
|
||||
# Fix SDK and toolset for most samples.
|
||||
(Get-Content $_.FullName) -Replace "<PlatformToolset>v110</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
|
||||
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
|
||||
# Fix SDK and toolset for samples that require newer SDK/toolset. At the moment it is only dx12.
|
||||
(Get-Content $_.FullName) -Replace "<PlatformToolset>v140</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
|
||||
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>" | Set-Content -Path $_.FullName
|
||||
(Get-Content $_.FullName) -Replace "<PlatformToolset>v\d{3}</PlatformToolset>","<PlatformToolset>v142</PlatformToolset>" | Set-Content -Path $_.FullName
|
||||
(Get-Content $_.FullName) -Replace "<WindowsTargetPlatformVersion>[\d\.]+</WindowsTargetPlatformVersion>","<WindowsTargetPlatformVersion>10.0.18362.0</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.
|
||||
- name: Build example_null (extra warnings, mingw 64-bit)
|
||||
run: mingw32-make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
||||
|
||||
- name: Build example_null (mingw 64-bit, as DLL)
|
||||
shell: bash
|
||||
run: |
|
||||
echo '#ifdef _EXPORT' > 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 '#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 -o example_null.exe examples/example_null/main.cpp -L. -limgui
|
||||
rm -f example_null.exe libimgui.* example_single_file.*
|
||||
|
||||
- name: Build example_null (extra warnings, msvc 64-bit)
|
||||
shell: cmd
|
||||
run: |
|
||||
@@ -226,6 +236,18 @@ jobs:
|
||||
make -C examples/example_null clean
|
||||
CXXFLAGS="$CXXFLAGS -m64 -Werror" CXX=clang++ make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
||||
|
||||
- name: Build example_null (extra warnings, empty IM_ASSERT)
|
||||
run: |
|
||||
cat > example_single_file.cpp <<'EOF'
|
||||
|
||||
#define IM_ASSERT(x)
|
||||
#define IMGUI_IMPLEMENTATION
|
||||
#include "misc/single_file/imgui_single_file.h"
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (freetype)
|
||||
run: |
|
||||
make -C examples/example_null clean
|
||||
@@ -240,7 +262,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with ImWchar32)
|
||||
run: |
|
||||
@@ -252,7 +274,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
|
||||
run: |
|
||||
@@ -265,7 +287,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
|
||||
run: |
|
||||
@@ -277,7 +299,19 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
|
||||
run: |
|
||||
cat > example_single_file.cpp <<'EOF'
|
||||
|
||||
#define IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
#define IMGUI_IMPLEMENTATION
|
||||
#include "misc/single_file/imgui_single_file.h"
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
|
||||
run: |
|
||||
@@ -290,7 +324,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
|
||||
run: |
|
||||
@@ -302,7 +336,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
|
||||
run: |
|
||||
@@ -314,7 +348,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
|
||||
run: |
|
||||
@@ -334,7 +368,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (without c++ runtime, Clang)
|
||||
run: |
|
||||
@@ -346,7 +380,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
|
||||
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_glfw_opengl2
|
||||
run: make -C examples/example_glfw_opengl2
|
||||
@@ -363,7 +397,7 @@ jobs:
|
||||
run: make -C examples/example_sdl_opengl3
|
||||
|
||||
- name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||
run: g++ -c -I. -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
|
||||
run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
|
||||
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
@@ -386,7 +420,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_null (without c++ runtime)
|
||||
run: |
|
||||
@@ -397,7 +431,7 @@ jobs:
|
||||
#include "examples/example_null/main.cpp"
|
||||
|
||||
EOF
|
||||
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
|
||||
clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
|
||||
|
||||
- name: Build example_glfw_opengl2
|
||||
run: make -C examples/example_glfw_opengl2
|
||||
@@ -471,34 +505,3 @@ jobs:
|
||||
run: |
|
||||
cd examples/example_android_opengl3/android
|
||||
gradle assembleDebug
|
||||
|
||||
Discord-CI:
|
||||
runs-on: ubuntu-18.04
|
||||
if: always()
|
||||
needs: [Windows, Linux, MacOS, iOS, Emscripten, Android]
|
||||
steps:
|
||||
- uses: dearimgui/github_discord_notifier@latest
|
||||
with:
|
||||
discord-webhook: ${{ secrets.DISCORD_CI_WEBHOOK }}
|
||||
github-token: ${{ github.token }}
|
||||
action-task: discord-jobs
|
||||
discord-filter: "'{{ github.branch }}'.match(/master|docking/g) != null && '{{ run.conclusion }}' != '{{ last_run.conclusion }}'"
|
||||
discord-username: GitHub Actions
|
||||
discord-job-new-failure-message: ''
|
||||
discord-job-fixed-failure-message: ''
|
||||
discord-job-new-failure-embed: |
|
||||
{
|
||||
"title": "`{{ job.name }}` job is failing on `{{ github.branch }}`!",
|
||||
"description": "Commit [{{ github.context.payload.head_commit.title }}]({{ github.context.payload.head_commit.url }}) pushed to [{{ github.branch }}]({{ github.branch_url }}) broke [{{ job.name }}]({{ job.url }}) build job.\nFailing steps: {{ failing_steps }}",
|
||||
"url": "{{ job.url }}",
|
||||
"color": "0xFF0000",
|
||||
"timestamp": "{{ run.updated_at }}"
|
||||
}
|
||||
discord-job-fixed-failure-embed: |
|
||||
{
|
||||
"title": "`{{ github.branch }}` branch is no longer failing!",
|
||||
"description": "Build failures were fixed on [{{ github.branch }}]({{ github.branch_url }}) branch.",
|
||||
"color": "0x00FF00",
|
||||
"url": "{{ github.context.payload.head_commit.url }}",
|
||||
"timestamp": "{{ run.completed_at }}"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2021 Omar Cornut
|
||||
Copyright (c) 2014-2022 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [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] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
@@ -16,6 +17,11 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
|
||||
// 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: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -155,7 +161,6 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
|
||||
// Render command lists
|
||||
int idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
@@ -171,12 +176,17 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle, Draw
|
||||
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
|
||||
al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
|
||||
al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x - clip_min.x, clip_max.y - clip_min.y);
|
||||
al_draw_prim(&vertices[0], bd->VertexDecl, texture, pcmd->IdxOffset, pcmd->IdxOffset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
}
|
||||
idx_offset += pcmd->ElemCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +279,119 @@ static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text)
|
||||
}
|
||||
#endif
|
||||
|
||||
static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
case ALLEGRO_KEY_TAB: return ImGuiKey_Tab;
|
||||
case ALLEGRO_KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||
case ALLEGRO_KEY_RIGHT: return ImGuiKey_RightArrow;
|
||||
case ALLEGRO_KEY_UP: return ImGuiKey_UpArrow;
|
||||
case ALLEGRO_KEY_DOWN: return ImGuiKey_DownArrow;
|
||||
case ALLEGRO_KEY_PGUP: return ImGuiKey_PageUp;
|
||||
case ALLEGRO_KEY_PGDN: return ImGuiKey_PageDown;
|
||||
case ALLEGRO_KEY_HOME: return ImGuiKey_Home;
|
||||
case ALLEGRO_KEY_END: return ImGuiKey_End;
|
||||
case ALLEGRO_KEY_INSERT: return ImGuiKey_Insert;
|
||||
case ALLEGRO_KEY_DELETE: return ImGuiKey_Delete;
|
||||
case ALLEGRO_KEY_BACKSPACE: return ImGuiKey_Backspace;
|
||||
case ALLEGRO_KEY_SPACE: return ImGuiKey_Space;
|
||||
case ALLEGRO_KEY_ENTER: return ImGuiKey_Enter;
|
||||
case ALLEGRO_KEY_ESCAPE: return ImGuiKey_Escape;
|
||||
case ALLEGRO_KEY_QUOTE: return ImGuiKey_Apostrophe;
|
||||
case ALLEGRO_KEY_COMMA: return ImGuiKey_Comma;
|
||||
case ALLEGRO_KEY_MINUS: return ImGuiKey_Minus;
|
||||
case ALLEGRO_KEY_FULLSTOP: return ImGuiKey_Period;
|
||||
case ALLEGRO_KEY_SLASH: return ImGuiKey_Slash;
|
||||
case ALLEGRO_KEY_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case ALLEGRO_KEY_EQUALS: return ImGuiKey_Equal;
|
||||
case ALLEGRO_KEY_OPENBRACE: return ImGuiKey_LeftBracket;
|
||||
case ALLEGRO_KEY_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case ALLEGRO_KEY_CLOSEBRACE: return ImGuiKey_RightBracket;
|
||||
case ALLEGRO_KEY_TILDE: return ImGuiKey_GraveAccent;
|
||||
case ALLEGRO_KEY_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||
case ALLEGRO_KEY_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||
case ALLEGRO_KEY_NUMLOCK: return ImGuiKey_NumLock;
|
||||
case ALLEGRO_KEY_PRINTSCREEN: return ImGuiKey_PrintScreen;
|
||||
case ALLEGRO_KEY_PAUSE: return ImGuiKey_Pause;
|
||||
case ALLEGRO_KEY_PAD_0: return ImGuiKey_Keypad0;
|
||||
case ALLEGRO_KEY_PAD_1: return ImGuiKey_Keypad1;
|
||||
case ALLEGRO_KEY_PAD_2: return ImGuiKey_Keypad2;
|
||||
case ALLEGRO_KEY_PAD_3: return ImGuiKey_Keypad3;
|
||||
case ALLEGRO_KEY_PAD_4: return ImGuiKey_Keypad4;
|
||||
case ALLEGRO_KEY_PAD_5: return ImGuiKey_Keypad5;
|
||||
case ALLEGRO_KEY_PAD_6: return ImGuiKey_Keypad6;
|
||||
case ALLEGRO_KEY_PAD_7: return ImGuiKey_Keypad7;
|
||||
case ALLEGRO_KEY_PAD_8: return ImGuiKey_Keypad8;
|
||||
case ALLEGRO_KEY_PAD_9: return ImGuiKey_Keypad9;
|
||||
case ALLEGRO_KEY_PAD_DELETE: return ImGuiKey_KeypadDecimal;
|
||||
case ALLEGRO_KEY_PAD_SLASH: return ImGuiKey_KeypadDivide;
|
||||
case ALLEGRO_KEY_PAD_ASTERISK: return ImGuiKey_KeypadMultiply;
|
||||
case ALLEGRO_KEY_PAD_MINUS: return ImGuiKey_KeypadSubtract;
|
||||
case ALLEGRO_KEY_PAD_PLUS: return ImGuiKey_KeypadAdd;
|
||||
case ALLEGRO_KEY_PAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case ALLEGRO_KEY_PAD_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
case ALLEGRO_KEY_LCTRL: return ImGuiKey_LeftCtrl;
|
||||
case ALLEGRO_KEY_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case ALLEGRO_KEY_ALT: return ImGuiKey_LeftAlt;
|
||||
case ALLEGRO_KEY_LWIN: return ImGuiKey_LeftSuper;
|
||||
case ALLEGRO_KEY_RCTRL: return ImGuiKey_RightCtrl;
|
||||
case ALLEGRO_KEY_RSHIFT: return ImGuiKey_RightShift;
|
||||
case ALLEGRO_KEY_ALTGR: return ImGuiKey_RightAlt;
|
||||
case ALLEGRO_KEY_RWIN: return ImGuiKey_RightSuper;
|
||||
case ALLEGRO_KEY_MENU: return ImGuiKey_Menu;
|
||||
case ALLEGRO_KEY_0: return ImGuiKey_0;
|
||||
case ALLEGRO_KEY_1: return ImGuiKey_1;
|
||||
case ALLEGRO_KEY_2: return ImGuiKey_2;
|
||||
case ALLEGRO_KEY_3: return ImGuiKey_3;
|
||||
case ALLEGRO_KEY_4: return ImGuiKey_4;
|
||||
case ALLEGRO_KEY_5: return ImGuiKey_5;
|
||||
case ALLEGRO_KEY_6: return ImGuiKey_6;
|
||||
case ALLEGRO_KEY_7: return ImGuiKey_7;
|
||||
case ALLEGRO_KEY_8: return ImGuiKey_8;
|
||||
case ALLEGRO_KEY_9: return ImGuiKey_9;
|
||||
case ALLEGRO_KEY_A: return ImGuiKey_A;
|
||||
case ALLEGRO_KEY_B: return ImGuiKey_B;
|
||||
case ALLEGRO_KEY_C: return ImGuiKey_C;
|
||||
case ALLEGRO_KEY_D: return ImGuiKey_D;
|
||||
case ALLEGRO_KEY_E: return ImGuiKey_E;
|
||||
case ALLEGRO_KEY_F: return ImGuiKey_F;
|
||||
case ALLEGRO_KEY_G: return ImGuiKey_G;
|
||||
case ALLEGRO_KEY_H: return ImGuiKey_H;
|
||||
case ALLEGRO_KEY_I: return ImGuiKey_I;
|
||||
case ALLEGRO_KEY_J: return ImGuiKey_J;
|
||||
case ALLEGRO_KEY_K: return ImGuiKey_K;
|
||||
case ALLEGRO_KEY_L: return ImGuiKey_L;
|
||||
case ALLEGRO_KEY_M: return ImGuiKey_M;
|
||||
case ALLEGRO_KEY_N: return ImGuiKey_N;
|
||||
case ALLEGRO_KEY_O: return ImGuiKey_O;
|
||||
case ALLEGRO_KEY_P: return ImGuiKey_P;
|
||||
case ALLEGRO_KEY_Q: return ImGuiKey_Q;
|
||||
case ALLEGRO_KEY_R: return ImGuiKey_R;
|
||||
case ALLEGRO_KEY_S: return ImGuiKey_S;
|
||||
case ALLEGRO_KEY_T: return ImGuiKey_T;
|
||||
case ALLEGRO_KEY_U: return ImGuiKey_U;
|
||||
case ALLEGRO_KEY_V: return ImGuiKey_V;
|
||||
case ALLEGRO_KEY_W: return ImGuiKey_W;
|
||||
case ALLEGRO_KEY_X: return ImGuiKey_X;
|
||||
case ALLEGRO_KEY_Y: return ImGuiKey_Y;
|
||||
case ALLEGRO_KEY_Z: return ImGuiKey_Z;
|
||||
case ALLEGRO_KEY_F1: return ImGuiKey_F1;
|
||||
case ALLEGRO_KEY_F2: return ImGuiKey_F2;
|
||||
case ALLEGRO_KEY_F3: return ImGuiKey_F3;
|
||||
case ALLEGRO_KEY_F4: return ImGuiKey_F4;
|
||||
case ALLEGRO_KEY_F5: return ImGuiKey_F5;
|
||||
case ALLEGRO_KEY_F6: return ImGuiKey_F6;
|
||||
case ALLEGRO_KEY_F7: return ImGuiKey_F7;
|
||||
case ALLEGRO_KEY_F8: return ImGuiKey_F8;
|
||||
case ALLEGRO_KEY_F9: return ImGuiKey_F9;
|
||||
case ALLEGRO_KEY_F10: return ImGuiKey_F10;
|
||||
case ALLEGRO_KEY_F11: return ImGuiKey_F11;
|
||||
case ALLEGRO_KEY_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -294,30 +417,6 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
};
|
||||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||
|
||||
io.KeyMap[ImGuiKey_Tab] = ALLEGRO_KEY_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = ALLEGRO_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = ALLEGRO_KEY_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = ALLEGRO_KEY_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = ALLEGRO_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = ALLEGRO_KEY_PGUP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = ALLEGRO_KEY_PGDN;
|
||||
io.KeyMap[ImGuiKey_Home] = ALLEGRO_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = ALLEGRO_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = ALLEGRO_KEY_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = ALLEGRO_KEY_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = ALLEGRO_KEY_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Space] = ALLEGRO_KEY_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = ALLEGRO_KEY_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = ALLEGRO_KEY_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = ALLEGRO_KEY_PAD_ENTER;
|
||||
io.KeyMap[ImGuiKey_A] = ALLEGRO_KEY_A;
|
||||
io.KeyMap[ImGuiKey_C] = ALLEGRO_KEY_C;
|
||||
io.KeyMap[ImGuiKey_V] = ALLEGRO_KEY_V;
|
||||
io.KeyMap[ImGuiKey_X] = ALLEGRO_KEY_X;
|
||||
io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z;
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
|
||||
@@ -329,8 +428,9 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
|
||||
void ImGui_ImplAllegro5_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
||||
if (bd->VertexDecl)
|
||||
@@ -343,6 +443,18 @@ void ImGui_ImplAllegro5_Shutdown()
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
// ev->keyboard.modifiers seems always zero so using that...
|
||||
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ALLEGRO_KEYBOARD_STATE keys;
|
||||
al_get_keyboard_state(&keys);
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL));
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT));
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR));
|
||||
io.AddKeyEvent(ImGuiKey_ModSuper, al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN));
|
||||
}
|
||||
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
@@ -357,29 +469,28 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
|
||||
case ALLEGRO_EVENT_MOUSE_AXES:
|
||||
if (ev->mouse.display == bd->Display)
|
||||
{
|
||||
io.MouseWheel += ev->mouse.dz;
|
||||
io.MouseWheelH -= ev->mouse.dw;
|
||||
io.MousePos = ImVec2(ev->mouse.x, ev->mouse.y);
|
||||
io.AddMousePosEvent(ev->mouse.x, ev->mouse.y);
|
||||
io.AddMouseWheelEvent(-ev->mouse.dw, ev->mouse.dz);
|
||||
}
|
||||
return true;
|
||||
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
|
||||
if (ev->mouse.display == bd->Display && ev->mouse.button <= 5)
|
||||
io.MouseDown[ev->mouse.button - 1] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
|
||||
if (ev->mouse.display == bd->Display && ev->mouse.button > 0 && ev->mouse.button <= 5)
|
||||
io.AddMouseButtonEvent(ev->mouse.button - 1, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
|
||||
return true;
|
||||
case ALLEGRO_EVENT_TOUCH_MOVE:
|
||||
if (ev->touch.display == bd->Display)
|
||||
io.MousePos = ImVec2(ev->touch.x, ev->touch.y);
|
||||
io.AddMousePosEvent(ev->touch.x, ev->touch.y);
|
||||
return true;
|
||||
case ALLEGRO_EVENT_TOUCH_BEGIN:
|
||||
case ALLEGRO_EVENT_TOUCH_END:
|
||||
case ALLEGRO_EVENT_TOUCH_CANCEL:
|
||||
if (ev->touch.display == bd->Display && ev->touch.primary)
|
||||
io.MouseDown[0] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
|
||||
io.AddMouseButtonEvent(0, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
|
||||
return true;
|
||||
case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
|
||||
if (ev->mouse.display == bd->Display)
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
return true;
|
||||
case ALLEGRO_EVENT_KEY_CHAR:
|
||||
if (ev->keyboard.display == bd->Display)
|
||||
@@ -389,7 +500,12 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
|
||||
case ALLEGRO_EVENT_KEY_DOWN:
|
||||
case ALLEGRO_EVENT_KEY_UP:
|
||||
if (ev->keyboard.display == bd->Display)
|
||||
io.KeysDown[ev->keyboard.keycode] = (ev->type == ALLEGRO_EVENT_KEY_DOWN);
|
||||
{
|
||||
ImGui_ImplAllegro5_UpdateKeyModifiers();
|
||||
ImGuiKey key = ImGui_ImplAllegro5_KeyCodeToImGuiKey(ev->keyboard.keycode);
|
||||
io.AddKeyEvent(key, (ev->type == ALLEGRO_EVENT_KEY_DOWN));
|
||||
io.SetKeyEventNativeData(key, ev->keyboard.keycode, -1); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
return true;
|
||||
case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT:
|
||||
if (ev->display.source == bd->Display)
|
||||
@@ -459,13 +575,6 @@ void ImGui_ImplAllegro5_NewFrame()
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
ALLEGRO_KEYBOARD_STATE keys;
|
||||
al_get_keyboard_state(&keys);
|
||||
io.KeyCtrl = al_key_down(&keys, ALLEGRO_KEY_LCTRL) || al_key_down(&keys, ALLEGRO_KEY_RCTRL);
|
||||
io.KeyShift = al_key_down(&keys, ALLEGRO_KEY_LSHIFT) || al_key_down(&keys, ALLEGRO_KEY_RSHIFT);
|
||||
io.KeyAlt = al_key_down(&keys, ALLEGRO_KEY_ALT) || al_key_down(&keys, ALLEGRO_KEY_ALTGR);
|
||||
io.KeySuper = al_key_down(&keys, ALLEGRO_KEY_LWIN) || al_key_down(&keys, ALLEGRO_KEY_RWIN);
|
||||
|
||||
// Setup mouse cursor shape
|
||||
ImGui_ImplAllegro5_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [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] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
@@ -2,29 +2,31 @@
|
||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard arrays indexed using AKEYCODE_* codes, e.g. ImGui::IsKeyPressed(AKEYCODE_SPACE).
|
||||
// [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]
|
||||
// Missing features:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-03-04: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_android.h"
|
||||
#include <time.h>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <android/native_window.h>
|
||||
#include <android/input.h>
|
||||
#include <android/keycodes.h>
|
||||
@@ -34,7 +36,119 @@
|
||||
static double g_Time = 0.0;
|
||||
static ANativeWindow* g_Window;
|
||||
static char g_LogTag[] = "ImGuiExample";
|
||||
static std::map<int32_t, std::queue<int32_t>> g_KeyEventQueues; // FIXME: Remove dependency on map and queue once we use upcoming input queue.
|
||||
|
||||
static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
case AKEYCODE_TAB: return ImGuiKey_Tab;
|
||||
case AKEYCODE_DPAD_LEFT: return ImGuiKey_LeftArrow;
|
||||
case AKEYCODE_DPAD_RIGHT: return ImGuiKey_RightArrow;
|
||||
case AKEYCODE_DPAD_UP: return ImGuiKey_UpArrow;
|
||||
case AKEYCODE_DPAD_DOWN: return ImGuiKey_DownArrow;
|
||||
case AKEYCODE_PAGE_UP: return ImGuiKey_PageUp;
|
||||
case AKEYCODE_PAGE_DOWN: return ImGuiKey_PageDown;
|
||||
case AKEYCODE_MOVE_HOME: return ImGuiKey_Home;
|
||||
case AKEYCODE_MOVE_END: return ImGuiKey_End;
|
||||
case AKEYCODE_INSERT: return ImGuiKey_Insert;
|
||||
case AKEYCODE_FORWARD_DEL: return ImGuiKey_Delete;
|
||||
case AKEYCODE_DEL: return ImGuiKey_Backspace;
|
||||
case AKEYCODE_SPACE: return ImGuiKey_Space;
|
||||
case AKEYCODE_ENTER: return ImGuiKey_Enter;
|
||||
case AKEYCODE_ESCAPE: return ImGuiKey_Escape;
|
||||
case AKEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case AKEYCODE_COMMA: return ImGuiKey_Comma;
|
||||
case AKEYCODE_MINUS: return ImGuiKey_Minus;
|
||||
case AKEYCODE_PERIOD: return ImGuiKey_Period;
|
||||
case AKEYCODE_SLASH: return ImGuiKey_Slash;
|
||||
case AKEYCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case AKEYCODE_EQUALS: return ImGuiKey_Equal;
|
||||
case AKEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||
case AKEYCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case AKEYCODE_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||
case AKEYCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||
case AKEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||
case AKEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;
|
||||
case AKEYCODE_NUM_LOCK: return ImGuiKey_NumLock;
|
||||
case AKEYCODE_SYSRQ: return ImGuiKey_PrintScreen;
|
||||
case AKEYCODE_BREAK: return ImGuiKey_Pause;
|
||||
case AKEYCODE_NUMPAD_0: return ImGuiKey_Keypad0;
|
||||
case AKEYCODE_NUMPAD_1: return ImGuiKey_Keypad1;
|
||||
case AKEYCODE_NUMPAD_2: return ImGuiKey_Keypad2;
|
||||
case AKEYCODE_NUMPAD_3: return ImGuiKey_Keypad3;
|
||||
case AKEYCODE_NUMPAD_4: return ImGuiKey_Keypad4;
|
||||
case AKEYCODE_NUMPAD_5: return ImGuiKey_Keypad5;
|
||||
case AKEYCODE_NUMPAD_6: return ImGuiKey_Keypad6;
|
||||
case AKEYCODE_NUMPAD_7: return ImGuiKey_Keypad7;
|
||||
case AKEYCODE_NUMPAD_8: return ImGuiKey_Keypad8;
|
||||
case AKEYCODE_NUMPAD_9: return ImGuiKey_Keypad9;
|
||||
case AKEYCODE_NUMPAD_DOT: return ImGuiKey_KeypadDecimal;
|
||||
case AKEYCODE_NUMPAD_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case AKEYCODE_NUMPAD_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case AKEYCODE_NUMPAD_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd;
|
||||
case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftCtrl;
|
||||
case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift;
|
||||
case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt;
|
||||
case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper;
|
||||
case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightCtrl;
|
||||
case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift;
|
||||
case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt;
|
||||
case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper;
|
||||
case AKEYCODE_MENU: return ImGuiKey_Menu;
|
||||
case AKEYCODE_0: return ImGuiKey_0;
|
||||
case AKEYCODE_1: return ImGuiKey_1;
|
||||
case AKEYCODE_2: return ImGuiKey_2;
|
||||
case AKEYCODE_3: return ImGuiKey_3;
|
||||
case AKEYCODE_4: return ImGuiKey_4;
|
||||
case AKEYCODE_5: return ImGuiKey_5;
|
||||
case AKEYCODE_6: return ImGuiKey_6;
|
||||
case AKEYCODE_7: return ImGuiKey_7;
|
||||
case AKEYCODE_8: return ImGuiKey_8;
|
||||
case AKEYCODE_9: return ImGuiKey_9;
|
||||
case AKEYCODE_A: return ImGuiKey_A;
|
||||
case AKEYCODE_B: return ImGuiKey_B;
|
||||
case AKEYCODE_C: return ImGuiKey_C;
|
||||
case AKEYCODE_D: return ImGuiKey_D;
|
||||
case AKEYCODE_E: return ImGuiKey_E;
|
||||
case AKEYCODE_F: return ImGuiKey_F;
|
||||
case AKEYCODE_G: return ImGuiKey_G;
|
||||
case AKEYCODE_H: return ImGuiKey_H;
|
||||
case AKEYCODE_I: return ImGuiKey_I;
|
||||
case AKEYCODE_J: return ImGuiKey_J;
|
||||
case AKEYCODE_K: return ImGuiKey_K;
|
||||
case AKEYCODE_L: return ImGuiKey_L;
|
||||
case AKEYCODE_M: return ImGuiKey_M;
|
||||
case AKEYCODE_N: return ImGuiKey_N;
|
||||
case AKEYCODE_O: return ImGuiKey_O;
|
||||
case AKEYCODE_P: return ImGuiKey_P;
|
||||
case AKEYCODE_Q: return ImGuiKey_Q;
|
||||
case AKEYCODE_R: return ImGuiKey_R;
|
||||
case AKEYCODE_S: return ImGuiKey_S;
|
||||
case AKEYCODE_T: return ImGuiKey_T;
|
||||
case AKEYCODE_U: return ImGuiKey_U;
|
||||
case AKEYCODE_V: return ImGuiKey_V;
|
||||
case AKEYCODE_W: return ImGuiKey_W;
|
||||
case AKEYCODE_X: return ImGuiKey_X;
|
||||
case AKEYCODE_Y: return ImGuiKey_Y;
|
||||
case AKEYCODE_Z: return ImGuiKey_Z;
|
||||
case AKEYCODE_F1: return ImGuiKey_F1;
|
||||
case AKEYCODE_F2: return ImGuiKey_F2;
|
||||
case AKEYCODE_F3: return ImGuiKey_F3;
|
||||
case AKEYCODE_F4: return ImGuiKey_F4;
|
||||
case AKEYCODE_F5: return ImGuiKey_F5;
|
||||
case AKEYCODE_F6: return ImGuiKey_F6;
|
||||
case AKEYCODE_F7: return ImGuiKey_F7;
|
||||
case AKEYCODE_F8: return ImGuiKey_F8;
|
||||
case AKEYCODE_F9: return ImGuiKey_F9;
|
||||
case AKEYCODE_F10: return ImGuiKey_F10;
|
||||
case AKEYCODE_F11: return ImGuiKey_F11;
|
||||
case AKEYCODE_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
{
|
||||
@@ -45,12 +159,14 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
case AINPUT_EVENT_TYPE_KEY:
|
||||
{
|
||||
int32_t event_key_code = AKeyEvent_getKeyCode(input_event);
|
||||
int32_t event_scan_code = AKeyEvent_getScanCode(input_event);
|
||||
int32_t event_action = AKeyEvent_getAction(input_event);
|
||||
int32_t event_meta_state = AKeyEvent_getMetaState(input_event);
|
||||
|
||||
io.KeyCtrl = ((event_meta_state & AMETA_CTRL_ON) != 0);
|
||||
io.KeyShift = ((event_meta_state & AMETA_SHIFT_ON) != 0);
|
||||
io.KeyAlt = ((event_meta_state & AMETA_ALT_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, (event_meta_state & AMETA_CTRL_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, (event_meta_state & AMETA_SHIFT_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, (event_meta_state & AMETA_ALT_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModSuper, (event_meta_state & AMETA_META_ON) != 0);
|
||||
|
||||
switch (event_action)
|
||||
{
|
||||
@@ -59,8 +175,16 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
// ImGui_ImplAndroid_NewFrame()...or consider using IO queue, if suitable: https://github.com/ocornut/imgui/issues/2787
|
||||
case AKEY_EVENT_ACTION_DOWN:
|
||||
case AKEY_EVENT_ACTION_UP:
|
||||
g_KeyEventQueues[event_key_code].push(event_action);
|
||||
{
|
||||
ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code);
|
||||
if (key != ImGuiKey_None && (event_action == AKEY_EVENT_ACTION_DOWN || event_action == AKEY_EVENT_ACTION_UP))
|
||||
{
|
||||
io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN);
|
||||
io.SetKeyEventNativeData(key, event_key_code, event_scan_code);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -81,26 +205,25 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event)
|
||||
if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER)
|
||||
|| (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN))
|
||||
{
|
||||
io.MouseDown[0] = (event_action == AMOTION_EVENT_ACTION_DOWN);
|
||||
io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
|
||||
case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
|
||||
{
|
||||
int32_t button_state = AMotionEvent_getButtonState(input_event);
|
||||
io.MouseDown[0] = ((button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
|
||||
io.MouseDown[1] = ((button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
|
||||
io.MouseDown[2] = ((button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
|
||||
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
|
||||
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
|
||||
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
|
||||
}
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
|
||||
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
|
||||
io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_SCROLL:
|
||||
io.MouseWheel = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index);
|
||||
io.MouseWheelH = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index);
|
||||
io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -123,30 +246,6 @@ bool ImGui_ImplAndroid_Init(ANativeWindow* window)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = "imgui_impl_android";
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||
io.KeyMap[ImGuiKey_Tab] = AKEYCODE_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = AKEYCODE_DPAD_LEFT; // also covers physical keyboard arrow key
|
||||
io.KeyMap[ImGuiKey_RightArrow] = AKEYCODE_DPAD_RIGHT; // also covers physical keyboard arrow key
|
||||
io.KeyMap[ImGuiKey_UpArrow] = AKEYCODE_DPAD_UP; // also covers physical keyboard arrow key
|
||||
io.KeyMap[ImGuiKey_DownArrow] = AKEYCODE_DPAD_DOWN; // also covers physical keyboard arrow key
|
||||
io.KeyMap[ImGuiKey_PageUp] = AKEYCODE_PAGE_UP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = AKEYCODE_PAGE_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = AKEYCODE_MOVE_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = AKEYCODE_MOVE_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = AKEYCODE_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = AKEYCODE_FORWARD_DEL;
|
||||
io.KeyMap[ImGuiKey_Backspace] = AKEYCODE_DEL;
|
||||
io.KeyMap[ImGuiKey_Space] = AKEYCODE_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = AKEYCODE_ENTER;
|
||||
io.KeyMap[ImGuiKey_Escape] = AKEYCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = AKEYCODE_NUMPAD_ENTER;
|
||||
io.KeyMap[ImGuiKey_A] = AKEYCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = AKEYCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = AKEYCODE_V;
|
||||
io.KeyMap[ImGuiKey_X] = AKEYCODE_X;
|
||||
io.KeyMap[ImGuiKey_Y] = AKEYCODE_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = AKEYCODE_Z;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -158,16 +257,6 @@ void ImGui_ImplAndroid_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Process queued key events
|
||||
// FIXME: This is a workaround for multiple key event actions occurring at once (see above) and can be removed once we use upcoming input queue.
|
||||
for (auto& key_queue : g_KeyEventQueues)
|
||||
{
|
||||
if (key_queue.second.empty())
|
||||
continue;
|
||||
io.KeysDown[key_queue.first] = (key_queue.second.front() == AKEY_EVENT_ACTION_DOWN);
|
||||
key_queue.second.pop();
|
||||
}
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int32_t window_width = ANativeWindow_getWidth(g_Window);
|
||||
int32_t window_height = ANativeWindow_getHeight(g_Window);
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard arrays indexed using AKEYCODE_* codes, e.g. ImGui::IsKeyPressed(AKEYCODE_SPACE).
|
||||
// [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]
|
||||
// Missing features:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture backend. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -12,6 +13,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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-02-18: DirectX10: Change blending equation to preserve alpha in output buffer.
|
||||
@@ -74,6 +76,10 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX10_InitPlatformInterface();
|
||||
static void ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
||||
{
|
||||
@@ -253,8 +259,14 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D10_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.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);
|
||||
|
||||
// Bind texture, Draw
|
||||
@@ -529,6 +541,7 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx10";
|
||||
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)
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
@@ -545,14 +558,18 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
bd->pd3dDevice->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX10_InitPlatformInterface();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
@@ -569,3 +586,127 @@ void ImGui_ImplDX10_NewFrame()
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX10_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..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX10_ViewportData
|
||||
{
|
||||
IDXGISwapChain* SwapChain;
|
||||
ID3D10RenderTargetView* RTView;
|
||||
|
||||
ImGui_ImplDX10_ViewportData() { SwapChain = NULL; RTView = NULL; }
|
||||
~ImGui_ImplDX10_ViewportData() { IM_ASSERT(SwapChain == NULL && RTView == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
// Create swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.BufferCount = 1;
|
||||
sd.OutputWindow = hwnd;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
sd.Flags = 0;
|
||||
|
||||
IM_ASSERT(vd->SwapChain == NULL && vd->RTView == NULL);
|
||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D10Texture2D* pBackBuffer;
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL here since we didn't create the data for it.
|
||||
if (ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = NULL;
|
||||
if (vd->RTView)
|
||||
vd->RTView->Release();
|
||||
vd->RTView = NULL;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView)
|
||||
{
|
||||
vd->RTView->Release();
|
||||
vd->RTView = NULL;
|
||||
}
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D10Texture2D* pBackBuffer = NULL;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX10_SetWindowSize() failed creating buffers.\n"); return; }
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDevice->OMSetRenderTargets(1, &vd->RTView, NULL);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
bd->pd3dDevice->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
||||
ImGui_ImplDX10_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX10_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX10_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderViewport;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture backend. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -12,6 +13,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
@@ -75,6 +77,10 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX11_InitPlatformInterface();
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
{
|
||||
@@ -263,8 +269,14 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.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);
|
||||
|
||||
// Bind texture, Draw
|
||||
@@ -541,6 +553,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx11";
|
||||
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)
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
@@ -560,14 +573,19 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->pd3dDeviceContext->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX11_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
@@ -585,3 +603,126 @@ void ImGui_ImplDX11_NewFrame()
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX11_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..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX11_ViewportData
|
||||
{
|
||||
IDXGISwapChain* SwapChain;
|
||||
ID3D11RenderTargetView* RTView;
|
||||
|
||||
ImGui_ImplDX11_ViewportData() { SwapChain = NULL; RTView = NULL; }
|
||||
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == NULL && RTView == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backend will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
// Create swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.BufferCount = 1;
|
||||
sd.OutputWindow = hwnd;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
sd.Flags = 0;
|
||||
|
||||
IM_ASSERT(vd->SwapChain == NULL && vd->RTView == NULL);
|
||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
|
||||
if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = NULL;
|
||||
if (vd->RTView)
|
||||
vd->RTView->Release();
|
||||
vd->RTView = NULL;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView)
|
||||
{
|
||||
vd->RTView->Release();
|
||||
vd->RTView = NULL;
|
||||
}
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer = NULL;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
if (pBackBuffer == NULL) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; }
|
||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &vd->RTView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, NULL);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
||||
ImGui_ImplDX11_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. 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.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
@@ -20,6 +22,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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-02-18: DirectX12: Change blending equation to preserve alpha in output buffer.
|
||||
@@ -49,34 +52,19 @@
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
{
|
||||
ID3D12Resource* IndexBuffer;
|
||||
ID3D12Resource* VertexBuffer;
|
||||
int IndexBufferSize;
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
|
||||
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||
UINT numFramesInFlight;
|
||||
UINT frameIndex;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset(this, 0, sizeof(*this)); frameIndex = UINT_MAX; }
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
{
|
||||
float mvp[4][4];
|
||||
ImGui_ImplDX12_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
@@ -86,6 +74,97 @@ static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Buffers used during the rendering of a frame
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
{
|
||||
ID3D12Resource* IndexBuffer;
|
||||
ID3D12Resource* VertexBuffer;
|
||||
int IndexBufferSize;
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
// Buffers used for secondary viewports created by the multi-viewports systems
|
||||
struct ImGui_ImplDX12_FrameContext
|
||||
{
|
||||
ID3D12CommandAllocator* CommandAllocator;
|
||||
ID3D12Resource* RenderTarget;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetCpuDescriptors;
|
||||
};
|
||||
|
||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
// Main viewport created by application will only use the Resources field.
|
||||
// Secondary viewports created by this backend will use all the fields (including Window fields),
|
||||
struct ImGui_ImplDX12_ViewportData
|
||||
{
|
||||
// Window
|
||||
ID3D12CommandQueue* CommandQueue;
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
ID3D12DescriptorHeap* RtvDescHeap;
|
||||
IDXGISwapChain3* SwapChain;
|
||||
ID3D12Fence* Fence;
|
||||
UINT64 FenceSignaledValue;
|
||||
HANDLE FenceEvent;
|
||||
UINT NumFramesInFlight;
|
||||
ImGui_ImplDX12_FrameContext* FrameCtx;
|
||||
|
||||
// Render buffers
|
||||
UINT FrameIndex;
|
||||
ImGui_ImplDX12_RenderBuffers* FrameRenderBuffers;
|
||||
|
||||
ImGui_ImplDX12_ViewportData(UINT num_frames_in_flight)
|
||||
{
|
||||
CommandQueue = NULL;
|
||||
CommandList = NULL;
|
||||
RtvDescHeap = NULL;
|
||||
SwapChain = NULL;
|
||||
Fence = NULL;
|
||||
FenceSignaledValue = 0;
|
||||
FenceEvent = NULL;
|
||||
NumFramesInFlight = num_frames_in_flight;
|
||||
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
|
||||
FrameIndex = UINT_MAX;
|
||||
FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[NumFramesInFlight];
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
FrameCtx[i].CommandAllocator = NULL;
|
||||
FrameCtx[i].RenderTarget = NULL;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
FrameRenderBuffers[i].IndexBuffer = NULL;
|
||||
FrameRenderBuffers[i].VertexBuffer = NULL;
|
||||
FrameRenderBuffers[i].VertexBufferSize = 5000;
|
||||
FrameRenderBuffers[i].IndexBufferSize = 10000;
|
||||
}
|
||||
}
|
||||
~ImGui_ImplDX12_ViewportData()
|
||||
{
|
||||
IM_ASSERT(CommandQueue == NULL && CommandList == NULL);
|
||||
IM_ASSERT(RtvDescHeap == NULL);
|
||||
IM_ASSERT(SwapChain == NULL);
|
||||
IM_ASSERT(Fence == NULL);
|
||||
IM_ASSERT(FenceEvent == NULL);
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
IM_ASSERT(FrameCtx[i].CommandAllocator == NULL && FrameCtx[i].RenderTarget == NULL);
|
||||
IM_ASSERT(FrameRenderBuffers[i].IndexBuffer == NULL && FrameRenderBuffers[i].VertexBuffer == NULL);
|
||||
}
|
||||
|
||||
delete[] FrameCtx; FrameCtx = NULL;
|
||||
delete[] FrameRenderBuffers; FrameRenderBuffers = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX12_InitPlatformInterface();
|
||||
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
@@ -159,11 +238,10 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// FIXME: I'm 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.
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->frameIndex = bd->frameIndex + 1;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
vd->FrameIndex++;
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &vd->FrameRenderBuffers[vd->FrameIndex % bd->numFramesInFlight];
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
@@ -259,16 +337,19 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply Scissor, Bind texture, Draw
|
||||
const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
||||
if (r.right > r.left && r.bottom > r.top)
|
||||
{
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
@@ -666,24 +747,24 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_DestroyRenderBuffers(ImGui_ImplDX12_RenderBuffers* render_buffers)
|
||||
{
|
||||
SafeRelease(render_buffers->IndexBuffer);
|
||||
SafeRelease(render_buffers->VertexBuffer);
|
||||
render_buffers->IndexBufferSize = render_buffers->VertexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(NULL); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
SafeRelease(fr->IndexBuffer);
|
||||
SafeRelease(fr->VertexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
@@ -697,36 +778,46 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
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)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
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->pFrameResources = new ImGui_ImplDX12_RenderBuffers[num_frames_in_flight];
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
IM_UNUSED(cbv_srv_heap); // Unused in master branch (will be used by multi-viewports)
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
for (int i = 0; i < num_frames_in_flight; i++)
|
||||
{
|
||||
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = NULL;
|
||||
fr->VertexBuffer = NULL;
|
||||
fr->IndexBufferSize = 10000;
|
||||
fr->VertexBufferSize = 5000;
|
||||
}
|
||||
// Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
||||
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Manually delete main viewport render resources in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)main_viewport->RendererUserData)
|
||||
{
|
||||
// We could just call ImGui_ImplDX12_DestroyWindow(main_viewport) as a convenience but that would be misleading since we only use data->Resources[]
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
IM_DELETE(vd);
|
||||
main_viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
// Clean up windows and device objects
|
||||
ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
IM_DELETE(bd);
|
||||
@@ -740,3 +831,243 @@ void ImGui_ImplDX12_NewFrame()
|
||||
if (!bd->pPipelineState)
|
||||
ImGui_ImplDX12_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_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
vd->FrameIndex = UINT_MAX;
|
||||
|
||||
// Create command queue.
|
||||
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
|
||||
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
HRESULT res = S_OK;
|
||||
res = bd->pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&vd->CommandQueue));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
// Create command allocator.
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; ++i)
|
||||
{
|
||||
res = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&vd->FrameCtx[i].CommandAllocator));
|
||||
IM_ASSERT(res == S_OK);
|
||||
}
|
||||
|
||||
// Create command list.
|
||||
res = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, vd->FrameCtx[0].CommandAllocator, NULL, IID_PPV_ARGS(&vd->CommandList));
|
||||
IM_ASSERT(res == S_OK);
|
||||
vd->CommandList->Close();
|
||||
|
||||
// Create fence.
|
||||
res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&vd->Fence));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
vd->FenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
IM_ASSERT(vd->FenceEvent != NULL);
|
||||
|
||||
// Create swap chain
|
||||
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
|
||||
DXGI_SWAP_CHAIN_DESC1 sd1;
|
||||
ZeroMemory(&sd1, sizeof(sd1));
|
||||
sd1.BufferCount = bd->numFramesInFlight;
|
||||
sd1.Width = (UINT)viewport->Size.x;
|
||||
sd1.Height = (UINT)viewport->Size.y;
|
||||
sd1.Format = bd->RTVFormat;
|
||||
sd1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd1.SampleDesc.Count = 1;
|
||||
sd1.SampleDesc.Quality = 0;
|
||||
sd1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
sd1.Scaling = DXGI_SCALING_STRETCH;
|
||||
sd1.Stereo = FALSE;
|
||||
|
||||
IDXGIFactory4* dxgi_factory = NULL;
|
||||
res = ::CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_factory));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
IDXGISwapChain1* swap_chain = NULL;
|
||||
res = dxgi_factory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, NULL, NULL, &swap_chain);
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
dxgi_factory->Release();
|
||||
|
||||
// Or swapChain.As(&mSwapChain)
|
||||
IM_ASSERT(vd->SwapChain == NULL);
|
||||
swap_chain->QueryInterface(IID_PPV_ARGS(&vd->SwapChain));
|
||||
swap_chain->Release();
|
||||
|
||||
// Create the render targets
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
desc.NumDescriptors = bd->numFramesInFlight;
|
||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
desc.NodeMask = 1;
|
||||
|
||||
HRESULT hr = bd->pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&vd->RtvDescHeap));
|
||||
IM_ASSERT(hr == S_OK);
|
||||
|
||||
SIZE_T rtv_descriptor_size = bd->pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = vd->RtvDescHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
vd->FrameCtx[i].RenderTargetCpuDescriptors = rtv_handle;
|
||||
rtv_handle.ptr += rtv_descriptor_size;
|
||||
}
|
||||
|
||||
ID3D12Resource* back_buffer;
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
IM_ASSERT(vd->FrameCtx[i].RenderTarget == NULL);
|
||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
}
|
||||
|
||||
static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
if (vd && vd->CommandQueue && vd->Fence && vd->FenceEvent)
|
||||
{
|
||||
hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, 0); // Reset any forgotten waits
|
||||
hr = vd->Fence->SetEventOnCompletion(vd->FenceSignaledValue, vd->FenceEvent);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
ImGui_WaitForPendingOperations(vd);
|
||||
|
||||
SafeRelease(vd->CommandQueue);
|
||||
SafeRelease(vd->CommandList);
|
||||
SafeRelease(vd->SwapChain);
|
||||
SafeRelease(vd->RtvDescHeap);
|
||||
SafeRelease(vd->Fence);
|
||||
::CloseHandle(vd->FenceEvent);
|
||||
vd->FenceEvent = NULL;
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
||||
SafeRelease(vd->FrameCtx[i].CommandAllocator);
|
||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
||||
}
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
ImGui_WaitForPendingOperations(vd);
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
||||
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D12Resource* back_buffer = NULL;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, NULL, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % bd->numFramesInFlight];
|
||||
UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
||||
barrier.Transition.pResource = vd->FrameCtx[back_buffer_idx].RenderTarget;
|
||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
|
||||
// Draw
|
||||
ID3D12GraphicsCommandList* cmd_list = vd->CommandList;
|
||||
|
||||
frame_context->CommandAllocator->Reset();
|
||||
cmd_list->Reset(frame_context->CommandAllocator, NULL);
|
||||
cmd_list->ResourceBarrier(1, &barrier);
|
||||
cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, NULL);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (float*)&clear_color, 0, NULL);
|
||||
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
||||
|
||||
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
||||
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
cmd_list->ResourceBarrier(1, &barrier);
|
||||
cmd_list->Close();
|
||||
|
||||
vd->CommandQueue->Wait(vd->Fence, vd->FenceSignaledValue);
|
||||
vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list);
|
||||
vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
vd->SwapChain->Present(0, 0);
|
||||
while (vd->Fence->GetCompletedValue() < vd->FenceSignaledValue)
|
||||
::SwitchToThread();
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX12_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX12_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX12_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX12_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX12_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -3,26 +3,21 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// 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*.
|
||||
// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file.
|
||||
// See imgui_impl_dx12.cpp file for details.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#include <dxgiformat.h> // DXGI_FORMAT
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4471) // a forward declaration of an unscoped enumeration must have an underlying type
|
||||
#endif
|
||||
|
||||
enum DXGI_FORMAT;
|
||||
struct ID3D12Device;
|
||||
struct ID3D12DescriptorHeap;
|
||||
struct ID3D12GraphicsCommandList;
|
||||
@@ -42,8 +37,3 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
|
||||
// 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();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -12,6 +13,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 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-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||
// 2021-05-19: DirectX9: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -70,6 +72,12 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX9_InitPlatformInterface();
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
{
|
||||
@@ -248,7 +256,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
const RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) };
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||
bd->pd3dDevice->SetTexture(0, texture);
|
||||
bd->pd3dDevice->SetScissorRect(&r);
|
||||
@@ -259,6 +274,11 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
|
||||
// from rendering until the first window submits at least one draw call, even once. That's our workaround. (see #2560)
|
||||
if (global_vtx_offset == 0)
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
||||
|
||||
// Restore the DX9 transform
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||
@@ -279,18 +299,24 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
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()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "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 = NULL;
|
||||
@@ -347,6 +373,7 @@ bool ImGui_ImplDX9_CreateDeviceObjects()
|
||||
return false;
|
||||
if (!ImGui_ImplDX9_CreateFontsTexture())
|
||||
return false;
|
||||
ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -358,6 +385,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
||||
if (bd->FontTexture) { bd->FontTexture->Release(); bd->FontTexture = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||
}
|
||||
|
||||
void ImGui_ImplDX9_NewFrame()
|
||||
@@ -368,3 +396,145 @@ void ImGui_ImplDX9_NewFrame()
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplDX9_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..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplDX9_ViewportData
|
||||
{
|
||||
IDirect3DSwapChain9* SwapChain;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
ImGui_ImplDX9_ViewportData() { SwapChain = NULL; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); }
|
||||
~ImGui_ImplDX9_ViewportData() { IM_ASSERT(SwapChain == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
|
||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
||||
// Some backends will leave PlatformHandleRaw NULL, in which case we assume PlatformHandle will contain the HWND.
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
||||
vd->d3dpp.Windowed = TRUE;
|
||||
vd->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
vd->d3dpp.BackBufferWidth = (UINT)viewport->Size.x;
|
||||
vd->d3dpp.BackBufferHeight = (UINT)viewport->Size.y;
|
||||
vd->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
vd->d3dpp.hDeviceWindow = hwnd;
|
||||
vd->d3dpp.EnableAutoDepthStencil = FALSE;
|
||||
vd->d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
vd->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync
|
||||
|
||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
||||
IM_ASSERT(hr == D3D_OK);
|
||||
IM_ASSERT(vd->SwapChain != NULL);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
|
||||
if (ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = NULL;
|
||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
vd->SwapChain->Release();
|
||||
vd->SwapChain = NULL;
|
||||
vd->d3dpp.BackBufferWidth = (UINT)size.x;
|
||||
vd->d3dpp.BackBufferHeight = (UINT)size.y;
|
||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
||||
IM_ASSERT(hr == D3D_OK);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
LPDIRECT3DSURFACE9 render_target = NULL;
|
||||
LPDIRECT3DSURFACE9 last_render_target = NULL;
|
||||
LPDIRECT3DSURFACE9 last_depth_stencil = NULL;
|
||||
vd->SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target);
|
||||
bd->pd3dDevice->GetRenderTarget(0, &last_render_target);
|
||||
bd->pd3dDevice->GetDepthStencilSurface(&last_depth_stencil);
|
||||
bd->pd3dDevice->SetRenderTarget(0, render_target);
|
||||
bd->pd3dDevice->SetDepthStencilSurface(NULL);
|
||||
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f));
|
||||
bd->pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, clear_col_dx, 1.0f, 0);
|
||||
}
|
||||
|
||||
ImGui_ImplDX9_RenderDrawData(viewport->DrawData);
|
||||
|
||||
// Restore render target
|
||||
bd->pd3dDevice->SetRenderTarget(0, last_render_target);
|
||||
bd->pd3dDevice->SetDepthStencilSurface(last_depth_stencil);
|
||||
render_target->Release();
|
||||
last_render_target->Release();
|
||||
if (last_depth_stencil) last_depth_stencil->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
HRESULT hr = vd->SwapChain->Present(NULL, NULL, vd->d3dpp.hDeviceWindow, NULL, 0);
|
||||
// Let main application handle D3DERR_DEVICELOST by resetting the device.
|
||||
IM_ASSERT(hr == D3D_OK || hr == D3DERR_DEVICELOST);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX9_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX9_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX9_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (!platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplDX9_CreateWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
||||
if (platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,17 @@
|
||||
// dear imgui: Platform Backend for GLFW
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan, WebGPU..)
|
||||
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
|
||||
// (Requires: GLFW 3.1+. Prefer GLFW 3.3+ for full feature support.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [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: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: 3 cursors types are missing from GLFW.
|
||||
// [X] Platform: Keyboard arrays indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE).
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: 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.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -29,11 +34,16 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool ins
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
// GLFW callbacks
|
||||
// - When calling Init with 'install_callbacks=true': GLFW callbacks will be installed for you. They will call user's previously installed callbacks, if any.
|
||||
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call those function yourself from your own GLFW callbacks.
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered);
|
||||
// GLFW callbacks (installer)
|
||||
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
|
||||
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window);
|
||||
|
||||
// GLFW callbacks (individual callbacks to call if you didn't install callbacks)
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused); // Since 1.84
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered); // Since 1.84
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y); // Since 1.87
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
|
||||
@@ -5,19 +5,24 @@
|
||||
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
|
||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// 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]
|
||||
// Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h.
|
||||
// 2019-03-25: Misc: Made io.DeltaTime always above zero.
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
||||
@@ -37,6 +42,120 @@
|
||||
|
||||
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.
|
||||
static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case '\t': return ImGuiKey_Tab;
|
||||
case 256 + GLUT_KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||
case 256 + GLUT_KEY_RIGHT: return ImGuiKey_RightArrow;
|
||||
case 256 + GLUT_KEY_UP: return ImGuiKey_UpArrow;
|
||||
case 256 + GLUT_KEY_DOWN: return ImGuiKey_DownArrow;
|
||||
case 256 + GLUT_KEY_PAGE_UP: return ImGuiKey_PageUp;
|
||||
case 256 + GLUT_KEY_PAGE_DOWN: return ImGuiKey_PageDown;
|
||||
case 256 + GLUT_KEY_HOME: return ImGuiKey_Home;
|
||||
case 256 + GLUT_KEY_END: return ImGuiKey_End;
|
||||
case 256 + GLUT_KEY_INSERT: return ImGuiKey_Insert;
|
||||
case 127: return ImGuiKey_Delete;
|
||||
case 8: return ImGuiKey_Backspace;
|
||||
case ' ': return ImGuiKey_Space;
|
||||
case 13: return ImGuiKey_Enter;
|
||||
case 27: return ImGuiKey_Escape;
|
||||
case 39: return ImGuiKey_Apostrophe;
|
||||
case 44: return ImGuiKey_Comma;
|
||||
case 45: return ImGuiKey_Minus;
|
||||
case 46: return ImGuiKey_Period;
|
||||
case 47: return ImGuiKey_Slash;
|
||||
case 59: return ImGuiKey_Semicolon;
|
||||
case 61: return ImGuiKey_Equal;
|
||||
case 91: return ImGuiKey_LeftBracket;
|
||||
case 92: return ImGuiKey_Backslash;
|
||||
case 93: return ImGuiKey_RightBracket;
|
||||
case 96: return ImGuiKey_GraveAccent;
|
||||
//case 0: return ImGuiKey_CapsLock;
|
||||
//case 0: return ImGuiKey_ScrollLock;
|
||||
case 256 + 0x006D: return ImGuiKey_NumLock;
|
||||
//case 0: return ImGuiKey_PrintScreen;
|
||||
//case 0: return ImGuiKey_Pause;
|
||||
//case '0': return ImGuiKey_Keypad0;
|
||||
//case '1': return ImGuiKey_Keypad1;
|
||||
//case '2': return ImGuiKey_Keypad2;
|
||||
//case '3': return ImGuiKey_Keypad3;
|
||||
//case '4': return ImGuiKey_Keypad4;
|
||||
//case '5': return ImGuiKey_Keypad5;
|
||||
//case '6': return ImGuiKey_Keypad6;
|
||||
//case '7': return ImGuiKey_Keypad7;
|
||||
//case '8': return ImGuiKey_Keypad8;
|
||||
//case '9': return ImGuiKey_Keypad9;
|
||||
//case 46: return ImGuiKey_KeypadDecimal;
|
||||
//case 47: return ImGuiKey_KeypadDivide;
|
||||
case 42: return ImGuiKey_KeypadMultiply;
|
||||
//case 45: return ImGuiKey_KeypadSubtract;
|
||||
case 43: return ImGuiKey_KeypadAdd;
|
||||
//case 13: return ImGuiKey_KeypadEnter;
|
||||
//case 0: return ImGuiKey_KeypadEqual;
|
||||
case 256 + 0x0072: return ImGuiKey_LeftCtrl;
|
||||
case 256 + 0x0070: return ImGuiKey_LeftShift;
|
||||
case 256 + 0x0074: return ImGuiKey_LeftAlt;
|
||||
//case 0: return ImGuiKey_LeftSuper;
|
||||
case 256 + 0x0073: return ImGuiKey_RightCtrl;
|
||||
case 256 + 0x0071: return ImGuiKey_RightShift;
|
||||
case 256 + 0x0075: return ImGuiKey_RightAlt;
|
||||
//case 0: return ImGuiKey_RightSuper;
|
||||
//case 0: return ImGuiKey_Menu;
|
||||
case '0': return ImGuiKey_0;
|
||||
case '1': return ImGuiKey_1;
|
||||
case '2': return ImGuiKey_2;
|
||||
case '3': return ImGuiKey_3;
|
||||
case '4': return ImGuiKey_4;
|
||||
case '5': return ImGuiKey_5;
|
||||
case '6': return ImGuiKey_6;
|
||||
case '7': return ImGuiKey_7;
|
||||
case '8': return ImGuiKey_8;
|
||||
case '9': return ImGuiKey_9;
|
||||
case 'A': case 'a': return ImGuiKey_A;
|
||||
case 'B': case 'b': return ImGuiKey_B;
|
||||
case 'C': case 'c': return ImGuiKey_C;
|
||||
case 'D': case 'd': return ImGuiKey_D;
|
||||
case 'E': case 'e': return ImGuiKey_E;
|
||||
case 'F': case 'f': return ImGuiKey_F;
|
||||
case 'G': case 'g': return ImGuiKey_G;
|
||||
case 'H': case 'h': return ImGuiKey_H;
|
||||
case 'I': case 'i': return ImGuiKey_I;
|
||||
case 'J': case 'j': return ImGuiKey_J;
|
||||
case 'K': case 'k': return ImGuiKey_K;
|
||||
case 'L': case 'l': return ImGuiKey_L;
|
||||
case 'M': case 'm': return ImGuiKey_M;
|
||||
case 'N': case 'n': return ImGuiKey_N;
|
||||
case 'O': case 'o': return ImGuiKey_O;
|
||||
case 'P': case 'p': return ImGuiKey_P;
|
||||
case 'Q': case 'q': return ImGuiKey_Q;
|
||||
case 'R': case 'r': return ImGuiKey_R;
|
||||
case 'S': case 's': return ImGuiKey_S;
|
||||
case 'T': case 't': return ImGuiKey_T;
|
||||
case 'U': case 'u': return ImGuiKey_U;
|
||||
case 'V': case 'v': return ImGuiKey_V;
|
||||
case 'W': case 'w': return ImGuiKey_W;
|
||||
case 'X': case 'x': return ImGuiKey_X;
|
||||
case 'Y': case 'y': return ImGuiKey_Y;
|
||||
case 'Z': case 'z': return ImGuiKey_Z;
|
||||
case 256 + GLUT_KEY_F1: return ImGuiKey_F1;
|
||||
case 256 + GLUT_KEY_F2: return ImGuiKey_F2;
|
||||
case 256 + GLUT_KEY_F3: return ImGuiKey_F3;
|
||||
case 256 + GLUT_KEY_F4: return ImGuiKey_F4;
|
||||
case 256 + GLUT_KEY_F5: return ImGuiKey_F5;
|
||||
case 256 + GLUT_KEY_F6: return ImGuiKey_F6;
|
||||
case 256 + GLUT_KEY_F7: return ImGuiKey_F7;
|
||||
case 256 + GLUT_KEY_F8: return ImGuiKey_F8;
|
||||
case 256 + GLUT_KEY_F9: return ImGuiKey_F9;
|
||||
case 256 + GLUT_KEY_F10: return ImGuiKey_F10;
|
||||
case 256 + GLUT_KEY_F11: return ImGuiKey_F11;
|
||||
case 256 + GLUT_KEY_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplGLUT_Init()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -46,33 +165,8 @@ bool ImGui_ImplGLUT_Init()
|
||||
#else
|
||||
io.BackendPlatformName = "imgui_impl_glut";
|
||||
#endif
|
||||
|
||||
g_Time = 0;
|
||||
|
||||
// Glut has 1 function for characters and one for "special keys". We map the characters in the 0..255 range and the keys above.
|
||||
io.KeyMap[ImGuiKey_Tab] = '\t'; // == 9 == CTRL+I
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = 256 + GLUT_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = 256 + GLUT_KEY_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = 256 + GLUT_KEY_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = 256 + GLUT_KEY_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = 256 + GLUT_KEY_PAGE_UP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = 256 + GLUT_KEY_PAGE_DOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = 256 + GLUT_KEY_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = 256 + GLUT_KEY_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = 256 + GLUT_KEY_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = 127;
|
||||
io.KeyMap[ImGuiKey_Backspace] = 8; // == CTRL+H
|
||||
io.KeyMap[ImGuiKey_Space] = ' ';
|
||||
io.KeyMap[ImGuiKey_Enter] = 13; // == CTRL+M
|
||||
io.KeyMap[ImGuiKey_Escape] = 27;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = 13; // == CTRL+M
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -110,13 +204,20 @@ void ImGui_ImplGLUT_NewFrame()
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
static void ImGui_ImplGLUT_UpdateKeyboardMods()
|
||||
static void ImGui_ImplGLUT_UpdateKeyModifiers()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int mods = glutGetModifiers();
|
||||
io.KeyCtrl = (mods & GLUT_ACTIVE_CTRL) != 0;
|
||||
io.KeyShift = (mods & GLUT_ACTIVE_SHIFT) != 0;
|
||||
io.KeyAlt = (mods & GLUT_ACTIVE_ALT) != 0;
|
||||
int glut_key_mods = glutGetModifiers();
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, (glut_key_mods & GLUT_ACTIVE_CTRL) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, (glut_key_mods & GLUT_ACTIVE_SHIFT) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, (glut_key_mods & GLUT_ACTIVE_ALT) != 0);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGLUT_AddKeyEvent(ImGuiKey key, bool down, int native_keycode)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(key, down);
|
||||
io.SetKeyEventNativeData(key, native_keycode, -1); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y)
|
||||
@@ -127,79 +228,58 @@ void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y)
|
||||
if (c >= 32)
|
||||
io.AddInputCharacter((unsigned int)c);
|
||||
|
||||
// Store letters in KeysDown[] array as both uppercase and lowercase + Handle GLUT translating CTRL+A..CTRL+Z as 1..26.
|
||||
// This is a hacky mess but GLUT is unable to distinguish e.g. a TAB key from CTRL+I so this is probably the best we can do here.
|
||||
if (c >= 1 && c <= 26)
|
||||
io.KeysDown[c] = io.KeysDown[c - 1 + 'a'] = io.KeysDown[c - 1 + 'A'] = true;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
io.KeysDown[c] = io.KeysDown[c - 'a' + 'A'] = true;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = true;
|
||||
else
|
||||
io.KeysDown[c] = true;
|
||||
ImGui_ImplGLUT_UpdateKeyboardMods();
|
||||
ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c);
|
||||
ImGui_ImplGLUT_AddKeyEvent(key, true, c);
|
||||
ImGui_ImplGLUT_UpdateKeyModifiers();
|
||||
(void)x; (void)y; // Unused
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y)
|
||||
{
|
||||
//printf("char_up_func %d '%c'\n", c, c);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (c >= 1 && c <= 26)
|
||||
io.KeysDown[c] = io.KeysDown[c - 1 + 'a'] = io.KeysDown[c - 1 + 'A'] = false;
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
io.KeysDown[c] = io.KeysDown[c - 'a' + 'A'] = false;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = false;
|
||||
else
|
||||
io.KeysDown[c] = false;
|
||||
ImGui_ImplGLUT_UpdateKeyboardMods();
|
||||
ImGuiKey key = ImGui_ImplGLUT_KeyToImGuiKey(c);
|
||||
ImGui_ImplGLUT_AddKeyEvent(key, false, c);
|
||||
ImGui_ImplGLUT_UpdateKeyModifiers();
|
||||
(void)x; (void)y; // Unused
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y)
|
||||
{
|
||||
//printf("key_down_func %d\n", key);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (key + 256 < IM_ARRAYSIZE(io.KeysDown))
|
||||
io.KeysDown[key + 256] = true;
|
||||
ImGui_ImplGLUT_UpdateKeyboardMods();
|
||||
ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256);
|
||||
ImGui_ImplGLUT_AddKeyEvent(imgui_key, true, key + 256);
|
||||
ImGui_ImplGLUT_UpdateKeyModifiers();
|
||||
(void)x; (void)y; // Unused
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y)
|
||||
{
|
||||
//printf("key_up_func %d\n", key);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (key + 256 < IM_ARRAYSIZE(io.KeysDown))
|
||||
io.KeysDown[key + 256] = false;
|
||||
ImGui_ImplGLUT_UpdateKeyboardMods();
|
||||
ImGuiKey imgui_key = ImGui_ImplGLUT_KeyToImGuiKey(key + 256);
|
||||
ImGui_ImplGLUT_AddKeyEvent(imgui_key, false, key + 256);
|
||||
ImGui_ImplGLUT_UpdateKeyModifiers();
|
||||
(void)x; (void)y; // Unused
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2((float)x, (float)y);
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
int button = -1;
|
||||
if (glut_button == GLUT_LEFT_BUTTON) button = 0;
|
||||
if (glut_button == GLUT_RIGHT_BUTTON) button = 1;
|
||||
if (glut_button == GLUT_MIDDLE_BUTTON) button = 2;
|
||||
if (button != -1 && state == GLUT_DOWN)
|
||||
io.MouseDown[button] = true;
|
||||
if (button != -1 && state == GLUT_UP)
|
||||
io.MouseDown[button] = false;
|
||||
if (button != -1 && state == GLUT_DOWN || state == GLUT_UP)
|
||||
io.AddMouseButtonEvent(button, state == GLUT_DOWN);
|
||||
}
|
||||
|
||||
#ifdef __FREEGLUT_EXT_H__
|
||||
void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2((float)x, (float)y);
|
||||
if (dir > 0)
|
||||
io.MouseWheel += 1.0;
|
||||
else if (dir < 0)
|
||||
io.MouseWheel -= 1.0;
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
if (dir != 0)
|
||||
io.AddMouseWheelEvent(0.0f, dir > 0 ? 1.0f : -1.0f);
|
||||
(void)button; // Unused
|
||||
}
|
||||
#endif
|
||||
@@ -213,5 +293,5 @@ void ImGui_ImplGLUT_ReshapeFunc(int w, int h)
|
||||
void ImGui_ImplGLUT_MotionFunc(int x, int y)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2((float)x, (float)y);
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
|
||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// 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]
|
||||
// Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
// dear imgui: Renderer + Platform Backend for Marmalade + IwGx
|
||||
// Marmalade code: Copyright (C) 2015 by Giovanni Zito (this file is part of Dear ImGui)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'CIwTexture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// Missing features:
|
||||
// [ ] Renderer: Clipping rectangles are not honored.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
|
||||
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_Marmalade_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_marmalade.h"
|
||||
|
||||
#include <s3eClipboard.h>
|
||||
#include <s3ePointer.h>
|
||||
#include <s3eKeyboard.h>
|
||||
#include <IwTexture.h>
|
||||
#include <IwGx.h>
|
||||
|
||||
// Data
|
||||
static double g_Time = 0.0f;
|
||||
static bool g_MousePressed[3] = { false, false, false };
|
||||
static CIwTexture* g_FontTexture = NULL;
|
||||
static char* g_ClipboardText = NULL;
|
||||
static bool g_osdKeyboardEnabled = false;
|
||||
|
||||
// use this setting to scale the interface - e.g. on device you could use 2 or 3 scale factor
|
||||
static ImVec2 g_RenderScale = ImVec2(1.0f, 1.0f);
|
||||
|
||||
// Render function.
|
||||
void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
const int nVert = cmd_list->VtxBuffer.Size;
|
||||
CIwFVec2* pVertStream = IW_GX_ALLOC(CIwFVec2, nVert);
|
||||
CIwFVec2* pUVStream = IW_GX_ALLOC(CIwFVec2, nVert);
|
||||
CIwColour* pColStream = IW_GX_ALLOC(CIwColour, nVert);
|
||||
|
||||
for (int i = 0; i < nVert; i++)
|
||||
{
|
||||
// FIXME-OPT: optimize multiplication on GPU using vertex shader/projection matrix.
|
||||
pVertStream[i].x = cmd_list->VtxBuffer[i].pos.x * g_RenderScale.x;
|
||||
pVertStream[i].y = cmd_list->VtxBuffer[i].pos.y * g_RenderScale.y;
|
||||
pUVStream[i].x = cmd_list->VtxBuffer[i].uv.x;
|
||||
pUVStream[i].y = cmd_list->VtxBuffer[i].uv.y;
|
||||
pColStream[i] = cmd_list->VtxBuffer[i].col;
|
||||
}
|
||||
|
||||
IwGxSetVertStreamScreenSpace(pVertStream, nVert);
|
||||
IwGxSetUVStream(pUVStream);
|
||||
IwGxSetColStream(pColStream, nVert);
|
||||
IwGxSetNormStream(0);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Not honoring ClipRect fields.
|
||||
CIwMaterial* pCurrentMaterial = IW_GX_ALLOC_MATERIAL();
|
||||
pCurrentMaterial->SetShadeMode(CIwMaterial::SHADE_FLAT);
|
||||
pCurrentMaterial->SetCullMode(CIwMaterial::CULL_NONE);
|
||||
pCurrentMaterial->SetFiltering(false);
|
||||
pCurrentMaterial->SetAlphaMode(CIwMaterial::ALPHA_BLEND);
|
||||
pCurrentMaterial->SetDepthWriteMode(CIwMaterial::DEPTH_WRITE_NORMAL);
|
||||
pCurrentMaterial->SetAlphaTestMode(CIwMaterial::ALPHATEST_DISABLED);
|
||||
pCurrentMaterial->SetTexture((CIwTexture*)pcmd->GetTexID());
|
||||
IwGxSetMaterial(pCurrentMaterial);
|
||||
IwGxDrawPrims(IW_GX_TRI_LIST, (uint16*)idx_buffer, pcmd->ElemCount);
|
||||
}
|
||||
idx_buffer += pcmd->ElemCount;
|
||||
}
|
||||
IwGxFlush();
|
||||
}
|
||||
|
||||
// TODO: restore modified state (i.e. mvp matrix)
|
||||
}
|
||||
|
||||
static const char* ImGui_Marmalade_GetClipboardText(void* /*user_data*/)
|
||||
{
|
||||
if (!s3eClipboardAvailable())
|
||||
return NULL;
|
||||
|
||||
if (int size = s3eClipboardGetText(NULL, 0))
|
||||
{
|
||||
if (g_ClipboardText)
|
||||
delete[] g_ClipboardText;
|
||||
g_ClipboardText = new char[size];
|
||||
g_ClipboardText[0] = '\0';
|
||||
s3eClipboardGetText(g_ClipboardText, size);
|
||||
}
|
||||
|
||||
return g_ClipboardText;
|
||||
}
|
||||
|
||||
static void ImGui_Marmalade_SetClipboardText(void* /*user_data*/, const char* text)
|
||||
{
|
||||
if (s3eClipboardAvailable())
|
||||
s3eClipboardSetText(text);
|
||||
}
|
||||
|
||||
int32 ImGui_Marmalade_PointerButtonEventCallback(void* system_data, void* user_data)
|
||||
{
|
||||
// pEvent->m_Button is of type s3ePointerButton and indicates which mouse
|
||||
// button was pressed. For touchscreen this should always have the value
|
||||
// S3E_POINTER_BUTTON_SELECT
|
||||
s3ePointerEvent* pEvent = (s3ePointerEvent*)system_data;
|
||||
|
||||
if (pEvent->m_Pressed == 1)
|
||||
{
|
||||
if (pEvent->m_Button == S3E_POINTER_BUTTON_LEFTMOUSE)
|
||||
g_MousePressed[0] = true;
|
||||
if (pEvent->m_Button == S3E_POINTER_BUTTON_RIGHTMOUSE)
|
||||
g_MousePressed[1] = true;
|
||||
if (pEvent->m_Button == S3E_POINTER_BUTTON_MIDDLEMOUSE)
|
||||
g_MousePressed[2] = true;
|
||||
if (pEvent->m_Button == S3E_POINTER_BUTTON_MOUSEWHEELUP)
|
||||
io.MouseWheel += pEvent->m_y;
|
||||
if (pEvent->m_Button == S3E_POINTER_BUTTON_MOUSEWHEELDOWN)
|
||||
io.MouseWheel += pEvent->m_y;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ImGui_Marmalade_KeyCallback(void* system_data, void* user_data)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
s3eKeyboardEvent* e = (s3eKeyboardEvent*)system_data;
|
||||
if (e->m_Pressed == 1)
|
||||
io.KeysDown[e->m_Key] = true;
|
||||
if (e->m_Pressed == 0)
|
||||
io.KeysDown[e->m_Key] = false;
|
||||
|
||||
io.KeyCtrl = s3eKeyboardGetState(s3eKeyLeftControl) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightControl) == S3E_KEY_STATE_DOWN;
|
||||
io.KeyShift = s3eKeyboardGetState(s3eKeyLeftShift) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightShift) == S3E_KEY_STATE_DOWN;
|
||||
io.KeyAlt = s3eKeyboardGetState(s3eKeyLeftAlt) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightAlt) == S3E_KEY_STATE_DOWN;
|
||||
io.KeySuper = s3eKeyboardGetState(s3eKeyLeftWindows) == S3E_KEY_STATE_DOWN || s3eKeyboardGetState(s3eKeyRightWindows) == S3E_KEY_STATE_DOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 ImGui_Marmalade_CharCallback(void* system_data, void* user_data)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
s3eKeyboardCharEvent* e = (s3eKeyboardCharEvent*)system_data;
|
||||
io.AddInputCharacter((unsigned int)e->m_Char);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ImGui_Marmalade_CreateDeviceObjects()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
g_FontTexture = new CIwTexture();
|
||||
g_FontTexture->SetModifiable(true);
|
||||
CIwImage& image = g_FontTexture->GetImage();
|
||||
image.SetFormat(CIwImage::ARGB_8888);
|
||||
image.SetWidth(width);
|
||||
image.SetHeight(height);
|
||||
image.SetBuffers(); // allocates and own buffers
|
||||
image.ReadTexels(pixels);
|
||||
g_FontTexture->SetMipMapping(false);
|
||||
g_FontTexture->SetFiltering(false);
|
||||
g_FontTexture->Upload();
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)g_FontTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_Marmalade_InvalidateDeviceObjects()
|
||||
{
|
||||
if (g_ClipboardText)
|
||||
{
|
||||
delete[] g_ClipboardText;
|
||||
g_ClipboardText = NULL;
|
||||
}
|
||||
|
||||
if (g_FontTexture)
|
||||
{
|
||||
ImGui::GetIO().Fonts->SetTexID(0);
|
||||
delete g_FontTexture;
|
||||
g_FontTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_Marmalade_Init(bool install_callbacks)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_marmalade";
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||
io.KeyMap[ImGuiKey_Tab] = s3eKeyTab
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = s3eKeyLeft;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = s3eKeyRight;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = s3eKeyUp;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = s3eKeyDown;
|
||||
io.KeyMap[ImGuiKey_PageUp] = s3eKeyPageUp;
|
||||
io.KeyMap[ImGuiKey_PageDown] = s3eKeyPageDown;
|
||||
io.KeyMap[ImGuiKey_Home] = s3eKeyHome;
|
||||
io.KeyMap[ImGuiKey_End] = s3eKeyEnd;
|
||||
io.KeyMap[ImGuiKey_Insert] = s3eKeyInsert;
|
||||
io.KeyMap[ImGuiKey_Delete] = s3eKeyDelete;
|
||||
io.KeyMap[ImGuiKey_Backspace] = s3eKeyBackspace;
|
||||
io.KeyMap[ImGuiKey_Space] = s3eKeySpace;
|
||||
io.KeyMap[ImGuiKey_Enter] = s3eKeyEnter;
|
||||
io.KeyMap[ImGuiKey_Escape] = s3eKeyEsc;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = s3eKeyNumPadEnter;
|
||||
io.KeyMap[ImGuiKey_A] = s3eKeyA;
|
||||
io.KeyMap[ImGuiKey_C] = s3eKeyC;
|
||||
io.KeyMap[ImGuiKey_V] = s3eKeyV;
|
||||
io.KeyMap[ImGuiKey_X] = s3eKeyX;
|
||||
io.KeyMap[ImGuiKey_Y] = s3eKeyY;
|
||||
io.KeyMap[ImGuiKey_Z] = s3eKeyZ;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_Marmalade_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_Marmalade_GetClipboardText;
|
||||
|
||||
if (install_callbacks)
|
||||
{
|
||||
s3ePointerRegister(S3E_POINTER_BUTTON_EVENT, ImGui_Marmalade_PointerButtonEventCallback, 0);
|
||||
s3eKeyboardRegister(S3E_KEYBOARD_KEY_EVENT, ImGui_Marmalade_KeyCallback, 0);
|
||||
s3eKeyboardRegister(S3E_KEYBOARD_CHAR_EVENT, ImGui_Marmalade_CharCallback, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_Marmalade_Shutdown()
|
||||
{
|
||||
ImGui_Marmalade_InvalidateDeviceObjects();
|
||||
}
|
||||
|
||||
void ImGui_Marmalade_NewFrame()
|
||||
{
|
||||
if (!g_FontTexture)
|
||||
ImGui_Marmalade_CreateDeviceObjects();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w = IwGxGetScreenWidth(), h = IwGxGetScreenHeight();
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
// For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui.
|
||||
io.DisplayFramebufferScale = g_scale;
|
||||
|
||||
// Setup time step
|
||||
double current_time = s3eTimerGetUST() / 1000.0f;
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
double mouse_x, mouse_y;
|
||||
mouse_x = s3ePointerGetX();
|
||||
mouse_y = s3ePointerGetY();
|
||||
io.MousePos = ImVec2((float)mouse_x / g_scale.x, (float)mouse_y / g_scale.y); // Mouse position (set to -FLT_MAX,-FLT_MAX if no mouse / on another screen, etc.)
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
io.MouseDown[i] = g_MousePressed[i] || s3ePointerGetState((s3ePointerButton)i) != S3E_POINTER_STATE_UP; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
g_MousePressed[i] = false;
|
||||
}
|
||||
|
||||
// TODO: Hide OS mouse cursor if ImGui is drawing it
|
||||
// s3ePointerSetInt(S3E_POINTER_HIDE_CURSOR,(io.MouseDrawCursor ? 0 : 1));
|
||||
|
||||
// Show/hide OSD keyboard
|
||||
if (io.WantTextInput)
|
||||
{
|
||||
// Some text input widget is active?
|
||||
if (!g_osdKeyboardEnabled)
|
||||
{
|
||||
g_osdKeyboardEnabled = true;
|
||||
s3eKeyboardSetInt(S3E_KEYBOARD_GET_CHAR, 1); // show OSD keyboard
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No text input widget is active
|
||||
if (g_osdKeyboardEnabled)
|
||||
{
|
||||
g_osdKeyboardEnabled = false;
|
||||
s3eKeyboardSetInt(S3E_KEYBOARD_GET_CHAR, 0); // hide OSD keyboard
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// dear imgui: Renderer + Platform Backend for Marmalade + IwGx
|
||||
// Marmalade code: Copyright (C) 2015 by Giovanni Zito (this file is part of Dear ImGui)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'CIwTexture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_Marmalade_Init(bool install_callbacks);
|
||||
IMGUI_IMPL_API void ImGui_Marmalade_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_Marmalade_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_Marmalade_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_Marmalade_CreateDeviceObjects();
|
||||
|
||||
// Callbacks (installed by default if you enable 'install_callbacks' during initialization)
|
||||
// You can also handle inputs yourself and use those as a reference.
|
||||
IMGUI_IMPL_API int32 ImGui_Marmalade_PointerButtonEventCallback(void* system_data, void* user_data);
|
||||
IMGUI_IMPL_API int32 ImGui_Marmalade_KeyCallback(void* system_data, void* user_data);
|
||||
IMGUI_IMPL_API int32 ImGui_Marmalade_CharCallback(void* system_data, void* user_data);
|
||||
@@ -4,6 +4,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport / platform windows.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -12,6 +14,12 @@
|
||||
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjC API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
@class MTLRenderPassDescriptor;
|
||||
@protocol MTLDevice, MTLCommandBuffer, MTLRenderCommandEncoder;
|
||||
|
||||
@@ -27,3 +35,35 @@ 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 void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// C++ API
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Enable Metal C++ binding support with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file
|
||||
// More info about using Metal from C++: https://developer.apple.com/metal/cpp/
|
||||
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
|
||||
#include <Metal/Metal.hpp>
|
||||
|
||||
#ifndef __OBJC__
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(MTL::Device* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data,
|
||||
MTL::CommandBuffer* commandBuffer,
|
||||
MTL::RenderCommandEncoder* commandEncoder);
|
||||
|
||||
// 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 void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,14 +4,19 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport / platform 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code).
|
||||
// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
|
||||
// 2021-08-24: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted. (#4464)
|
||||
// 2021-05-19: Metal: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: Metal: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-25: Metal: Fixed texture storage mode when building on Mac Catalyst.
|
||||
@@ -76,7 +81,43 @@
|
||||
|
||||
static MetalContext *g_sharedMetalContext = nil;
|
||||
|
||||
#pragma mark - ImGui API implementation
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
|
||||
#pragma mark - Dear ImGui Metal C++ Backend API
|
||||
|
||||
bool ImGui_ImplMetal_Init(MTL::Device* device)
|
||||
{
|
||||
return ImGui_ImplMetal_Init((id<MTLDevice>)(device));
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor)
|
||||
{
|
||||
ImGui_ImplMetal_NewFrame((MTLRenderPassDescriptor*)(renderPassDescriptor));
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data,
|
||||
MTL::CommandBuffer* commandBuffer,
|
||||
MTL::RenderCommandEncoder* commandEncoder)
|
||||
{
|
||||
ImGui_ImplMetal_RenderDrawData(draw_data,
|
||||
(id<MTLCommandBuffer>)(commandBuffer),
|
||||
(id<MTLRenderCommandEncoder>)(commandEncoder));
|
||||
|
||||
}
|
||||
|
||||
bool ImGui_ImplMetal_CreateFontsTexture(MTL::Device* device)
|
||||
{
|
||||
return ImGui_ImplMetal_CreateFontsTexture((id<MTLDevice>)(device));
|
||||
}
|
||||
|
||||
bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
|
||||
{
|
||||
return ImGui_ImplMetal_CreateDeviceObjects((id<MTLDevice>)(device));
|
||||
}
|
||||
|
||||
#endif // #ifdef IMGUI_IMPL_METAL_CPP
|
||||
|
||||
#pragma mark - Dear ImGui Metal Backend API
|
||||
|
||||
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||
{
|
||||
@@ -504,36 +545,39 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec4 clip_rect;
|
||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||
clip_rect.w = (pcmd->ClipRect.w - 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);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||
// Clamp to viewport as setScissorRect() 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;
|
||||
if (pcmd->ElemCount == 0) // drawIndexedPrimitives() validation doesn't accept this
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
MTLScissorRect scissorRect =
|
||||
{
|
||||
// Apply scissor/clipping rectangle
|
||||
MTLScissorRect scissorRect =
|
||||
{
|
||||
.x = NSUInteger(clip_rect.x),
|
||||
.y = NSUInteger(clip_rect.y),
|
||||
.width = NSUInteger(clip_rect.z - clip_rect.x),
|
||||
.height = NSUInteger(clip_rect.w - clip_rect.y)
|
||||
};
|
||||
[commandEncoder setScissorRect:scissorRect];
|
||||
.x = NSUInteger(clip_min.x),
|
||||
.y = NSUInteger(clip_min.y),
|
||||
.width = NSUInteger(clip_max.x - clip_min.x),
|
||||
.height = NSUInteger(clip_max.y - clip_min.y)
|
||||
};
|
||||
[commandEncoder setScissorRect:scissorRect];
|
||||
|
||||
// Bind texture, Draw
|
||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
||||
|
||||
// Bind texture, Draw
|
||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
||||
|
||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:pcmd->ElemCount
|
||||
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
|
||||
indexBuffer:indexBuffer.buffer
|
||||
indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
|
||||
}
|
||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
indexCount:pcmd->ElemCount
|
||||
indexType:sizeof(ImDrawIdx) == 2 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
|
||||
indexBuffer:indexBuffer.buffer
|
||||
indexBufferOffset:indexBufferOffset + pcmd->IdxOffset * sizeof(ImDrawIdx)];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// 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.
|
||||
@@ -19,6 +20,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 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: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
||||
@@ -70,6 +73,10 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL2_Init()
|
||||
{
|
||||
@@ -80,15 +87,21 @@ bool ImGui_ImplOpenGL2_Init()
|
||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_opengl2";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
@@ -200,23 +213,18 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec4 clip_rect;
|
||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||
clip_rect.w = (pcmd->ClipRect.w - 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);
|
||||
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;
|
||||
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||
{
|
||||
// Apply scissor/clipping rectangle
|
||||
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
||||
}
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
||||
}
|
||||
idx_buffer += pcmd->ElemCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,3 +294,31 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -14,6 +15,9 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
|
||||
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
|
||||
// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader.
|
||||
// 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-25: OpenGL: Use OES_vertex_array extension on Emscripten + backup/restore current state.
|
||||
@@ -94,9 +98,23 @@
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// GL includes
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#include <GLES2/gl2.h>
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
||||
#include <OpenGLES/ES2/gl.h> // Use GL ES 2
|
||||
#else
|
||||
#include <GLES2/gl2.h> // Use GL ES 2
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#ifndef GL_GLEXT_PROTOTYPES
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
@@ -104,6 +122,9 @@
|
||||
#include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
|
||||
#include <OpenGLES/ES3/gl.h> // Use GL ES 3
|
||||
#else
|
||||
@@ -170,6 +191,8 @@ struct ImGui_ImplOpenGL3_Data
|
||||
GLuint AttribLocationVtxUV;
|
||||
GLuint AttribLocationVtxColor;
|
||||
unsigned int VboHandle, ElementsHandle;
|
||||
GLsizeiptr VertexBufferSize;
|
||||
GLsizeiptr IndexBufferSize;
|
||||
bool HasClipOrigin;
|
||||
|
||||
ImGui_ImplOpenGL3_Data() { memset(this, 0, sizeof(*this)); }
|
||||
@@ -182,6 +205,10 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
{
|
||||
@@ -223,6 +250,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
if (bd->GlVersion >= 320)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
// 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 NULL if unsure.
|
||||
@@ -260,14 +288,19 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
@@ -420,8 +453,20 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
|
||||
GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
if (bd->VertexBufferSize < vtx_buffer_size)
|
||||
{
|
||||
bd->VertexBufferSize = vtx_buffer_size;
|
||||
glBufferData(GL_ARRAY_BUFFER, bd->VertexBufferSize, NULL, GL_STREAM_DRAW);
|
||||
}
|
||||
if (bd->IndexBufferSize < idx_buffer_size)
|
||||
{
|
||||
bd->IndexBufferSize = idx_buffer_size;
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, NULL, GL_STREAM_DRAW);
|
||||
}
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
@@ -438,26 +483,22 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec4 clip_rect;
|
||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||
clip_rect.w = (pcmd->ClipRect.w - 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);
|
||||
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;
|
||||
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||
{
|
||||
// Apply scissor/clipping rectangle
|
||||
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
if (bd->GlVersion >= 320)
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
|
||||
else
|
||||
if (bd->GlVersion >= 320)
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
|
||||
else
|
||||
#endif
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||
}
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -625,7 +666,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
"}\n";
|
||||
|
||||
const GLchar* vertex_shader_glsl_300_es =
|
||||
"precision mediump float;\n"
|
||||
"precision highp float;\n"
|
||||
"layout (location = 0) in vec2 Position;\n"
|
||||
"layout (location = 1) in vec2 UV;\n"
|
||||
"layout (location = 2) in vec4 Color;\n"
|
||||
@@ -775,3 +816,35 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
||||
if (bd->ShaderHandle) { glDeleteProgram(bd->ShaderHandle); bd->ShaderHandle = 0; }
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@@ -42,7 +43,7 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
|
||||
// Try to detect GLES on matching platforms
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
|
||||
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// About imgui_impl_opengl3_loader.h:
|
||||
//
|
||||
// We embed our own OpenGL loader to not require user to provide their own or to have to use ours,
|
||||
// which proved to be endless problems for users.
|
||||
// Our loader is custom-generated, based on gl3w but automatically filtered to only include
|
||||
// enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small.
|
||||
//
|
||||
// YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY.
|
||||
// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
|
||||
//
|
||||
// Regenerate with:
|
||||
// python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
//
|
||||
// More info:
|
||||
// https://github.com/dearimgui/gl3w_stripped
|
||||
// https://github.com/ocornut/imgui/issues/4445
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* This file was generated with gl3w_gen.py, part of imgl3w
|
||||
* (hosted at https://github.com/dearimgui/gl3w_stripped)
|
||||
@@ -26,14 +45,11 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// We embed our own OpenGL loader to not require user to provide their own or to have to use ours, which proved to be endless problems for users.
|
||||
// Our loader is custom-generated, based on gl3w but automatically filtered to only include enums/functions that we use in this source file.
|
||||
// Regenerate with: python gl3w_gen.py --imgui-dir /path/to/imgui/
|
||||
// see https://github.com/dearimgui/gl3w_stripped for more info.
|
||||
#ifndef __gl3w_h_
|
||||
#define __gl3w_h_
|
||||
|
||||
// Adapted from KHR/khrplatform.h to avoid including entire file.
|
||||
#ifndef __khrplatform_h_
|
||||
typedef float khronos_float_t;
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
@@ -58,6 +74,7 @@ typedef uint64_t khronos_uint64_t;
|
||||
typedef signed long long khronos_int64_t;
|
||||
typedef unsigned long long khronos_uint64_t;
|
||||
#endif
|
||||
#endif // __khrplatform_h_
|
||||
|
||||
#ifndef __gl_glcorearb_h_
|
||||
#define __gl_glcorearb_h_ 1
|
||||
@@ -162,6 +179,7 @@ typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
|
||||
typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
|
||||
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
|
||||
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
|
||||
typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
|
||||
@@ -177,6 +195,7 @@ GLAPI void APIENTRY glDisable (GLenum cap);
|
||||
GLAPI void APIENTRY glEnable (GLenum cap);
|
||||
GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);
|
||||
GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
GLAPI GLenum APIENTRY glGetError (void);
|
||||
GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);
|
||||
GLAPI const GLubyte *APIENTRY glGetString (GLenum name);
|
||||
GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);
|
||||
@@ -230,11 +249,13 @@ typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
|
||||
GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
|
||||
GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
|
||||
GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_5 */
|
||||
#ifndef GL_VERSION_2_0
|
||||
@@ -416,7 +437,7 @@ GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||
|
||||
/* gl3w internal state */
|
||||
union GL3WProcs {
|
||||
GL3WglProc ptr[52];
|
||||
GL3WglProc ptr[54];
|
||||
struct {
|
||||
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||
PFNGLATTACHSHADERPROC AttachShader;
|
||||
@@ -428,6 +449,7 @@ union GL3WProcs {
|
||||
PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate;
|
||||
PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
|
||||
PFNGLBUFFERDATAPROC BufferData;
|
||||
PFNGLBUFFERSUBDATAPROC BufferSubData;
|
||||
PFNGLCLEARPROC Clear;
|
||||
PFNGLCLEARCOLORPROC ClearColor;
|
||||
PFNGLCOMPILESHADERPROC CompileShader;
|
||||
@@ -448,6 +470,7 @@ union GL3WProcs {
|
||||
PFNGLGENTEXTURESPROC GenTextures;
|
||||
PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
|
||||
PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
|
||||
PFNGLGETERRORPROC GetError;
|
||||
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||
PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
|
||||
PFNGLGETPROGRAMIVPROC GetProgramiv;
|
||||
@@ -473,61 +496,63 @@ union GL3WProcs {
|
||||
} gl;
|
||||
};
|
||||
|
||||
GL3W_API extern union GL3WProcs gl3wProcs;
|
||||
GL3W_API extern union GL3WProcs imgl3wProcs;
|
||||
|
||||
/* OpenGL functions */
|
||||
#define glActiveTexture gl3wProcs.gl.ActiveTexture
|
||||
#define glAttachShader gl3wProcs.gl.AttachShader
|
||||
#define glBindBuffer gl3wProcs.gl.BindBuffer
|
||||
#define glBindSampler gl3wProcs.gl.BindSampler
|
||||
#define glBindTexture gl3wProcs.gl.BindTexture
|
||||
#define glBindVertexArray gl3wProcs.gl.BindVertexArray
|
||||
#define glBlendEquation gl3wProcs.gl.BlendEquation
|
||||
#define glBlendEquationSeparate gl3wProcs.gl.BlendEquationSeparate
|
||||
#define glBlendFuncSeparate gl3wProcs.gl.BlendFuncSeparate
|
||||
#define glBufferData gl3wProcs.gl.BufferData
|
||||
#define glClear gl3wProcs.gl.Clear
|
||||
#define glClearColor gl3wProcs.gl.ClearColor
|
||||
#define glCompileShader gl3wProcs.gl.CompileShader
|
||||
#define glCreateProgram gl3wProcs.gl.CreateProgram
|
||||
#define glCreateShader gl3wProcs.gl.CreateShader
|
||||
#define glDeleteBuffers gl3wProcs.gl.DeleteBuffers
|
||||
#define glDeleteProgram gl3wProcs.gl.DeleteProgram
|
||||
#define glDeleteShader gl3wProcs.gl.DeleteShader
|
||||
#define glDeleteTextures gl3wProcs.gl.DeleteTextures
|
||||
#define glDeleteVertexArrays gl3wProcs.gl.DeleteVertexArrays
|
||||
#define glDetachShader gl3wProcs.gl.DetachShader
|
||||
#define glDisable gl3wProcs.gl.Disable
|
||||
#define glDrawElements gl3wProcs.gl.DrawElements
|
||||
#define glDrawElementsBaseVertex gl3wProcs.gl.DrawElementsBaseVertex
|
||||
#define glEnable gl3wProcs.gl.Enable
|
||||
#define glEnableVertexAttribArray gl3wProcs.gl.EnableVertexAttribArray
|
||||
#define glGenBuffers gl3wProcs.gl.GenBuffers
|
||||
#define glGenTextures gl3wProcs.gl.GenTextures
|
||||
#define glGenVertexArrays gl3wProcs.gl.GenVertexArrays
|
||||
#define glGetAttribLocation gl3wProcs.gl.GetAttribLocation
|
||||
#define glGetIntegerv gl3wProcs.gl.GetIntegerv
|
||||
#define glGetProgramInfoLog gl3wProcs.gl.GetProgramInfoLog
|
||||
#define glGetProgramiv gl3wProcs.gl.GetProgramiv
|
||||
#define glGetShaderInfoLog gl3wProcs.gl.GetShaderInfoLog
|
||||
#define glGetShaderiv gl3wProcs.gl.GetShaderiv
|
||||
#define glGetString gl3wProcs.gl.GetString
|
||||
#define glGetStringi gl3wProcs.gl.GetStringi
|
||||
#define glGetUniformLocation gl3wProcs.gl.GetUniformLocation
|
||||
#define glIsEnabled gl3wProcs.gl.IsEnabled
|
||||
#define glLinkProgram gl3wProcs.gl.LinkProgram
|
||||
#define glPixelStorei gl3wProcs.gl.PixelStorei
|
||||
#define glPolygonMode gl3wProcs.gl.PolygonMode
|
||||
#define glReadPixels gl3wProcs.gl.ReadPixels
|
||||
#define glScissor gl3wProcs.gl.Scissor
|
||||
#define glShaderSource gl3wProcs.gl.ShaderSource
|
||||
#define glTexImage2D gl3wProcs.gl.TexImage2D
|
||||
#define glTexParameteri gl3wProcs.gl.TexParameteri
|
||||
#define glUniform1i gl3wProcs.gl.Uniform1i
|
||||
#define glUniformMatrix4fv gl3wProcs.gl.UniformMatrix4fv
|
||||
#define glUseProgram gl3wProcs.gl.UseProgram
|
||||
#define glVertexAttribPointer gl3wProcs.gl.VertexAttribPointer
|
||||
#define glViewport gl3wProcs.gl.Viewport
|
||||
#define glActiveTexture imgl3wProcs.gl.ActiveTexture
|
||||
#define glAttachShader imgl3wProcs.gl.AttachShader
|
||||
#define glBindBuffer imgl3wProcs.gl.BindBuffer
|
||||
#define glBindSampler imgl3wProcs.gl.BindSampler
|
||||
#define glBindTexture imgl3wProcs.gl.BindTexture
|
||||
#define glBindVertexArray imgl3wProcs.gl.BindVertexArray
|
||||
#define glBlendEquation imgl3wProcs.gl.BlendEquation
|
||||
#define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate
|
||||
#define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate
|
||||
#define glBufferData imgl3wProcs.gl.BufferData
|
||||
#define glBufferSubData imgl3wProcs.gl.BufferSubData
|
||||
#define glClear imgl3wProcs.gl.Clear
|
||||
#define glClearColor imgl3wProcs.gl.ClearColor
|
||||
#define glCompileShader imgl3wProcs.gl.CompileShader
|
||||
#define glCreateProgram imgl3wProcs.gl.CreateProgram
|
||||
#define glCreateShader imgl3wProcs.gl.CreateShader
|
||||
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
|
||||
#define glDeleteProgram imgl3wProcs.gl.DeleteProgram
|
||||
#define glDeleteShader imgl3wProcs.gl.DeleteShader
|
||||
#define glDeleteTextures imgl3wProcs.gl.DeleteTextures
|
||||
#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays
|
||||
#define glDetachShader imgl3wProcs.gl.DetachShader
|
||||
#define glDisable imgl3wProcs.gl.Disable
|
||||
#define glDrawElements imgl3wProcs.gl.DrawElements
|
||||
#define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex
|
||||
#define glEnable imgl3wProcs.gl.Enable
|
||||
#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray
|
||||
#define glGenBuffers imgl3wProcs.gl.GenBuffers
|
||||
#define glGenTextures imgl3wProcs.gl.GenTextures
|
||||
#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays
|
||||
#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation
|
||||
#define glGetError imgl3wProcs.gl.GetError
|
||||
#define glGetIntegerv imgl3wProcs.gl.GetIntegerv
|
||||
#define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog
|
||||
#define glGetProgramiv imgl3wProcs.gl.GetProgramiv
|
||||
#define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog
|
||||
#define glGetShaderiv imgl3wProcs.gl.GetShaderiv
|
||||
#define glGetString imgl3wProcs.gl.GetString
|
||||
#define glGetStringi imgl3wProcs.gl.GetStringi
|
||||
#define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation
|
||||
#define glIsEnabled imgl3wProcs.gl.IsEnabled
|
||||
#define glLinkProgram imgl3wProcs.gl.LinkProgram
|
||||
#define glPixelStorei imgl3wProcs.gl.PixelStorei
|
||||
#define glPolygonMode imgl3wProcs.gl.PolygonMode
|
||||
#define glReadPixels imgl3wProcs.gl.ReadPixels
|
||||
#define glScissor imgl3wProcs.gl.Scissor
|
||||
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
||||
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
||||
#define glTexParameteri imgl3wProcs.gl.TexParameteri
|
||||
#define glUniform1i imgl3wProcs.gl.Uniform1i
|
||||
#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
|
||||
#define glUseProgram imgl3wProcs.gl.UseProgram
|
||||
#define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer
|
||||
#define glViewport imgl3wProcs.gl.Viewport
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -671,6 +696,7 @@ static const char *proc_names[] = {
|
||||
"glBlendEquationSeparate",
|
||||
"glBlendFuncSeparate",
|
||||
"glBufferData",
|
||||
"glBufferSubData",
|
||||
"glClear",
|
||||
"glClearColor",
|
||||
"glCompileShader",
|
||||
@@ -691,6 +717,7 @@ static const char *proc_names[] = {
|
||||
"glGenTextures",
|
||||
"glGenVertexArrays",
|
||||
"glGetAttribLocation",
|
||||
"glGetError",
|
||||
"glGetIntegerv",
|
||||
"glGetProgramInfoLog",
|
||||
"glGetProgramiv",
|
||||
@@ -715,13 +742,13 @@ static const char *proc_names[] = {
|
||||
"glViewport",
|
||||
};
|
||||
|
||||
GL3W_API union GL3WProcs gl3wProcs;
|
||||
GL3W_API union GL3WProcs imgl3wProcs;
|
||||
|
||||
static void load_procs(GL3WGetProcAddressProc proc)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(proc_names); i++)
|
||||
gl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||
imgl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [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: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// Issues:
|
||||
// [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters]..
|
||||
// [ ] Platform: Multi-viewport / platform 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
@@ -18,7 +21,7 @@
|
||||
@class NSEvent;
|
||||
@class NSView;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_HandleEvent(NSEvent* _Nonnull event, NSView* _Nullable view);
|
||||
|
||||
@@ -4,21 +4,37 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [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: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: IME support.
|
||||
// Issues:
|
||||
// [ ] Platform: Keys are all generally very broken. Best using [event keycode] and not [event characters]..
|
||||
// [ ] Platform: Multi-viewport / platform windows.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_osx.h"
|
||||
#import "imgui.h"
|
||||
#import "imgui_impl_osx.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <mach/mach_time.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <GameController/GameController.h>
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-02-07: Inputs: Forward keyDown/keyUp events to OS when unused by dear imgui.
|
||||
// 2022-01-31: Fix building with old Xcode versions that are missing gamepad features.
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys.
|
||||
// 2021-12-13: Add game controller support.
|
||||
// 2021-09-21: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on NSApplicationDidBecomeActiveNotification/NSApplicationDidResignActiveNotification events.
|
||||
// 2021-06-23: Inputs: Added a fix for shortcuts using CTRL key instead of CMD key.
|
||||
// 2021-04-19: Inputs: Added a fix for keys remaining stuck in pressed state when CMD-tabbing into different application.
|
||||
@@ -34,15 +50,21 @@
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
||||
// 2018-07-07: Initial version.
|
||||
|
||||
#define APPLE_HAS_BUTTON_OPTIONS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500 || __TV_OS_VERSION_MIN_REQUIRED >= 130000)
|
||||
#define APPLE_HAS_CONTROLLER (__IPHONE_OS_VERSION_MIN_REQUIRED >= 140000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 110000 || __TV_OS_VERSION_MIN_REQUIRED >= 140000)
|
||||
#define APPLE_HAS_THUMBSTICKS (__IPHONE_OS_VERSION_MIN_REQUIRED >= 120100 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101401 || __TV_OS_VERSION_MIN_REQUIRED >= 120100)
|
||||
|
||||
@class ImFocusObserver;
|
||||
@class KeyEventResponder;
|
||||
|
||||
// Data
|
||||
static CFAbsoluteTime g_Time = 0.0;
|
||||
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
|
||||
static bool g_MouseCursorHidden = false;
|
||||
static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {};
|
||||
static bool g_MouseDown[ImGuiMouseButton_COUNT] = {};
|
||||
static ImFocusObserver* g_FocusObserver = NULL;
|
||||
static double g_HostClockPeriod = 0.0;
|
||||
static double g_Time = 0.0;
|
||||
static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {};
|
||||
static bool g_MouseCursorHidden = false;
|
||||
static ImFocusObserver* g_FocusObserver = nil;
|
||||
static KeyEventResponder* g_KeyEventResponder = nil;
|
||||
static NSTextInputContext* g_InputContext = nil;
|
||||
|
||||
// Undocumented methods for creating cursors.
|
||||
@interface NSCursor()
|
||||
@@ -52,13 +74,146 @@ static ImFocusObserver* g_FocusObserver = NULL;
|
||||
+ (id)_windowResizeEastWestCursor;
|
||||
@end
|
||||
|
||||
static void resetKeys()
|
||||
static void InitHostClockPeriod()
|
||||
{
|
||||
struct mach_timebase_info info;
|
||||
mach_timebase_info(&info);
|
||||
g_HostClockPeriod = 1e-9 * ((double)info.denom / (double)info.numer); // Period is the reciprocal of frequency.
|
||||
}
|
||||
|
||||
static double GetMachAbsoluteTimeInSeconds()
|
||||
{
|
||||
return (double)mach_absolute_time() * g_HostClockPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
KeyEventResponder implements the NSTextInputClient protocol as is required by the macOS text input manager.
|
||||
|
||||
The macOS text input manager is invoked by calling the interpretKeyEvents method from the keyDown method.
|
||||
Keyboard events are then evaluated by the macOS input manager and valid text input is passed back via the
|
||||
insertText:replacementRange method.
|
||||
|
||||
This is the same approach employed by other cross-platform libraries such as SDL2:
|
||||
https://github.com/spurious/SDL-mirror/blob/e17aacbd09e65a4fd1e166621e011e581fb017a8/src/video/cocoa/SDL_cocoakeyboard.m#L53
|
||||
and GLFW:
|
||||
https://github.com/glfw/glfw/blob/b55a517ae0c7b5127dffa79a64f5406021bf9076/src/cocoa_window.m#L722-L723
|
||||
*/
|
||||
@interface KeyEventResponder: NSView<NSTextInputClient>
|
||||
@end
|
||||
|
||||
@implementation KeyEventResponder
|
||||
{
|
||||
float _posX;
|
||||
float _posY;
|
||||
NSRect _imeRect;
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)setImePosX:(float)posX imePosY:(float)posY
|
||||
{
|
||||
_posX = posX;
|
||||
_posY = posY;
|
||||
}
|
||||
|
||||
- (void)updateImePosWithView:(NSView *)view
|
||||
{
|
||||
NSWindow *window = view.window;
|
||||
if (!window)
|
||||
return;
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||
_imeRect = [window convertRectToScreen:rect];
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
// Ensure self is a first responder to receive the input events.
|
||||
[self.window makeFirstResponder:self];
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent*)event
|
||||
{
|
||||
if (!ImGui_ImplOSX_HandleEvent(event, self))
|
||||
[super keyDown:event];
|
||||
|
||||
// Call to the macOS input manager system.
|
||||
[self interpretKeyEvents:@[event]];
|
||||
}
|
||||
|
||||
- (void)keyUp:(NSEvent*)event
|
||||
{
|
||||
if (!ImGui_ImplOSX_HandleEvent(event, self))
|
||||
[super keyUp:event];
|
||||
}
|
||||
|
||||
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.KeysDown, 0, sizeof(io.KeysDown));
|
||||
io.KeyCtrl = io.KeyShift = io.KeyAlt = io.KeySuper = false;
|
||||
|
||||
NSString* characters;
|
||||
if ([aString isKindOfClass:[NSAttributedString class]])
|
||||
characters = [aString string];
|
||||
else
|
||||
characters = (NSString*)aString;
|
||||
|
||||
io.AddInputCharactersUTF8(characters.UTF8String);
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)myselector
|
||||
{
|
||||
}
|
||||
|
||||
- (nullable NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSUInteger)characterIndexForPoint:(NSPoint)point
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(nullable NSRangePointer)actualRange
|
||||
{
|
||||
return _imeRect;
|
||||
}
|
||||
|
||||
- (BOOL)hasMarkedText
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSRange)markedRange
|
||||
{
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
|
||||
- (NSRange)selectedRange
|
||||
{
|
||||
return NSMakeRange(NSNotFound, 0);
|
||||
}
|
||||
|
||||
- (void)setMarkedText:(nonnull id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
|
||||
{
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
{
|
||||
}
|
||||
|
||||
- (nonnull NSArray<NSAttributedStringKey>*)validAttributesForMarkedText
|
||||
{
|
||||
return @[];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface ImFocusObserver : NSObject
|
||||
|
||||
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
||||
@@ -78,17 +233,135 @@ static void resetKeys()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddFocusEvent(false);
|
||||
|
||||
// Unfocused applications do not receive input events, therefore we must manually
|
||||
// release any pressed keys when application loses focus, otherwise they would remain
|
||||
// stuck in a pressed state. https://github.com/ocornut/imgui/issues/3832
|
||||
resetKeys();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOSX_Init()
|
||||
static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
case kVK_ANSI_A: return ImGuiKey_A;
|
||||
case kVK_ANSI_S: return ImGuiKey_S;
|
||||
case kVK_ANSI_D: return ImGuiKey_D;
|
||||
case kVK_ANSI_F: return ImGuiKey_F;
|
||||
case kVK_ANSI_H: return ImGuiKey_H;
|
||||
case kVK_ANSI_G: return ImGuiKey_G;
|
||||
case kVK_ANSI_Z: return ImGuiKey_Z;
|
||||
case kVK_ANSI_X: return ImGuiKey_X;
|
||||
case kVK_ANSI_C: return ImGuiKey_C;
|
||||
case kVK_ANSI_V: return ImGuiKey_V;
|
||||
case kVK_ANSI_B: return ImGuiKey_B;
|
||||
case kVK_ANSI_Q: return ImGuiKey_Q;
|
||||
case kVK_ANSI_W: return ImGuiKey_W;
|
||||
case kVK_ANSI_E: return ImGuiKey_E;
|
||||
case kVK_ANSI_R: return ImGuiKey_R;
|
||||
case kVK_ANSI_Y: return ImGuiKey_Y;
|
||||
case kVK_ANSI_T: return ImGuiKey_T;
|
||||
case kVK_ANSI_1: return ImGuiKey_1;
|
||||
case kVK_ANSI_2: return ImGuiKey_2;
|
||||
case kVK_ANSI_3: return ImGuiKey_3;
|
||||
case kVK_ANSI_4: return ImGuiKey_4;
|
||||
case kVK_ANSI_6: return ImGuiKey_6;
|
||||
case kVK_ANSI_5: return ImGuiKey_5;
|
||||
case kVK_ANSI_Equal: return ImGuiKey_Equal;
|
||||
case kVK_ANSI_9: return ImGuiKey_9;
|
||||
case kVK_ANSI_7: return ImGuiKey_7;
|
||||
case kVK_ANSI_Minus: return ImGuiKey_Minus;
|
||||
case kVK_ANSI_8: return ImGuiKey_8;
|
||||
case kVK_ANSI_0: return ImGuiKey_0;
|
||||
case kVK_ANSI_RightBracket: return ImGuiKey_RightBracket;
|
||||
case kVK_ANSI_O: return ImGuiKey_O;
|
||||
case kVK_ANSI_U: return ImGuiKey_U;
|
||||
case kVK_ANSI_LeftBracket: return ImGuiKey_LeftBracket;
|
||||
case kVK_ANSI_I: return ImGuiKey_I;
|
||||
case kVK_ANSI_P: return ImGuiKey_P;
|
||||
case kVK_ANSI_L: return ImGuiKey_L;
|
||||
case kVK_ANSI_J: return ImGuiKey_J;
|
||||
case kVK_ANSI_Quote: return ImGuiKey_Apostrophe;
|
||||
case kVK_ANSI_K: return ImGuiKey_K;
|
||||
case kVK_ANSI_Semicolon: return ImGuiKey_Semicolon;
|
||||
case kVK_ANSI_Backslash: return ImGuiKey_Backslash;
|
||||
case kVK_ANSI_Comma: return ImGuiKey_Comma;
|
||||
case kVK_ANSI_Slash: return ImGuiKey_Slash;
|
||||
case kVK_ANSI_N: return ImGuiKey_N;
|
||||
case kVK_ANSI_M: return ImGuiKey_M;
|
||||
case kVK_ANSI_Period: return ImGuiKey_Period;
|
||||
case kVK_ANSI_Grave: return ImGuiKey_GraveAccent;
|
||||
case kVK_ANSI_KeypadDecimal: return ImGuiKey_KeypadDecimal;
|
||||
case kVK_ANSI_KeypadMultiply: return ImGuiKey_KeypadMultiply;
|
||||
case kVK_ANSI_KeypadPlus: return ImGuiKey_KeypadAdd;
|
||||
case kVK_ANSI_KeypadClear: return ImGuiKey_NumLock;
|
||||
case kVK_ANSI_KeypadDivide: return ImGuiKey_KeypadDivide;
|
||||
case kVK_ANSI_KeypadEnter: return ImGuiKey_KeypadEnter;
|
||||
case kVK_ANSI_KeypadMinus: return ImGuiKey_KeypadSubtract;
|
||||
case kVK_ANSI_KeypadEquals: return ImGuiKey_KeypadEqual;
|
||||
case kVK_ANSI_Keypad0: return ImGuiKey_Keypad0;
|
||||
case kVK_ANSI_Keypad1: return ImGuiKey_Keypad1;
|
||||
case kVK_ANSI_Keypad2: return ImGuiKey_Keypad2;
|
||||
case kVK_ANSI_Keypad3: return ImGuiKey_Keypad3;
|
||||
case kVK_ANSI_Keypad4: return ImGuiKey_Keypad4;
|
||||
case kVK_ANSI_Keypad5: return ImGuiKey_Keypad5;
|
||||
case kVK_ANSI_Keypad6: return ImGuiKey_Keypad6;
|
||||
case kVK_ANSI_Keypad7: return ImGuiKey_Keypad7;
|
||||
case kVK_ANSI_Keypad8: return ImGuiKey_Keypad8;
|
||||
case kVK_ANSI_Keypad9: return ImGuiKey_Keypad9;
|
||||
case kVK_Return: return ImGuiKey_Enter;
|
||||
case kVK_Tab: return ImGuiKey_Tab;
|
||||
case kVK_Space: return ImGuiKey_Space;
|
||||
case kVK_Delete: return ImGuiKey_Backspace;
|
||||
case kVK_Escape: return ImGuiKey_Escape;
|
||||
case kVK_CapsLock: return ImGuiKey_CapsLock;
|
||||
case kVK_Control: return ImGuiKey_LeftCtrl;
|
||||
case kVK_Shift: return ImGuiKey_LeftShift;
|
||||
case kVK_Option: return ImGuiKey_LeftAlt;
|
||||
case kVK_Command: return ImGuiKey_LeftSuper;
|
||||
case kVK_RightControl: return ImGuiKey_RightCtrl;
|
||||
case kVK_RightShift: return ImGuiKey_RightShift;
|
||||
case kVK_RightOption: return ImGuiKey_RightAlt;
|
||||
case kVK_RightCommand: return ImGuiKey_RightSuper;
|
||||
// case kVK_Function: return ImGuiKey_;
|
||||
// case kVK_F17: return ImGuiKey_;
|
||||
// case kVK_VolumeUp: return ImGuiKey_;
|
||||
// case kVK_VolumeDown: return ImGuiKey_;
|
||||
// case kVK_Mute: return ImGuiKey_;
|
||||
// case kVK_F18: return ImGuiKey_;
|
||||
// case kVK_F19: return ImGuiKey_;
|
||||
// case kVK_F20: return ImGuiKey_;
|
||||
case kVK_F5: return ImGuiKey_F5;
|
||||
case kVK_F6: return ImGuiKey_F6;
|
||||
case kVK_F7: return ImGuiKey_F7;
|
||||
case kVK_F3: return ImGuiKey_F3;
|
||||
case kVK_F8: return ImGuiKey_F8;
|
||||
case kVK_F9: return ImGuiKey_F9;
|
||||
case kVK_F11: return ImGuiKey_F11;
|
||||
case kVK_F13: return ImGuiKey_PrintScreen;
|
||||
// case kVK_F16: return ImGuiKey_;
|
||||
// case kVK_F14: return ImGuiKey_;
|
||||
case kVK_F10: return ImGuiKey_F10;
|
||||
case 0x6E: return ImGuiKey_Menu;
|
||||
case kVK_F12: return ImGuiKey_F12;
|
||||
// case kVK_F15: return ImGuiKey_;
|
||||
case kVK_Help: return ImGuiKey_Insert;
|
||||
case kVK_Home: return ImGuiKey_Home;
|
||||
case kVK_PageUp: return ImGuiKey_PageUp;
|
||||
case kVK_ForwardDelete: return ImGuiKey_Delete;
|
||||
case kVK_F4: return ImGuiKey_F4;
|
||||
case kVK_End: return ImGuiKey_End;
|
||||
case kVK_F2: return ImGuiKey_F2;
|
||||
case kVK_PageDown: return ImGuiKey_PageDown;
|
||||
case kVK_F1: return ImGuiKey_F1;
|
||||
case kVK_LeftArrow: return ImGuiKey_LeftArrow;
|
||||
case kVK_RightArrow: return ImGuiKey_RightArrow;
|
||||
case kVK_DownArrow: return ImGuiKey_DownArrow;
|
||||
case kVK_UpArrow: return ImGuiKey_UpArrow;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ImGui_ImplOSX_Init(NSView* view)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -96,34 +369,9 @@ bool ImGui_ImplOSX_Init()
|
||||
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_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
io.BackendPlatformName = "imgui_impl_osx";
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
const int offset_for_function_keys = 256 - 0xF700;
|
||||
io.KeyMap[ImGuiKey_Tab] = '\t';
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = NSLeftArrowFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = NSRightArrowFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = NSUpArrowFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = NSDownArrowFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_PageUp] = NSPageUpFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_PageDown] = NSPageDownFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_Home] = NSHomeFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_End] = NSEndFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_Insert] = NSInsertFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_Delete] = NSDeleteFunctionKey + offset_for_function_keys;
|
||||
io.KeyMap[ImGuiKey_Backspace] = 127;
|
||||
io.KeyMap[ImGuiKey_Space] = 32;
|
||||
io.KeyMap[ImGuiKey_Enter] = 13;
|
||||
io.KeyMap[ImGuiKey_Escape] = 27;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = 3;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
// Load cursors. Some of them are undocumented.
|
||||
g_MouseCursorHidden = false;
|
||||
g_MouseCursors[ImGuiMouseCursor_Arrow] = [NSCursor arrowCursor];
|
||||
@@ -175,6 +423,36 @@ bool ImGui_ImplOSX_Init()
|
||||
name:NSApplicationDidResignActiveNotification
|
||||
object:nil];
|
||||
|
||||
// Add the NSTextInputClient to the view hierarchy,
|
||||
// to receive keyboard events and translate them to input text.
|
||||
g_KeyEventResponder = [[KeyEventResponder alloc] initWithFrame:NSZeroRect];
|
||||
g_InputContext = [[NSTextInputContext alloc] initWithClient:g_KeyEventResponder];
|
||||
[view addSubview:g_KeyEventResponder];
|
||||
|
||||
// Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down).
|
||||
// This monitor taps into global event stream and captures these events.
|
||||
NSEventMask eventMask = NSEventMaskFlagsChanged;
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
|
||||
{
|
||||
ImGui_ImplOSX_HandleEvent(event, g_KeyEventResponder);
|
||||
return event;
|
||||
}];
|
||||
|
||||
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||
{
|
||||
if (data->WantVisible)
|
||||
{
|
||||
[g_InputContext activate];
|
||||
}
|
||||
else
|
||||
{
|
||||
[g_InputContext discardMarkedText];
|
||||
[g_InputContext invalidateCharacterCoordinates];
|
||||
[g_InputContext deactivate];
|
||||
}
|
||||
[g_KeyEventResponder setImePosX:data->InputPos.x imePosY:data->InputPos.y + data->InputLineHeight];
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -183,17 +461,9 @@ void ImGui_ImplOSX_Shutdown()
|
||||
g_FocusObserver = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
|
||||
static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
{
|
||||
// Update buttons
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
||||
{
|
||||
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
io.MouseDown[i] = g_MouseJustPressed[i] || g_MouseDown[i];
|
||||
g_MouseJustPressed[i] = false;
|
||||
}
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return;
|
||||
|
||||
@@ -209,8 +479,12 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show OS mouse cursor
|
||||
[g_MouseCursors[g_MouseCursors[imgui_cursor] ? imgui_cursor : ImGuiMouseCursor_Arrow] set];
|
||||
NSCursor* desired = g_MouseCursors[imgui_cursor] ?: g_MouseCursors[ImGuiMouseCursor_Arrow];
|
||||
// -[NSCursor set] generates measureable overhead if called unconditionally.
|
||||
if (desired != NSCursor.currentCursor)
|
||||
{
|
||||
[desired set];
|
||||
}
|
||||
if (g_MouseCursorHidden)
|
||||
{
|
||||
g_MouseCursorHidden = false;
|
||||
@@ -219,6 +493,72 @@ static void ImGui_ImplOSX_UpdateMouseCursorAndButtons()
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
#if APPLE_HAS_CONTROLLER
|
||||
GCController* controller = GCController.current;
|
||||
#else
|
||||
GCController* controller = GCController.controllers.firstObject;
|
||||
#endif
|
||||
if (controller == nil || controller.extendedGamepad == nil)
|
||||
{
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
return;
|
||||
}
|
||||
|
||||
GCExtendedGamepad* gp = controller.extendedGamepad;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NAME) { io.AddKeyEvent(KEY_NO, gp.BUTTON_NAME.isPressed); }
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NAME, V0, V1) { float vn = (float)(gp.AXIS_NAME.value - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
|
||||
const float thumb_dead_zone = 0.0f;
|
||||
|
||||
#if APPLE_HAS_BUTTON_OPTIONS
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, buttonOptions);
|
||||
#endif
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, buttonA); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, buttonB); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, buttonX); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, buttonY); // Xbox Y, PS Triangle
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, dpad.left);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, dpad.right);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, dpad.up);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, dpad.down);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL1, leftShoulder, 0.0f, 1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR1, rightShoulder, 0.0f, 1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, leftTrigger, 0.0f, 1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, rightTrigger, 0.0f, 1.0f);
|
||||
#if APPLE_HAS_THUMBSTICKS
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, leftThumbstickButton);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, rightThumbstickButton);
|
||||
#endif
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, leftThumbstick.xAxis, -thumb_dead_zone, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, leftThumbstick.xAxis, +thumb_dead_zone, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, leftThumbstick.yAxis, +thumb_dead_zone, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, leftThumbstick.yAxis, -thumb_dead_zone, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, rightThumbstick.xAxis, -thumb_dead_zone, -1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, rightThumbstick.xAxis, +thumb_dead_zone, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, rightThumbstick.yAxis, +thumb_dead_zone, +1.0f);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, rightThumbstick.yAxis, -thumb_dead_zone, -1.0f);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.WantTextInput)
|
||||
[g_KeyEventResponder updateImePosWithView:view];
|
||||
}
|
||||
|
||||
void ImGui_ImplOSX_NewFrame(NSView* view)
|
||||
{
|
||||
// Setup display size
|
||||
@@ -232,25 +572,17 @@ void ImGui_ImplOSX_NewFrame(NSView* view)
|
||||
|
||||
// Setup time step
|
||||
if (g_Time == 0.0)
|
||||
g_Time = CFAbsoluteTimeGetCurrent();
|
||||
CFAbsoluteTime current_time = CFAbsoluteTimeGetCurrent();
|
||||
{
|
||||
InitHostClockPeriod();
|
||||
g_Time = GetMachAbsoluteTimeInSeconds();
|
||||
}
|
||||
double current_time = GetMachAbsoluteTimeInSeconds();
|
||||
io.DeltaTime = (float)(current_time - g_Time);
|
||||
g_Time = current_time;
|
||||
|
||||
ImGui_ImplOSX_UpdateMouseCursorAndButtons();
|
||||
}
|
||||
|
||||
static int mapCharacterToKey(int c)
|
||||
{
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 'a' + 'A';
|
||||
if (c == 25) // SHIFT+TAB -> TAB
|
||||
return 9;
|
||||
if (c >= 0 && c < 256)
|
||||
return c;
|
||||
if (c >= 0xF700 && c < 0xF700 + 256)
|
||||
return c - 0xF700 + 256;
|
||||
return -1;
|
||||
ImGui_ImplOSX_UpdateMouseCursor();
|
||||
ImGui_ImplOSX_UpdateGamepads();
|
||||
ImGui_ImplOSX_UpdateImePosWithView(view);
|
||||
}
|
||||
|
||||
bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||
@@ -260,16 +592,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||
if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
|
||||
{
|
||||
int button = (int)[event buttonNumber];
|
||||
if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown))
|
||||
g_MouseDown[button] = g_MouseJustPressed[button] = true;
|
||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||
io.AddMouseButtonEvent(button, true);
|
||||
return io.WantCaptureMouse;
|
||||
}
|
||||
|
||||
if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp)
|
||||
{
|
||||
int button = (int)[event buttonNumber];
|
||||
if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown))
|
||||
g_MouseDown[button] = false;
|
||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||
io.AddMouseButtonEvent(button, false);
|
||||
return io.WantCaptureMouse;
|
||||
}
|
||||
|
||||
@@ -278,11 +610,26 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||
NSPoint mousePoint = event.locationInWindow;
|
||||
mousePoint = [view convertPoint:mousePoint fromView:nil];
|
||||
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
|
||||
io.MousePos = ImVec2((float)mousePoint.x, (float)mousePoint.y);
|
||||
io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
|
||||
}
|
||||
|
||||
if (event.type == NSEventTypeScrollWheel)
|
||||
{
|
||||
// Ignore canceled events.
|
||||
//
|
||||
// From macOS 12.1, scrolling with two fingers and then decelerating
|
||||
// by tapping two fingers results in two events appearing:
|
||||
//
|
||||
// 1. A scroll wheel NSEvent, with a phase == NSEventPhaseMayBegin, when the user taps
|
||||
// two fingers to decelerate or stop the scroll events.
|
||||
//
|
||||
// 2. A scroll wheel NSEvent, with a phase == NSEventPhaseCancelled, when the user releases the
|
||||
// two-finger tap. It is this event that sometimes contains large values for scrollingDeltaX and
|
||||
// scrollingDeltaY. When these are added to the current x and y positions of the scrolling view,
|
||||
// it appears to jump up or down. It can be observed in Preview, various JetBrains IDEs and here.
|
||||
if (event.phase == NSEventPhaseCancelled)
|
||||
return false;
|
||||
|
||||
double wheel_dx = 0.0;
|
||||
double wheel_dy = 0.0;
|
||||
|
||||
@@ -303,65 +650,61 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||
wheel_dx = [event deltaX];
|
||||
wheel_dy = [event deltaY];
|
||||
}
|
||||
if (wheel_dx != 0.0 || wheel_dy != 0.0)
|
||||
io.AddMouseWheelEvent((float)wheel_dx * 0.1f, (float)wheel_dy * 0.1f);
|
||||
|
||||
if (fabs(wheel_dx) > 0.0)
|
||||
io.MouseWheelH += (float)wheel_dx * 0.1f;
|
||||
if (fabs(wheel_dy) > 0.0)
|
||||
io.MouseWheel += (float)wheel_dy * 0.1f;
|
||||
return io.WantCaptureMouse;
|
||||
}
|
||||
|
||||
// FIXME: All the key handling is wrong and broken. Refer to GLFW's cocoa_init.mm and cocoa_window.mm.
|
||||
if (event.type == NSEventTypeKeyDown)
|
||||
if (event.type == NSEventTypeKeyDown || event.type == NSEventTypeKeyUp)
|
||||
{
|
||||
NSString* str = [event characters];
|
||||
NSUInteger len = [str length];
|
||||
for (NSUInteger i = 0; i < len; i++)
|
||||
{
|
||||
int c = [str characterAtIndex:i];
|
||||
if (!io.KeySuper && !(c >= 0xF700 && c <= 0xFFFF) && c != 127)
|
||||
io.AddInputCharacter((unsigned int)c);
|
||||
if ([event isARepeat])
|
||||
return io.WantCaptureKeyboard;
|
||||
|
||||
// We must reset in case we're pressing a sequence of special keys while keeping the command pressed
|
||||
int key = mapCharacterToKey(c);
|
||||
if (key != -1 && key < 256 && !io.KeySuper)
|
||||
resetKeys();
|
||||
if (key != -1)
|
||||
io.KeysDown[key] = true;
|
||||
}
|
||||
return io.WantCaptureKeyboard;
|
||||
}
|
||||
int key_code = (int)[event keyCode];
|
||||
ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
|
||||
io.AddKeyEvent(key, event.type == NSEventTypeKeyDown);
|
||||
io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
|
||||
|
||||
if (event.type == NSEventTypeKeyUp)
|
||||
{
|
||||
NSString* str = [event characters];
|
||||
NSUInteger len = [str length];
|
||||
for (NSUInteger i = 0; i < len; i++)
|
||||
{
|
||||
int c = [str characterAtIndex:i];
|
||||
int key = mapCharacterToKey(c);
|
||||
if (key != -1)
|
||||
io.KeysDown[key] = false;
|
||||
}
|
||||
return io.WantCaptureKeyboard;
|
||||
}
|
||||
|
||||
if (event.type == NSEventTypeFlagsChanged)
|
||||
{
|
||||
unsigned int flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
unsigned short key_code = [event keyCode];
|
||||
NSEventModifierFlags modifier_flags = [event modifierFlags];
|
||||
|
||||
bool oldKeyCtrl = io.KeyCtrl;
|
||||
bool oldKeyShift = io.KeyShift;
|
||||
bool oldKeyAlt = io.KeyAlt;
|
||||
bool oldKeySuper = io.KeySuper;
|
||||
io.KeyCtrl = flags & NSEventModifierFlagControl;
|
||||
io.KeyShift = flags & NSEventModifierFlagShift;
|
||||
io.KeyAlt = flags & NSEventModifierFlagOption;
|
||||
io.KeySuper = flags & NSEventModifierFlagCommand;
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, (modifier_flags & NSEventModifierFlagShift) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, (modifier_flags & NSEventModifierFlagControl) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, (modifier_flags & NSEventModifierFlagOption) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModSuper, (modifier_flags & NSEventModifierFlagCommand) != 0);
|
||||
|
||||
ImGuiKey key = ImGui_ImplOSX_KeyCodeToImGuiKey(key_code);
|
||||
if (key != ImGuiKey_None)
|
||||
{
|
||||
// macOS does not generate down/up event for modifiers. We're trying
|
||||
// to use hardware dependent masks to extract that information.
|
||||
// 'imgui_mask' is left as a fallback.
|
||||
NSEventModifierFlags mask = 0;
|
||||
switch (key)
|
||||
{
|
||||
case ImGuiKey_LeftCtrl: mask = 0x0001; break;
|
||||
case ImGuiKey_RightCtrl: mask = 0x2000; break;
|
||||
case ImGuiKey_LeftShift: mask = 0x0002; break;
|
||||
case ImGuiKey_RightShift: mask = 0x0004; break;
|
||||
case ImGuiKey_LeftSuper: mask = 0x0008; break;
|
||||
case ImGuiKey_RightSuper: mask = 0x0010; break;
|
||||
case ImGuiKey_LeftAlt: mask = 0x0020; break;
|
||||
case ImGuiKey_RightAlt: mask = 0x0040; break;
|
||||
default:
|
||||
return io.WantCaptureKeyboard;
|
||||
}
|
||||
|
||||
NSEventModifierFlags modifier_flags = [event modifierFlags];
|
||||
io.AddKeyEvent(key, (modifier_flags & mask) != 0);
|
||||
io.SetKeyEventNativeData(key, key_code, -1); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
|
||||
// We must reset them as we will not receive any keyUp event if they where pressed with a modifier
|
||||
if ((oldKeyShift && !io.KeyShift) || (oldKeyCtrl && !io.KeyCtrl) || (oldKeyAlt && !io.KeyAlt) || (oldKeySuper && !io.KeySuper))
|
||||
resetKeys();
|
||||
return io.WantCaptureKeyboard;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
// (Prefer SDL 2.0.5+ for full feature support.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
|
||||
// [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: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -18,9 +20,18 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer.
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
|
||||
// 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
|
||||
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
|
||||
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
||||
// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
|
||||
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
|
||||
@@ -54,10 +65,11 @@
|
||||
#include "imgui_impl_sdl.h"
|
||||
|
||||
// SDL
|
||||
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,4) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IOS)
|
||||
@@ -66,17 +78,28 @@
|
||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||
#endif
|
||||
#define SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5)
|
||||
#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4)
|
||||
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
||||
#if !SDL_HAS_VULKAN
|
||||
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
||||
#endif
|
||||
|
||||
// SDL Data
|
||||
struct ImGui_ImplSDL2_Data
|
||||
{
|
||||
SDL_Window* Window;
|
||||
Uint64 Time;
|
||||
bool MousePressed[3];
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
SDL_Window* Window;
|
||||
SDL_Renderer* Renderer;
|
||||
Uint64 Time;
|
||||
Uint32 MouseWindowID;
|
||||
int MouseButtonsDown;
|
||||
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
int PendingMouseLeaveFrame;
|
||||
char* ClipboardTextData;
|
||||
bool MouseCanUseGlobalState;
|
||||
bool UseVulkan;
|
||||
|
||||
ImGui_ImplSDL2_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -90,6 +113,11 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplSDL2_UpdateMonitors();
|
||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context);
|
||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplSDL2_GetClipboardText(void*)
|
||||
{
|
||||
@@ -105,6 +133,128 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
|
||||
SDL_SetClipboardText(text);
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
|
||||
{
|
||||
switch (keycode)
|
||||
{
|
||||
case SDLK_TAB: return ImGuiKey_Tab;
|
||||
case SDLK_LEFT: return ImGuiKey_LeftArrow;
|
||||
case SDLK_RIGHT: return ImGuiKey_RightArrow;
|
||||
case SDLK_UP: return ImGuiKey_UpArrow;
|
||||
case SDLK_DOWN: return ImGuiKey_DownArrow;
|
||||
case SDLK_PAGEUP: return ImGuiKey_PageUp;
|
||||
case SDLK_PAGEDOWN: return ImGuiKey_PageDown;
|
||||
case SDLK_HOME: return ImGuiKey_Home;
|
||||
case SDLK_END: return ImGuiKey_End;
|
||||
case SDLK_INSERT: return ImGuiKey_Insert;
|
||||
case SDLK_DELETE: return ImGuiKey_Delete;
|
||||
case SDLK_BACKSPACE: return ImGuiKey_Backspace;
|
||||
case SDLK_SPACE: return ImGuiKey_Space;
|
||||
case SDLK_RETURN: return ImGuiKey_Enter;
|
||||
case SDLK_ESCAPE: return ImGuiKey_Escape;
|
||||
case SDLK_QUOTE: return ImGuiKey_Apostrophe;
|
||||
case SDLK_COMMA: return ImGuiKey_Comma;
|
||||
case SDLK_MINUS: return ImGuiKey_Minus;
|
||||
case SDLK_PERIOD: return ImGuiKey_Period;
|
||||
case SDLK_SLASH: return ImGuiKey_Slash;
|
||||
case SDLK_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SDLK_EQUALS: return ImGuiKey_Equal;
|
||||
case SDLK_LEFTBRACKET: return ImGuiKey_LeftBracket;
|
||||
case SDLK_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SDLK_RIGHTBRACKET: return ImGuiKey_RightBracket;
|
||||
case SDLK_BACKQUOTE: return ImGuiKey_GraveAccent;
|
||||
case SDLK_CAPSLOCK: return ImGuiKey_CapsLock;
|
||||
case SDLK_SCROLLLOCK: return ImGuiKey_ScrollLock;
|
||||
case SDLK_NUMLOCKCLEAR: return ImGuiKey_NumLock;
|
||||
case SDLK_PRINTSCREEN: return ImGuiKey_PrintScreen;
|
||||
case SDLK_PAUSE: return ImGuiKey_Pause;
|
||||
case SDLK_KP_0: return ImGuiKey_Keypad0;
|
||||
case SDLK_KP_1: return ImGuiKey_Keypad1;
|
||||
case SDLK_KP_2: return ImGuiKey_Keypad2;
|
||||
case SDLK_KP_3: return ImGuiKey_Keypad3;
|
||||
case SDLK_KP_4: return ImGuiKey_Keypad4;
|
||||
case SDLK_KP_5: return ImGuiKey_Keypad5;
|
||||
case SDLK_KP_6: return ImGuiKey_Keypad6;
|
||||
case SDLK_KP_7: return ImGuiKey_Keypad7;
|
||||
case SDLK_KP_8: return ImGuiKey_Keypad8;
|
||||
case SDLK_KP_9: return ImGuiKey_Keypad9;
|
||||
case SDLK_KP_PERIOD: return ImGuiKey_KeypadDecimal;
|
||||
case SDLK_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case SDLK_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case SDLK_KP_MINUS: return ImGuiKey_KeypadSubtract;
|
||||
case SDLK_KP_PLUS: return ImGuiKey_KeypadAdd;
|
||||
case SDLK_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case SDLK_KP_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
case SDLK_LCTRL: return ImGuiKey_LeftCtrl;
|
||||
case SDLK_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case SDLK_LALT: return ImGuiKey_LeftAlt;
|
||||
case SDLK_LGUI: return ImGuiKey_LeftSuper;
|
||||
case SDLK_RCTRL: return ImGuiKey_RightCtrl;
|
||||
case SDLK_RSHIFT: return ImGuiKey_RightShift;
|
||||
case SDLK_RALT: return ImGuiKey_RightAlt;
|
||||
case SDLK_RGUI: return ImGuiKey_RightSuper;
|
||||
case SDLK_APPLICATION: return ImGuiKey_Menu;
|
||||
case SDLK_0: return ImGuiKey_0;
|
||||
case SDLK_1: return ImGuiKey_1;
|
||||
case SDLK_2: return ImGuiKey_2;
|
||||
case SDLK_3: return ImGuiKey_3;
|
||||
case SDLK_4: return ImGuiKey_4;
|
||||
case SDLK_5: return ImGuiKey_5;
|
||||
case SDLK_6: return ImGuiKey_6;
|
||||
case SDLK_7: return ImGuiKey_7;
|
||||
case SDLK_8: return ImGuiKey_8;
|
||||
case SDLK_9: return ImGuiKey_9;
|
||||
case SDLK_a: return ImGuiKey_A;
|
||||
case SDLK_b: return ImGuiKey_B;
|
||||
case SDLK_c: return ImGuiKey_C;
|
||||
case SDLK_d: return ImGuiKey_D;
|
||||
case SDLK_e: return ImGuiKey_E;
|
||||
case SDLK_f: return ImGuiKey_F;
|
||||
case SDLK_g: return ImGuiKey_G;
|
||||
case SDLK_h: return ImGuiKey_H;
|
||||
case SDLK_i: return ImGuiKey_I;
|
||||
case SDLK_j: return ImGuiKey_J;
|
||||
case SDLK_k: return ImGuiKey_K;
|
||||
case SDLK_l: return ImGuiKey_L;
|
||||
case SDLK_m: return ImGuiKey_M;
|
||||
case SDLK_n: return ImGuiKey_N;
|
||||
case SDLK_o: return ImGuiKey_O;
|
||||
case SDLK_p: return ImGuiKey_P;
|
||||
case SDLK_q: return ImGuiKey_Q;
|
||||
case SDLK_r: return ImGuiKey_R;
|
||||
case SDLK_s: return ImGuiKey_S;
|
||||
case SDLK_t: return ImGuiKey_T;
|
||||
case SDLK_u: return ImGuiKey_U;
|
||||
case SDLK_v: return ImGuiKey_V;
|
||||
case SDLK_w: return ImGuiKey_W;
|
||||
case SDLK_x: return ImGuiKey_X;
|
||||
case SDLK_y: return ImGuiKey_Y;
|
||||
case SDLK_z: return ImGuiKey_Z;
|
||||
case SDLK_F1: return ImGuiKey_F1;
|
||||
case SDLK_F2: return ImGuiKey_F2;
|
||||
case SDLK_F3: return ImGuiKey_F3;
|
||||
case SDLK_F4: return ImGuiKey_F4;
|
||||
case SDLK_F5: return ImGuiKey_F5;
|
||||
case SDLK_F6: return ImGuiKey_F6;
|
||||
case SDLK_F7: return ImGuiKey_F7;
|
||||
case SDLK_F8: return ImGuiKey_F8;
|
||||
case SDLK_F9: return ImGuiKey_F9;
|
||||
case SDLK_F10: return ImGuiKey_F10;
|
||||
case SDLK_F11: return ImGuiKey_F11;
|
||||
case SDLK_F12: return ImGuiKey_F12;
|
||||
}
|
||||
return ImGuiKey_None;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, (sdl_key_mods & KMOD_CTRL) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, (sdl_key_mods & KMOD_SHIFT) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, (sdl_key_mods & KMOD_ALT) != 0);
|
||||
io.AddKeyEvent(ImGuiKey_ModSuper, (sdl_key_mods & KMOD_GUI) != 0);
|
||||
}
|
||||
|
||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
@@ -117,55 +267,90 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_MOUSEWHEEL:
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
if (event->wheel.x > 0) io.MouseWheelH += 1;
|
||||
if (event->wheel.x < 0) io.MouseWheelH -= 1;
|
||||
if (event->wheel.y > 0) io.MouseWheel += 1;
|
||||
if (event->wheel.y < 0) io.MouseWheel -= 1;
|
||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
int window_x, window_y;
|
||||
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
|
||||
mouse_pos.x += window_x;
|
||||
mouse_pos.y += window_y;
|
||||
}
|
||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||
return true;
|
||||
}
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEWHEEL:
|
||||
{
|
||||
if (event->button.button == SDL_BUTTON_LEFT) { bd->MousePressed[0] = true; }
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) { bd->MousePressed[1] = true; }
|
||||
if (event->button.button == SDL_BUTTON_MIDDLE) { bd->MousePressed[2] = true; }
|
||||
float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f;
|
||||
float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f;
|
||||
io.AddMouseWheelEvent(wheel_x, wheel_y);
|
||||
return true;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
int mouse_button = -1;
|
||||
if (event->button.button == SDL_BUTTON_LEFT) { mouse_button = 0; }
|
||||
if (event->button.button == SDL_BUTTON_RIGHT) { mouse_button = 1; }
|
||||
if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; }
|
||||
if (mouse_button == -1)
|
||||
break;
|
||||
io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN));
|
||||
bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button));
|
||||
return true;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
{
|
||||
io.AddInputCharactersUTF8(event->text.text);
|
||||
return true;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
int key = event->key.keysym.scancode;
|
||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
||||
io.KeysDown[key] = (event->type == SDL_KEYDOWN);
|
||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
||||
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
|
||||
#ifdef _WIN32
|
||||
io.KeySuper = false;
|
||||
#else
|
||||
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
|
||||
#endif
|
||||
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
|
||||
ImGuiKey key = ImGui_ImplSDL2_KeycodeToImGuiKey(event->key.keysym.sym);
|
||||
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.
|
||||
return true;
|
||||
}
|
||||
case SDL_WINDOWEVENT:
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
|
||||
// - However we won't get a correct LEAVE event for a captured window.
|
||||
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
|
||||
// causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
|
||||
// we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
|
||||
Uint8 window_event = event->window.event;
|
||||
if (window_event == SDL_WINDOWEVENT_ENTER)
|
||||
{
|
||||
bd->MouseWindowID = event->window.windowID;
|
||||
bd->PendingMouseLeaveFrame = 0;
|
||||
}
|
||||
if (window_event == SDL_WINDOWEVENT_LEAVE)
|
||||
bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||
io.AddFocusEvent(true);
|
||||
else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||
io.AddFocusEvent(false);
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE || window_event == SDL_WINDOWEVENT_MOVED || window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)SDL_GetWindowFromID(event->window.windowID)))
|
||||
{
|
||||
if (window_event == SDL_WINDOWEVENT_CLOSE)
|
||||
viewport->PlatformRequestClose = true;
|
||||
if (window_event == SDL_WINDOWEVENT_MOVED)
|
||||
viewport->PlatformRequestMove = true;
|
||||
if (window_event == SDL_WINDOWEVENT_RESIZED)
|
||||
viewport->PlatformRequestResize = true;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window)
|
||||
static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
|
||||
@@ -185,36 +370,21 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
|
||||
ImGui_ImplSDL2_Data* bd = IM_NEW(ImGui_ImplSDL2_Data)();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
io.BackendPlatformName = "imgui_impl_sdl";
|
||||
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_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
if (mouse_can_use_global_state)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
|
||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
||||
#ifndef __APPLE__
|
||||
if (mouse_can_use_global_state)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;// We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
#endif
|
||||
|
||||
bd->Window = window;
|
||||
bd->Renderer = renderer;
|
||||
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||
io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP;
|
||||
io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN;
|
||||
io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = SDL_SCANCODE_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = SDL_SCANCODE_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDL_SCANCODE_BACKSPACE;
|
||||
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_KP_ENTER;
|
||||
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
||||
io.KeyMap[ImGuiKey_X] = SDL_SCANCODE_X;
|
||||
io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y;
|
||||
io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
|
||||
io.ClipboardUserData = NULL;
|
||||
@@ -230,13 +400,15 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
|
||||
bd->MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
|
||||
// Set platform dependent data in viewport
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = (void*)window;
|
||||
#ifdef _WIN32
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(window, &info))
|
||||
io.ImeWindowHandle = info.info.win.window;
|
||||
#else
|
||||
(void)window;
|
||||
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
|
||||
#endif
|
||||
|
||||
// Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
|
||||
@@ -248,13 +420,20 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window)
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
#endif
|
||||
|
||||
// Update monitors
|
||||
ImGui_ImplSDL2_UpdateMonitors();
|
||||
|
||||
// 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.
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports))
|
||||
ImGui_ImplSDL2_InitPlatformInterface(window, sdl_gl_context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
|
||||
return ImGui_ImplSDL2_Init(window);
|
||||
return ImGui_ImplSDL2_Init(window, NULL, sdl_gl_context);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
||||
@@ -262,7 +441,11 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
||||
#if !SDL_HAS_VULKAN
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window);
|
||||
if (!ImGui_ImplSDL2_Init(window, NULL, NULL))
|
||||
return false;
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
bd->UseVulkan = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||
@@ -270,18 +453,26 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||
#if !defined(_WIN32)
|
||||
IM_ASSERT(0 && "Unsupported");
|
||||
#endif
|
||||
return ImGui_ImplSDL2_Init(window);
|
||||
return ImGui_ImplSDL2_Init(window, NULL, NULL);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window);
|
||||
return ImGui_ImplSDL2_Init(window, NULL, NULL);
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
|
||||
{
|
||||
return ImGui_ImplSDL2_Init(window, renderer, NULL);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDL2_ShutdownPlatformInterface();
|
||||
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
@@ -293,60 +484,67 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
|
||||
// This code is incredibly messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
|
||||
static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImVec2 mouse_pos_prev = io.MousePos;
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
|
||||
// Update mouse buttons
|
||||
int mouse_x_local, mouse_y_local;
|
||||
Uint32 mouse_buttons = SDL_GetMouseState(&mouse_x_local, &mouse_y_local);
|
||||
io.MouseDown[0] = bd->MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
io.MouseDown[1] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
|
||||
io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0;
|
||||
bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false;
|
||||
|
||||
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
|
||||
// We forward mouse input when hovered or captured (via SDL_MOUSEMOTION) or when focused (below)
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
SDL_Window* hovered_window = SDL_HAS_MOUSE_FOCUS_CLICKTHROUGH ? SDL_GetMouseFocus() : NULL; // This is better but is only reliably useful with SDL 2.0.5+ and SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH.
|
||||
SDL_Window* mouse_window = NULL;
|
||||
if (hovered_window && bd->Window == hovered_window)
|
||||
mouse_window = hovered_window;
|
||||
else if (focused_window && bd->Window == focused_window)
|
||||
mouse_window = focused_window;
|
||||
|
||||
// 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(ImGui::IsAnyMouseDown() ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_CaptureMouse(bd->MouseButtonsDown != 0 ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
#else
|
||||
// SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||
SDL_Window* mouse_window = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) ? bd->Window : NULL;
|
||||
SDL_Window* focused_window = bd->Window;
|
||||
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||
#endif
|
||||
|
||||
if (mouse_window == NULL)
|
||||
return;
|
||||
|
||||
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)mouse_pos_prev.x, (int)mouse_pos_prev.y);
|
||||
|
||||
// Set Dear ImGui mouse position from OS position + get buttons. (this is the common behavior)
|
||||
if (bd->MouseCanUseGlobalState)
|
||||
if (is_app_focused)
|
||||
{
|
||||
// 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)
|
||||
// Unlike local position obtained earlier this will be valid when straying out of bounds.
|
||||
int mouse_x_global, mouse_y_global;
|
||||
SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global);
|
||||
int window_x, window_y;
|
||||
SDL_GetWindowPosition(mouse_window, &window_x, &window_y);
|
||||
io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y));
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y);
|
||||
else
|
||||
#endif
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
int mouse_x, mouse_y, window_x, window_y;
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||
mouse_x -= window_x;
|
||||
mouse_y -= window_y;
|
||||
}
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
||||
{
|
||||
io.MousePos = ImVec2((float)mouse_x_local, (float)mouse_y_local);
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (SDL_Window* sdl_mouse_window = SDL_GetWindowFromID(bd->MouseWindowID))
|
||||
if (ImGuiViewport* mouse_viewport = ImGui::FindViewportByPlatformHandle((void*)sdl_mouse_window))
|
||||
mouse_viewport_id = mouse_viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,44 +572,77 @@ static void ImGui_ImplSDL2_UpdateMouseCursor()
|
||||
static void ImGui_ImplSDL2_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Get gamepad
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
SDL_GameController* game_controller = SDL_GameControllerOpen(0);
|
||||
if (!game_controller)
|
||||
{
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
return;
|
||||
}
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_NO) { io.NavInputs[NAV_NO] = (SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0) ? 1.0f : 0.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_NO) { io.AddKeyEvent(KEY_NO, SDL_GameControllerGetButton(game_controller, BUTTON_NO) != 0); }
|
||||
#define MAP_ANALOG(KEY_NO, AXIS_NO, V0, V1) { float vn = (float)(SDL_GameControllerGetAxis(game_controller, AXIS_NO) - V0) / (float)(V1 - V0); vn = IM_SATURATE(vn); io.AddKeyAnalogEvent(KEY_NO, vn > 0.1f, vn); }
|
||||
const int thumb_dead_zone = 8000; // SDL_gamecontroller.h suggests using this value.
|
||||
MAP_BUTTON(ImGuiNavInput_Activate, SDL_CONTROLLER_BUTTON_A); // Cross / A
|
||||
MAP_BUTTON(ImGuiNavInput_Cancel, SDL_CONTROLLER_BUTTON_B); // Circle / B
|
||||
MAP_BUTTON(ImGuiNavInput_Menu, SDL_CONTROLLER_BUTTON_X); // Square / X
|
||||
MAP_BUTTON(ImGuiNavInput_Input, SDL_CONTROLLER_BUTTON_Y); // Triangle / Y
|
||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT); // D-Pad Left
|
||||
MAP_BUTTON(ImGuiNavInput_DpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); // D-Pad Right
|
||||
MAP_BUTTON(ImGuiNavInput_DpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP); // D-Pad Up
|
||||
MAP_BUTTON(ImGuiNavInput_DpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN); // D-Pad Down
|
||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_FocusNext, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, SDL_CONTROLLER_BUTTON_LEFTSHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakFast, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); // R1 / RB
|
||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, SDL_CONTROLLER_BUTTON_START);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, SDL_CONTROLLER_BUTTON_BACK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, SDL_CONTROLLER_BUTTON_A); // Xbox A, PS Cross
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, SDL_CONTROLLER_BUTTON_B); // Xbox B, PS Circle
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, SDL_CONTROLLER_BUTTON_X); // Xbox X, PS Square
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, SDL_CONTROLLER_BUTTON_Y); // Xbox Y, PS Triangle
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, SDL_CONTROLLER_BUTTON_DPAD_UP);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0.0f, 32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0.0f, 32767);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, SDL_CONTROLLER_BUTTON_LEFTSTICK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, SDL_CONTROLLER_BUTTON_RIGHTSTICK);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, SDL_CONTROLLER_AXIS_LEFTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, SDL_CONTROLLER_AXIS_LEFTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, SDL_CONTROLLER_AXIS_LEFTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, SDL_CONTROLLER_AXIS_LEFTY, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, SDL_CONTROLLER_AXIS_RIGHTX, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, SDL_CONTROLLER_AXIS_RIGHTX, +thumb_dead_zone, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, SDL_CONTROLLER_AXIS_RIGHTY, -thumb_dead_zone, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
|
||||
// FIXME-PLATFORM: SDL doesn't have an event to notify the application of display/monitor changes
|
||||
static void ImGui_ImplSDL2_UpdateMonitors()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Monitors.resize(0);
|
||||
int display_count = SDL_GetNumVideoDisplays();
|
||||
for (int n = 0; n < display_count; n++)
|
||||
{
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
ImGuiPlatformMonitor monitor;
|
||||
SDL_Rect r;
|
||||
SDL_GetDisplayBounds(n, &r);
|
||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
||||
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
|
||||
SDL_GetDisplayUsableBounds(n, &r);
|
||||
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
|
||||
float dpi = 0.0f;
|
||||
if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL))
|
||||
monitor.DpiScale = dpi / 96.0f;
|
||||
#endif
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL2_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
@@ -424,7 +655,10 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
SDL_GetWindowSize(bd->Window, &w, &h);
|
||||
if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED)
|
||||
w = h = 0;
|
||||
SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
|
||||
if (bd->Renderer != NULL)
|
||||
SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h);
|
||||
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);
|
||||
@@ -435,9 +669,257 @@ void ImGui_ImplSDL2_NewFrame()
|
||||
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
ImGui_ImplSDL2_UpdateMousePosAndButtons();
|
||||
if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame == ImGui::GetFrameCount())
|
||||
{
|
||||
bd->MouseWindowID = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
|
||||
ImGui_ImplSDL2_UpdateMouseData();
|
||||
ImGui_ImplSDL2_UpdateMouseCursor();
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
ImGui_ImplSDL2_UpdateGamepads();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplSDL2_ViewportData
|
||||
{
|
||||
SDL_Window* Window;
|
||||
Uint32 WindowID;
|
||||
bool WindowOwned;
|
||||
SDL_GLContext GLContext;
|
||||
|
||||
ImGui_ImplSDL2_ViewportData() { Window = NULL; WindowID = 0; WindowOwned = false; GLContext = NULL; }
|
||||
~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == NULL && GLContext == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData;
|
||||
|
||||
// Share GL resources with main context
|
||||
bool use_opengl = (main_viewport_data->GLContext != NULL);
|
||||
SDL_GLContext backup_context = NULL;
|
||||
if (use_opengl)
|
||||
{
|
||||
backup_context = SDL_GL_GetCurrentContext();
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
||||
}
|
||||
|
||||
Uint32 sdl_flags = 0;
|
||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->UseVulkan ? SDL_WINDOW_VULKAN : 0);
|
||||
sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
sdl_flags |= SDL_WINDOW_HIDDEN;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
||||
#if !defined(_WIN32)
|
||||
// See SDL hack in ImGui_ImplSDL2_ShowWindow().
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0;
|
||||
#endif
|
||||
#if SDL_HAS_ALWAYS_ON_TOP
|
||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
|
||||
#endif
|
||||
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
||||
vd->WindowOwned = true;
|
||||
if (use_opengl)
|
||||
{
|
||||
vd->GLContext = SDL_GL_CreateContext(vd->Window);
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
}
|
||||
if (use_opengl && backup_context)
|
||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
||||
|
||||
viewport->PlatformHandle = (void*)vd->Window;
|
||||
#if defined(_WIN32)
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(vd->Window, &info))
|
||||
viewport->PlatformHandleRaw = info.info.win.window;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (vd->GLContext && vd->WindowOwned)
|
||||
SDL_GL_DeleteContext(vd->GLContext);
|
||||
if (vd->Window && vd->WindowOwned)
|
||||
SDL_DestroyWindow(vd->Window);
|
||||
vd->GLContext = NULL;
|
||||
vd->Window = NULL;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
#if defined(_WIN32)
|
||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
||||
|
||||
// SDL hack: Hide icon from task bar
|
||||
// Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
{
|
||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
ex_style &= ~WS_EX_APPWINDOW;
|
||||
ex_style |= WS_EX_TOOLWINDOW;
|
||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
|
||||
// SDL hack: SDL always activate/focus windows :/
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
{
|
||||
::ShowWindow(hwnd, SW_SHOWNA);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_ShowWindow(vd->Window);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
int x = 0, y = 0;
|
||||
SDL_GetWindowPosition(vd->Window, &x, &y);
|
||||
return ImVec2((float)x, (float)y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
int w = 0, h = 0;
|
||||
SDL_GetWindowSize(vd->Window, &w, &h);
|
||||
return ImVec2((float)w, (float)h);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowTitle(vd->Window, title);
|
||||
}
|
||||
|
||||
#if SDL_HAS_WINDOW_ALPHA
|
||||
static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_SetWindowOpacity(vd->Window, alpha);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
SDL_RaiseWindow(vd->Window);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
if (vd->GLContext)
|
||||
{
|
||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
||||
SDL_GL_SwapWindow(vd->Window);
|
||||
}
|
||||
}
|
||||
|
||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
||||
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
|
||||
#if SDL_HAS_VULKAN
|
||||
#include <SDL_vulkan.h>
|
||||
static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
||||
{
|
||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
||||
(void)vk_allocator;
|
||||
SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface);
|
||||
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
||||
}
|
||||
#endif // SDL_HAS_VULKAN
|
||||
|
||||
static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_gl_context)
|
||||
{
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle;
|
||||
platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow;
|
||||
platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers;
|
||||
#if SDL_HAS_WINDOW_ALPHA
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha;
|
||||
#endif
|
||||
#if SDL_HAS_VULKAN
|
||||
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface;
|
||||
#endif
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
||||
vd->Window = window;
|
||||
vd->WindowID = SDL_GetWindowID(window);
|
||||
vd->WindowOwned = false;
|
||||
vd->GLContext = sdl_gl_context;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = vd->Window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDL2_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Keyboard arrays indexed using SDL_SCANCODE_* codes, e.g. ImGui::IsKeyPressed(SDL_SCANCODE_SPACE).
|
||||
// [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: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features:
|
||||
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
|
||||
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
|
||||
// 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.
|
||||
@@ -19,12 +21,14 @@
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
249
backends/imgui_impl_sdlrenderer.cpp
Normal file
249
backends/imgui_impl_sdlrenderer.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Important to understand: SDL_Renderer is an _optional_ component of SDL.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer offers a limited graphic API to the end-user and it might
|
||||
// be difficult to step out of those boundaries.
|
||||
// However, we understand it is a convenient choice to get an app started easily.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19.
|
||||
// 2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2021-10-06: Backup and restore modified ClipRect/Viewport.
|
||||
// 2021-09-21: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdlrenderer.h"
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL.h>
|
||||
#if !SDL_VERSION_ATLEAST(2,0,17)
|
||||
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
||||
#endif
|
||||
|
||||
// SDL_Renderer data
|
||||
struct ImGui_ImplSDLRenderer_Data
|
||||
{
|
||||
SDL_Renderer* SDLRenderer;
|
||||
SDL_Texture* FontTexture;
|
||||
ImGui_ImplSDLRenderer_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// 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.
|
||||
static ImGui_ImplSDLRenderer_Data* ImGui_ImplSDLRenderer_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplSDLRenderer_Init(SDL_Renderer* renderer)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(renderer != NULL && "SDL_Renderer not initialized!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplSDLRenderer_Data* bd = IM_NEW(ImGui_ImplSDLRenderer_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlrenderer";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->SDLRenderer = renderer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDLRenderer_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLRenderer_SetupRenderState()
|
||||
{
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
|
||||
// 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.
|
||||
SDL_RenderSetViewport(bd->SDLRenderer, NULL);
|
||||
SDL_RenderSetClipRect(bd->SDLRenderer, NULL);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplSDLRenderer_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplSDLRenderer_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
|
||||
// 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
|
||||
// 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 rsy = 1.0f;
|
||||
SDL_RenderGetScale(bd->SDLRenderer, &rsx, &rsy);
|
||||
ImVec2 render_scale;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 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)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||
struct BackupSDLRendererState
|
||||
{
|
||||
SDL_Rect Viewport;
|
||||
bool ClipEnabled;
|
||||
SDL_Rect ClipRect;
|
||||
};
|
||||
BackupSDLRendererState old = {};
|
||||
old.ClipEnabled = SDL_RenderIsClipEnabled(bd->SDLRenderer) == SDL_TRUE;
|
||||
SDL_RenderGetViewport(bd->SDLRenderer, &old.Viewport);
|
||||
SDL_RenderGetClipRect(bd->SDLRenderer, &old.ClipRect);
|
||||
|
||||
// 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
|
||||
ImGui_ImplSDLRenderer_SetupRenderState();
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// 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_ImplSDLRenderer_SetupRenderState();
|
||||
else
|
||||
pcmd->UserCallback(cmd_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);
|
||||
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;
|
||||
|
||||
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
||||
SDL_RenderSetClipRect(bd->SDLRenderer, &r);
|
||||
|
||||
const float* xy = (const float*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, pos));
|
||||
const float* uv = (const float*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, uv));
|
||||
#if SDL_VERSION_ATLEAST(2,0,19)
|
||||
const SDL_Color* color = (const SDL_Color*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.19+
|
||||
#else
|
||||
const int* color = (const int*)((const char*)(vtx_buffer + pcmd->VtxOffset) + IM_OFFSETOF(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
|
||||
#endif
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw(bd->SDLRenderer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
uv, (int)sizeof(ImDrawVert),
|
||||
cmd_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_RenderSetViewport(bd->SDLRenderer, &old.Viewport);
|
||||
SDL_RenderSetClipRect(bd->SDLRenderer, old.ClipEnabled ? &old.ClipRect : NULL);
|
||||
}
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
bool ImGui_ImplSDLRenderer_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
|
||||
// Build texture atlas
|
||||
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
|
||||
bd->FontTexture = SDL_CreateTexture(bd->SDLRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (bd->FontTexture == NULL)
|
||||
{
|
||||
SDL_Log("error creating texture");
|
||||
return false;
|
||||
}
|
||||
SDL_UpdateTexture(bd->FontTexture, NULL, pixels, 4 * width);
|
||||
SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer_Data* bd = ImGui_ImplSDLRenderer_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
io.Fonts->SetTexID(0);
|
||||
SDL_DestroyTexture(bd->FontTexture);
|
||||
bd->FontTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLRenderer_CreateDeviceObjects()
|
||||
{
|
||||
return ImGui_ImplSDLRenderer_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
||||
}
|
||||
31
backends/imgui_impl_sdlrenderer.h
Normal file
31
backends/imgui_impl_sdlrenderer.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Important to understand: SDL_Renderer is an _optional_ component of SDL.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
// If your application will want to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer offers a limited graphic API to the end-user and it might
|
||||
// be difficult to step out of those boundaries.
|
||||
// However, we understand it is a convenient choice to get an app started easily.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct SDL_Renderer;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_Init(SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer_DestroyDeviceObjects();
|
||||
@@ -3,8 +3,16 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this backend! See https://github.com/ocornut/imgui/pull/914
|
||||
// [x] Platform: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// To build this on 32-bit systems and support texture changes:
|
||||
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in our .vcxproj files)
|
||||
// - [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 our batch files)
|
||||
|
||||
// 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.
|
||||
@@ -23,6 +31,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2021-10-15: Vulkan: Call vkCmdSetScissor() at the end of render a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize.
|
||||
// 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer.
|
||||
@@ -56,6 +66,11 @@
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4127) // condition expression is constant
|
||||
#endif
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplVulkan_RenderDrawData()
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_FrameRenderBuffers
|
||||
@@ -77,6 +92,18 @@ struct ImGui_ImplVulkanH_WindowRenderBuffers
|
||||
ImGui_ImplVulkanH_FrameRenderBuffers* FrameRenderBuffers;
|
||||
};
|
||||
|
||||
// For multi-viewport support:
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplVulkan_ViewportData
|
||||
{
|
||||
bool WindowOwned;
|
||||
ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
||||
|
||||
ImGui_ImplVulkan_ViewportData() { WindowOwned = false; memset(&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
||||
~ImGui_ImplVulkan_ViewportData() { }
|
||||
};
|
||||
|
||||
// Vulkan data
|
||||
struct ImGui_ImplVulkan_Data
|
||||
{
|
||||
@@ -86,7 +113,6 @@ struct ImGui_ImplVulkan_Data
|
||||
VkPipelineCreateFlags PipelineCreateFlags;
|
||||
VkDescriptorSetLayout DescriptorSetLayout;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkDescriptorSet DescriptorSet;
|
||||
VkPipeline Pipeline;
|
||||
uint32_t Subpass;
|
||||
VkShaderModule ShaderModuleVert;
|
||||
@@ -97,10 +123,11 @@ struct ImGui_ImplVulkan_Data
|
||||
VkDeviceMemory FontMemory;
|
||||
VkImage FontImage;
|
||||
VkImageView FontView;
|
||||
VkDescriptorSet FontDescriptorSet;
|
||||
VkDeviceMemory UploadBufferMemory;
|
||||
VkBuffer UploadBuffer;
|
||||
|
||||
// Render buffers
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
@@ -117,6 +144,7 @@ void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd
|
||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulkanH_FrameRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkanH_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||
|
||||
@@ -186,7 +214,18 @@ static bool g_FunctionsLoaded = true;
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUnmapMemory) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets)
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceSupportKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBeginRenderPass) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdEndRenderPass) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueuePresentKHR) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkEndCommandBuffer) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetFences) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAcquireNextImageKHR)
|
||||
|
||||
// Define function pointers
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
|
||||
@@ -198,6 +237,10 @@ IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||
// SHADERS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplVulkan_InitPlatformInterface();
|
||||
static void ImGui_ImplVulkan_ShutdownPlatformInterface();
|
||||
|
||||
// glsl_shader.vert, compiled with:
|
||||
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
||||
/*
|
||||
@@ -375,11 +418,9 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
|
||||
// Bind pipeline and descriptor sets:
|
||||
// Bind pipeline:
|
||||
{
|
||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
VkDescriptorSet desc_set[1] = { bd->DescriptorSet };
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, NULL);
|
||||
}
|
||||
|
||||
// Bind Vertex And Index Buffer:
|
||||
@@ -431,8 +472,10 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
if (pipeline == VK_NULL_HANDLE)
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
// Allocate array to store enough vertex/index buffers
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||
// Allocate array to store enough vertex/index buffers. Each unique viewport gets its own storage.
|
||||
ImGui_ImplVulkan_ViewportData* viewport_renderer_data = (ImGui_ImplVulkan_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
IM_ASSERT(viewport_renderer_data != NULL);
|
||||
ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers;
|
||||
if (wrb->FrameRenderBuffers == NULL)
|
||||
{
|
||||
wrb->Index = 0;
|
||||
@@ -511,36 +554,52 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec4 clip_rect;
|
||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||
clip_rect.w = (pcmd->ClipRect.w - 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);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||
// Clamp to viewport as vkCmdSetScissor() 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
|
||||
VkRect2D scissor;
|
||||
scissor.offset.x = (int32_t)(clip_min.x);
|
||||
scissor.offset.y = (int32_t)(clip_min.y);
|
||||
scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x);
|
||||
scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y);
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId };
|
||||
if (sizeof(ImTextureID) < sizeof(ImU64))
|
||||
{
|
||||
// Negative offsets are illegal for vkCmdSetScissor
|
||||
if (clip_rect.x < 0.0f)
|
||||
clip_rect.x = 0.0f;
|
||||
if (clip_rect.y < 0.0f)
|
||||
clip_rect.y = 0.0f;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
VkRect2D scissor;
|
||||
scissor.offset.x = (int32_t)(clip_rect.x);
|
||||
scissor.offset.y = (int32_t)(clip_rect.y);
|
||||
scissor.extent.width = (uint32_t)(clip_rect.z - clip_rect.x);
|
||||
scissor.extent.height = (uint32_t)(clip_rect.w - clip_rect.y);
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
|
||||
// Draw
|
||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
// We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used.
|
||||
IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet);
|
||||
desc_set[0] = bd->FontDescriptorSet;
|
||||
}
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, NULL);
|
||||
|
||||
// Draw
|
||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Note: at this point both vkCmdSetViewport() and vkCmdSetScissor() have been called.
|
||||
// Our last values will leak into user/application rendering IF:
|
||||
// - Your app uses a pipeline with VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR dynamic state
|
||||
// - And you forgot to call vkCmdSetViewport() and vkCmdSetScissor() yourself to explicitely set that state.
|
||||
// If you use VK_DYNAMIC_STATE_VIEWPORT or VK_DYNAMIC_STATE_SCISSOR you are responsible for setting the values before rendering.
|
||||
// In theory we should aim to backup/restore those values but I am not sure this is possible.
|
||||
// We perform a call to vkCmdSetScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644)
|
||||
VkRect2D scissor = { { 0, 0 }, { (uint32_t)fb_width, (uint32_t)fb_height } };
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
||||
@@ -600,20 +659,8 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Update the Descriptor Set:
|
||||
{
|
||||
VkDescriptorImageInfo desc_image[1] = {};
|
||||
desc_image[0].sampler = bd->FontSampler;
|
||||
desc_image[0].imageView = bd->FontView;
|
||||
desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
VkWriteDescriptorSet write_desc[1] = {};
|
||||
write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write_desc[0].dstSet = bd->DescriptorSet;
|
||||
write_desc[0].descriptorCount = 1;
|
||||
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
write_desc[0].pImageInfo = desc_image;
|
||||
vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL);
|
||||
}
|
||||
// Create the Descriptor Set:
|
||||
bd->FontDescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(bd->FontSampler, bd->FontView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// Create the Upload Buffer:
|
||||
{
|
||||
@@ -691,7 +738,7 @@ bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer)
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontImage);
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontDescriptorSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -700,7 +747,7 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca
|
||||
{
|
||||
// Create the shader modules
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (bd->ShaderModuleVert == NULL)
|
||||
if (bd->ShaderModuleVert == VK_NULL_HANDLE)
|
||||
{
|
||||
VkShaderModuleCreateInfo vert_info = {};
|
||||
vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
@@ -709,7 +756,7 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca
|
||||
VkResult err = vkCreateShaderModule(device, &vert_info, allocator, &bd->ShaderModuleVert);
|
||||
check_vk_result(err);
|
||||
}
|
||||
if (bd->ShaderModuleFrag == NULL)
|
||||
if (bd->ShaderModuleFrag == VK_NULL_HANDLE)
|
||||
{
|
||||
VkShaderModuleCreateInfo frag_info = {};
|
||||
frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
@@ -930,17 +977,6 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Create Descriptor Set:
|
||||
{
|
||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.descriptorPool = v->DescriptorPool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &bd->DescriptorSetLayout;
|
||||
err = vkAllocateDescriptorSets(v->Device, &alloc_info, &bd->DescriptorSet);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
if (!bd->PipelineLayout)
|
||||
{
|
||||
// Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix
|
||||
@@ -984,7 +1020,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
|
||||
if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; }
|
||||
@@ -1031,6 +1067,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_vulkan";
|
||||
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)
|
||||
|
||||
IM_ASSERT(info->Instance != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
|
||||
@@ -1047,15 +1084,34 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
|
||||
|
||||
ImGui_ImplVulkan_CreateDeviceObjects();
|
||||
|
||||
// Our render function expect RendererUserData to be storing the window render buffer we need (for the main viewport we won't use ->Window)
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplVulkan_InitPlatformInterface();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// First destroy objects in all viewports
|
||||
ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
|
||||
// Manually delete main viewport render data in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)main_viewport->RendererUserData)
|
||||
IM_DELETE(vd);
|
||||
main_viewport->RendererUserData = NULL;
|
||||
|
||||
// Clean up windows
|
||||
ImGui_ImplVulkan_ShutdownPlatformInterface();
|
||||
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
IM_DELETE(bd);
|
||||
@@ -1075,13 +1131,50 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
||||
if (bd->VulkanInitInfo.MinImageCount == min_image_count)
|
||||
return;
|
||||
|
||||
IM_ASSERT(0); // FIXME-VIEWPORT: Unsupported. Need to recreate all swap chains!
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err = vkDeviceWaitIdle(v->Device);
|
||||
check_vk_result(err);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
||||
|
||||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||
}
|
||||
|
||||
// Register a texture
|
||||
// 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.
|
||||
VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
// Create Descriptor Set:
|
||||
VkDescriptorSet descriptor_set;
|
||||
{
|
||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.descriptorPool = v->DescriptorPool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &bd->DescriptorSetLayout;
|
||||
VkResult err = vkAllocateDescriptorSets(v->Device, &alloc_info, &descriptor_set);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
// Update the Descriptor Set:
|
||||
{
|
||||
VkDescriptorImageInfo desc_image[1] = {};
|
||||
desc_image[0].sampler = sampler;
|
||||
desc_image[0].imageView = image_view;
|
||||
desc_image[0].imageLayout = image_layout;
|
||||
VkWriteDescriptorSet write_desc[1] = {};
|
||||
write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
write_desc[0].dstSet = descriptor_set;
|
||||
write_desc[0].descriptorCount = 1;
|
||||
write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
write_desc[0].pImageInfo = desc_image;
|
||||
vkUpdateDescriptorSets(v->Device, 1, write_desc, 0, NULL);
|
||||
}
|
||||
return descriptor_set;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
@@ -1231,7 +1324,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
{
|
||||
VkResult err;
|
||||
VkSwapchainKHR old_swapchain = wd->Swapchain;
|
||||
wd->Swapchain = NULL;
|
||||
wd->Swapchain = VK_NULL_HANDLE;
|
||||
err = vkDeviceWaitIdle(device);
|
||||
check_vk_result(err);
|
||||
|
||||
@@ -1400,6 +1493,7 @@ void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevic
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
(void)instance;
|
||||
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
|
||||
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, g_VulkanInitInfo.Subpass);
|
||||
ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator);
|
||||
}
|
||||
|
||||
@@ -1464,3 +1558,201 @@ void ImGui_ImplVulkanH_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVul
|
||||
buffers->Index = 0;
|
||||
buffers->Count = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)platform_io.Viewports[n]->RendererUserData)
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
||||
viewport->RendererUserData = vd;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
// Create surface
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
VkResult err = (VkResult)platform_io.Platform_CreateVkSurface(viewport, (ImU64)v->Instance, (const void*)v->Allocator, (ImU64*)&wd->Surface);
|
||||
check_vk_result(err);
|
||||
|
||||
// Check for WSI support
|
||||
VkBool32 res;
|
||||
vkGetPhysicalDeviceSurfaceSupportKHR(v->PhysicalDevice, v->QueueFamily, wd->Surface, &res);
|
||||
if (res != VK_TRUE)
|
||||
{
|
||||
IM_ASSERT(0); // Error: no WSI support on physical device
|
||||
return;
|
||||
}
|
||||
|
||||
// Select Surface Format
|
||||
const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace);
|
||||
|
||||
// Select Present Mode
|
||||
// FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1)
|
||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
||||
wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(v->PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes));
|
||||
//printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode);
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
vd->WindowOwned = true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData)
|
||||
{
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (vd->WindowOwned)
|
||||
ImGui_ImplVulkanH_DestroyWindow(v->Instance, v->Device, &vd->Window, v->Allocator);
|
||||
ImGui_ImplVulkanH_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator);
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->RendererUserData = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
if (vd == NULL) // This is NULL for the main viewport (which is left to the user/app to handle)
|
||||
return;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err;
|
||||
|
||||
ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex];
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
||||
{
|
||||
{
|
||||
err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
||||
check_vk_result(err);
|
||||
fd = &wd->Frames[wd->FrameIndex];
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100);
|
||||
if (err == VK_SUCCESS) break;
|
||||
if (err == VK_TIMEOUT) continue;
|
||||
check_vk_result(err);
|
||||
}
|
||||
{
|
||||
err = vkResetCommandPool(v->Device, fd->CommandPool, 0);
|
||||
check_vk_result(err);
|
||||
VkCommandBufferBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
|
||||
check_vk_result(err);
|
||||
}
|
||||
{
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
||||
|
||||
VkRenderPassBeginInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
info.renderPass = wd->RenderPass;
|
||||
info.framebuffer = fd->Framebuffer;
|
||||
info.renderArea.extent.width = wd->Width;
|
||||
info.renderArea.extent.height = wd->Height;
|
||||
info.clearValueCount = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? 0 : 1;
|
||||
info.pClearValues = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? NULL : &wd->ClearValue;
|
||||
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_RenderDrawData(viewport->DrawData, fd->CommandBuffer, wd->Pipeline);
|
||||
|
||||
{
|
||||
vkCmdEndRenderPass(fd->CommandBuffer);
|
||||
{
|
||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
VkSubmitInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
info.waitSemaphoreCount = 1;
|
||||
info.pWaitSemaphores = &fsd->ImageAcquiredSemaphore;
|
||||
info.pWaitDstStageMask = &wait_stage;
|
||||
info.commandBufferCount = 1;
|
||||
info.pCommandBuffers = &fd->CommandBuffer;
|
||||
info.signalSemaphoreCount = 1;
|
||||
info.pSignalSemaphores = &fsd->RenderCompleteSemaphore;
|
||||
|
||||
err = vkEndCommandBuffer(fd->CommandBuffer);
|
||||
check_vk_result(err);
|
||||
err = vkResetFences(v->Device, 1, &fd->Fence);
|
||||
check_vk_result(err);
|
||||
err = vkQueueSubmit(v->Queue, 1, &info, fd->Fence);
|
||||
check_vk_result(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
|
||||
VkResult err;
|
||||
uint32_t present_index = wd->FrameIndex;
|
||||
|
||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
||||
VkPresentInfoKHR info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
info.waitSemaphoreCount = 1;
|
||||
info.pWaitSemaphores = &fsd->RenderCompleteSemaphore;
|
||||
info.swapchainCount = 1;
|
||||
info.pSwapchains = &wd->Swapchain;
|
||||
info.pImageIndices = &present_index;
|
||||
err = vkQueuePresentKHR(v->Queue, &info);
|
||||
if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR)
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
else
|
||||
check_vk_result(err);
|
||||
|
||||
wd->FrameIndex = (wd->FrameIndex + 1) % wd->ImageCount; // This is for the next vkWaitForFences()
|
||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->ImageCount; // Now we can use the next set of semaphores
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_InitPlatformInterface()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
IM_ASSERT(platform_io.Platform_CreateVkSurface != NULL && "Platform needs to setup the CreateVkSurface handler.");
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplVulkan_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplVulkan_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplVulkan_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplVulkan_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: User texture binding. Changes of ImTextureID aren't supported by this backend! See https://github.com/ocornut/imgui/pull/914
|
||||
// [x] Platform: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// 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.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
@@ -56,23 +59,27 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
uint32_t Subpass;
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
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 bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
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 bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
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 bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// 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.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// 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 = NULL);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = NULL);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
@@ -81,8 +88,8 @@ IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loade
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the upcoming multi-viewport feature will need them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// 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.).
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// 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.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-11-29: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer()/wgpuRenderPassEncoderSetIndexBuffer().
|
||||
// 2021-08-24: Fix for latest specs.
|
||||
// 2021-05-24: Add support for draw_data->FramebufferScale.
|
||||
// 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92).
|
||||
@@ -269,7 +271,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_
|
||||
spirv_desc.codeSize = binary_data_size;
|
||||
spirv_desc.code = binary_data;
|
||||
|
||||
WGPUShaderModuleDescriptor desc;
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc);
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
@@ -280,7 +282,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_
|
||||
|
||||
static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture)
|
||||
{
|
||||
WGPUBindGroupEntry image_bg_entries[] = { { 0, 0, 0, 0, 0, texture } };
|
||||
WGPUBindGroupEntry image_bg_entries[] = { { nullptr, 0, 0, 0, 0, 0, texture } };
|
||||
|
||||
WGPUBindGroupDescriptor image_bg_descriptor = {};
|
||||
image_bg_descriptor.layout = layout;
|
||||
@@ -312,8 +314,8 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
|
||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, 0);
|
||||
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, 0);
|
||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
|
||||
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
|
||||
wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
|
||||
wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, NULL);
|
||||
|
||||
@@ -442,13 +444,14 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, NULL);
|
||||
}
|
||||
|
||||
// Apply Scissor, Bind texture, Draw
|
||||
uint32_t clip_rect[4];
|
||||
clip_rect[0] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.x - clip_off.x));
|
||||
clip_rect[1] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.y - clip_off.y));
|
||||
clip_rect[2] = (uint32_t)(clip_scale.x * (pcmd->ClipRect.z - clip_off.x));
|
||||
clip_rect[3] = (uint32_t)(clip_scale.y * (pcmd->ClipRect.w - clip_off.y));
|
||||
wgpuRenderPassEncoderSetScissorRect(pass_encoder, clip_rect[0], clip_rect[1], clip_rect[2] - clip_rect[0], clip_rect[3] - clip_rect[1]);
|
||||
// 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);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle, Draw
|
||||
wgpuRenderPassEncoderSetScissorRect(pass_encoder, (uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y));
|
||||
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
@@ -476,7 +479,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||
tex_desc.sampleCount = 1;
|
||||
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||
tex_desc.mipLevelCount = 1;
|
||||
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_Sampled;
|
||||
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
|
||||
g_resources.FontTexture = wgpuDeviceCreateTexture(g_wgpuDevice, &tex_desc);
|
||||
|
||||
WGPUTextureViewDescriptor tex_view_desc = {};
|
||||
@@ -544,7 +547,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
|
||||
// Create render pipeline
|
||||
WGPURenderPipelineDescriptor2 graphics_pipeline_desc = {};
|
||||
WGPURenderPipelineDescriptor graphics_pipeline_desc = {};
|
||||
graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList;
|
||||
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
|
||||
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
|
||||
@@ -569,7 +572,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
|
||||
WGPUVertexBufferLayout buffer_layouts[1];
|
||||
buffer_layouts[0].arrayStride = sizeof(ImDrawVert);
|
||||
buffer_layouts[0].stepMode = WGPUInputStepMode_Vertex;
|
||||
buffer_layouts[0].stepMode = WGPUVertexStepMode_Vertex;
|
||||
buffer_layouts[0].attributeCount = 3;
|
||||
buffer_layouts[0].attributes = attribute_desc;
|
||||
|
||||
@@ -610,7 +613,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
// Configure disabled depth-stencil state
|
||||
graphics_pipeline_desc.depthStencil = nullptr;
|
||||
|
||||
g_pipelineState = wgpuDeviceCreateRenderPipeline2(g_wgpuDevice, &graphics_pipeline_desc);
|
||||
g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc);
|
||||
|
||||
ImGui_ImplWGPU_CreateFontsTexture();
|
||||
ImGui_ImplWGPU_CreateUniformBuffer();
|
||||
@@ -622,8 +625,8 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
|
||||
WGPUBindGroupEntry common_bg_entries[] =
|
||||
{
|
||||
{ 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
|
||||
{ 1, 0, 0, 0, g_resources.Sampler, 0 },
|
||||
{ nullptr, 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
|
||||
{ nullptr, 1, 0, 0, 0, g_resources.Sampler, 0 },
|
||||
};
|
||||
|
||||
WGPUBindGroupDescriptor common_bg_descriptor = {};
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
|
||||
// [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: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// 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 +19,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
||||
#include <tchar.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
@@ -33,8 +35,17 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always update key mods next and before a key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API.
|
||||
// 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
|
||||
// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host windo doesn't have focus.
|
||||
// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
|
||||
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events).
|
||||
// 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-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
|
||||
@@ -67,16 +78,23 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplWin32_InitPlatformInterface();
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
struct ImGui_ImplWin32_Data
|
||||
{
|
||||
HWND hWnd;
|
||||
HWND MouseHwnd;
|
||||
bool MouseTracked;
|
||||
int MouseButtonsDown;
|
||||
INT64 Time;
|
||||
INT64 TicksPerSecond;
|
||||
ImGuiMouseCursor LastMouseCursor;
|
||||
bool HasGamepad;
|
||||
bool WantUpdateHasGamepad;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
HMODULE XInputDLL;
|
||||
@@ -114,38 +132,21 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
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_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
|
||||
bd->hWnd = (HWND)hwnd;
|
||||
bd->WantUpdateHasGamepad = true;
|
||||
bd->WantUpdateMonitors = true;
|
||||
bd->TicksPerSecond = perf_frequency;
|
||||
bd->Time = perf_counter;
|
||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
|
||||
io.ImeWindowHandle = hwnd;
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
|
||||
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplWin32_InitPlatformInterface();
|
||||
|
||||
// Dynamically load XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -172,8 +173,11 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
|
||||
void ImGui_ImplWin32_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
|
||||
// Unload XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -219,38 +223,95 @@ static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
static bool IsVkDown(int vk)
|
||||
{
|
||||
return (::GetKeyState(vk) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(key, down);
|
||||
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
||||
IM_UNUSED(native_scancode);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||
{
|
||||
// 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))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
||||
ImGui_ImplWin32_AddKeyEvent(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).
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(ImGuiKey_ModCtrl, IsVkDown(VK_CONTROL));
|
||||
io.AddKeyEvent(ImGuiKey_ModShift, IsVkDown(VK_SHIFT));
|
||||
io.AddKeyEvent(ImGuiKey_ModAlt, IsVkDown(VK_MENU));
|
||||
io.AddKeyEvent(ImGuiKey_ModSuper, IsVkDown(VK_APPS));
|
||||
}
|
||||
|
||||
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
|
||||
// Because of that, it is a little more complicated than your typical single-viewport binding code!
|
||||
static void ImGui_ImplWin32_UpdateMouseData()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(bd->hWnd != 0);
|
||||
|
||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
POINT mouse_screen_pos;
|
||||
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
|
||||
|
||||
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
|
||||
HWND focused_window = ::GetForegroundWindow();
|
||||
HWND hovered_window = bd->MouseHwnd;
|
||||
HWND mouse_window = NULL;
|
||||
if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd)))
|
||||
mouse_window = hovered_window;
|
||||
else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd)))
|
||||
mouse_window = focused_window;
|
||||
if (mouse_window == NULL)
|
||||
return;
|
||||
|
||||
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
if (is_app_focused)
|
||||
{
|
||||
POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
|
||||
if (::ClientToScreen(bd->hWnd, &pos))
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0)
|
||||
::ClientToScreen(focused_window, &pos);
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||
if (!io.WantSetMousePos && !bd->MouseTracked && has_mouse_screen_pos)
|
||||
{
|
||||
// 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)
|
||||
// (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
|
||||
// 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)
|
||||
// (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
|
||||
POINT mouse_pos = mouse_screen_pos;
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
::ScreenToClient(bd->hWnd, &mouse_pos);
|
||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Set Dear ImGui mouse position from OS position
|
||||
POINT pos;
|
||||
if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos))
|
||||
io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [X] Win32 backend correctly ignore viewports with the _NoInputs flag (here using ::WindowFromPoint with WM_NCHITTEST + HTTRANSPARENT in WndProc does that)
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||
// - [X] Win32 backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (has_mouse_screen_pos)
|
||||
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
|
||||
mouse_viewport_id = viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
|
||||
// Gamepad navigation mapping
|
||||
@@ -259,7 +320,6 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
@@ -267,42 +327,78 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
||||
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||
if (bd->WantUpdateHasGamepad)
|
||||
{
|
||||
XINPUT_CAPABILITIES caps;
|
||||
XINPUT_CAPABILITIES caps = {};
|
||||
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
||||
bd->WantUpdateHasGamepad = false;
|
||||
}
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
XINPUT_STATE xinput_state;
|
||||
if (bd->HasGamepad && bd->XInputGetState && bd->XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
|
||||
{
|
||||
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||
if (!bd->HasGamepad || bd->XInputGetState == NULL || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
|
||||
return;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
||||
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
|
||||
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
|
||||
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
|
||||
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
|
||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
|
||||
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
|
||||
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
|
||||
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
|
||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
|
||||
#define MAP_ANALOG(KEY_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); io.AddKeyAnalogEvent(KEY_NO, vn > 0.10f, IM_SATURATE(vn)); }
|
||||
MAP_BUTTON(ImGuiKey_GamepadStart, XINPUT_GAMEPAD_START);
|
||||
MAP_BUTTON(ImGuiKey_GamepadBack, XINPUT_GAMEPAD_BACK);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceDown, XINPUT_GAMEPAD_A);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceRight, XINPUT_GAMEPAD_B);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceLeft, XINPUT_GAMEPAD_X);
|
||||
MAP_BUTTON(ImGuiKey_GamepadFaceUp, XINPUT_GAMEPAD_Y);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadLeft, XINPUT_GAMEPAD_DPAD_LEFT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadRight, XINPUT_GAMEPAD_DPAD_RIGHT);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadUp, XINPUT_GAMEPAD_DPAD_UP);
|
||||
MAP_BUTTON(ImGuiKey_GamepadDpadDown, XINPUT_GAMEPAD_DPAD_DOWN);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL1, XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR1, XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||
MAP_ANALOG(ImGuiKey_GamepadL2, gamepad.bLeftTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||
MAP_ANALOG(ImGuiKey_GamepadR2, gamepad.bRightTrigger, XINPUT_GAMEPAD_TRIGGER_THRESHOLD, 255);
|
||||
MAP_BUTTON(ImGuiKey_GamepadL3, XINPUT_GAMEPAD_LEFT_THUMB);
|
||||
MAP_BUTTON(ImGuiKey_GamepadR3, XINPUT_GAMEPAD_RIGHT_THUMB);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadLStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickLeft, gamepad.sThumbRX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickRight, gamepad.sThumbRX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickUp, gamepad.sThumbRY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
||||
{
|
||||
MONITORINFO info = {};
|
||||
info.cbSize = sizeof(MONITORINFO);
|
||||
if (!::GetMonitorInfo(monitor, &info))
|
||||
return TRUE;
|
||||
ImGuiPlatformMonitor imgui_monitor;
|
||||
imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top);
|
||||
imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top));
|
||||
imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top);
|
||||
imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top));
|
||||
imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
ImGuiPlatformIO& io = ImGui::GetPlatformIO();
|
||||
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
||||
io.Monitors.push_front(imgui_monitor);
|
||||
else
|
||||
io.Monitors.push_back(imgui_monitor);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui::GetPlatformIO().Monitors.resize(0);
|
||||
::EnumDisplayMonitors(NULL, NULL, ImGui_ImplWin32_UpdateMonitors_EnumFunc, 0);
|
||||
bd->WantUpdateMonitors = false;
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -313,6 +409,8 @@ void ImGui_ImplWin32_NewFrame()
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
::GetClientRect(bd->hWnd, &rect);
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||
if (bd->WantUpdateMonitors)
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
INT64 current_time = 0;
|
||||
@@ -321,7 +419,10 @@ void ImGui_ImplWin32_NewFrame()
|
||||
bd->Time = current_time;
|
||||
|
||||
// Update OS mouse position
|
||||
ImGui_ImplWin32_UpdateMousePos();
|
||||
ImGui_ImplWin32_UpdateMouseData();
|
||||
|
||||
// Process workarounds for known Windows key handling issues
|
||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||
@@ -335,6 +436,122 @@ void ImGui_ImplWin32_NewFrame()
|
||||
ImGui_ImplWin32_UpdateGamepads();
|
||||
}
|
||||
|
||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255)
|
||||
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
|
||||
|
||||
// Map VK_xxx to ImGuiKey_xxx.
|
||||
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_TAB: return ImGuiKey_Tab;
|
||||
case VK_LEFT: return ImGuiKey_LeftArrow;
|
||||
case VK_RIGHT: return ImGuiKey_RightArrow;
|
||||
case VK_UP: return ImGuiKey_UpArrow;
|
||||
case VK_DOWN: return ImGuiKey_DownArrow;
|
||||
case VK_PRIOR: return ImGuiKey_PageUp;
|
||||
case VK_NEXT: return ImGuiKey_PageDown;
|
||||
case VK_HOME: return ImGuiKey_Home;
|
||||
case VK_END: return ImGuiKey_End;
|
||||
case VK_INSERT: return ImGuiKey_Insert;
|
||||
case VK_DELETE: return ImGuiKey_Delete;
|
||||
case VK_BACK: return ImGuiKey_Backspace;
|
||||
case VK_SPACE: return ImGuiKey_Space;
|
||||
case VK_RETURN: return ImGuiKey_Enter;
|
||||
case VK_ESCAPE: return ImGuiKey_Escape;
|
||||
case VK_OEM_7: return ImGuiKey_Apostrophe;
|
||||
case VK_OEM_COMMA: return ImGuiKey_Comma;
|
||||
case VK_OEM_MINUS: return ImGuiKey_Minus;
|
||||
case VK_OEM_PERIOD: return ImGuiKey_Period;
|
||||
case VK_OEM_2: return ImGuiKey_Slash;
|
||||
case VK_OEM_1: return ImGuiKey_Semicolon;
|
||||
case VK_OEM_PLUS: return ImGuiKey_Equal;
|
||||
case VK_OEM_4: return ImGuiKey_LeftBracket;
|
||||
case VK_OEM_5: return ImGuiKey_Backslash;
|
||||
case VK_OEM_6: return ImGuiKey_RightBracket;
|
||||
case VK_OEM_3: return ImGuiKey_GraveAccent;
|
||||
case VK_CAPITAL: return ImGuiKey_CapsLock;
|
||||
case VK_SCROLL: return ImGuiKey_ScrollLock;
|
||||
case VK_NUMLOCK: return ImGuiKey_NumLock;
|
||||
case VK_SNAPSHOT: return ImGuiKey_PrintScreen;
|
||||
case VK_PAUSE: return ImGuiKey_Pause;
|
||||
case VK_NUMPAD0: return ImGuiKey_Keypad0;
|
||||
case VK_NUMPAD1: return ImGuiKey_Keypad1;
|
||||
case VK_NUMPAD2: return ImGuiKey_Keypad2;
|
||||
case VK_NUMPAD3: return ImGuiKey_Keypad3;
|
||||
case VK_NUMPAD4: return ImGuiKey_Keypad4;
|
||||
case VK_NUMPAD5: return ImGuiKey_Keypad5;
|
||||
case VK_NUMPAD6: return ImGuiKey_Keypad6;
|
||||
case VK_NUMPAD7: return ImGuiKey_Keypad7;
|
||||
case VK_NUMPAD8: return ImGuiKey_Keypad8;
|
||||
case VK_NUMPAD9: return ImGuiKey_Keypad9;
|
||||
case VK_DECIMAL: return ImGuiKey_KeypadDecimal;
|
||||
case VK_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case VK_ADD: return ImGuiKey_KeypadAdd;
|
||||
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
|
||||
case VK_LMENU: return ImGuiKey_LeftAlt;
|
||||
case VK_LWIN: return ImGuiKey_LeftSuper;
|
||||
case VK_RSHIFT: return ImGuiKey_RightShift;
|
||||
case VK_RCONTROL: return ImGuiKey_RightCtrl;
|
||||
case VK_RMENU: return ImGuiKey_RightAlt;
|
||||
case VK_RWIN: return ImGuiKey_RightSuper;
|
||||
case VK_APPS: return ImGuiKey_Menu;
|
||||
case '0': return ImGuiKey_0;
|
||||
case '1': return ImGuiKey_1;
|
||||
case '2': return ImGuiKey_2;
|
||||
case '3': return ImGuiKey_3;
|
||||
case '4': return ImGuiKey_4;
|
||||
case '5': return ImGuiKey_5;
|
||||
case '6': return ImGuiKey_6;
|
||||
case '7': return ImGuiKey_7;
|
||||
case '8': return ImGuiKey_8;
|
||||
case '9': return ImGuiKey_9;
|
||||
case 'A': return ImGuiKey_A;
|
||||
case 'B': return ImGuiKey_B;
|
||||
case 'C': return ImGuiKey_C;
|
||||
case 'D': return ImGuiKey_D;
|
||||
case 'E': return ImGuiKey_E;
|
||||
case 'F': return ImGuiKey_F;
|
||||
case 'G': return ImGuiKey_G;
|
||||
case 'H': return ImGuiKey_H;
|
||||
case 'I': return ImGuiKey_I;
|
||||
case 'J': return ImGuiKey_J;
|
||||
case 'K': return ImGuiKey_K;
|
||||
case 'L': return ImGuiKey_L;
|
||||
case 'M': return ImGuiKey_M;
|
||||
case 'N': return ImGuiKey_N;
|
||||
case 'O': return ImGuiKey_O;
|
||||
case 'P': return ImGuiKey_P;
|
||||
case 'Q': return ImGuiKey_Q;
|
||||
case 'R': return ImGuiKey_R;
|
||||
case 'S': return ImGuiKey_S;
|
||||
case 'T': return ImGuiKey_T;
|
||||
case 'U': return ImGuiKey_U;
|
||||
case 'V': return ImGuiKey_V;
|
||||
case 'W': return ImGuiKey_W;
|
||||
case 'X': return ImGuiKey_X;
|
||||
case 'Y': return ImGuiKey_Y;
|
||||
case 'Z': return ImGuiKey_Z;
|
||||
case VK_F1: return ImGuiKey_F1;
|
||||
case VK_F2: return ImGuiKey_F2;
|
||||
case VK_F3: return ImGuiKey_F3;
|
||||
case VK_F4: return ImGuiKey_F4;
|
||||
case VK_F5: return ImGuiKey_F5;
|
||||
case VK_F6: return ImGuiKey_F6;
|
||||
case VK_F7: return ImGuiKey_F7;
|
||||
case VK_F8: return ImGuiKey_F8;
|
||||
case VK_F9: return ImGuiKey_F9;
|
||||
case VK_F10: return ImGuiKey_F10;
|
||||
case VK_F11: return ImGuiKey_F11;
|
||||
case VK_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
@@ -366,6 +583,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||
bd->MouseHwnd = hwnd;
|
||||
if (!bd->MouseTracked)
|
||||
@@ -374,11 +592,17 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
::TrackMouseEvent(&tme);
|
||||
bd->MouseTracked = true;
|
||||
}
|
||||
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
::ClientToScreen(hwnd, &mouse_pos);
|
||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||
break;
|
||||
}
|
||||
case WM_MOUSELEAVE:
|
||||
if (bd->MouseHwnd == hwnd)
|
||||
bd->MouseHwnd = NULL;
|
||||
bd->MouseTracked = false;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
break;
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
@@ -390,9 +614,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
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 (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
|
||||
if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL)
|
||||
::SetCapture(hwnd);
|
||||
io.MouseDown[button] = true;
|
||||
bd->MouseButtonsDown |= 1 << button;
|
||||
io.AddMouseButtonEvent(button, true);
|
||||
return 0;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
@@ -405,31 +630,59 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
io.MouseDown[button] = false;
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
|
||||
bd->MouseButtonsDown &= ~(1 << button);
|
||||
if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd)
|
||||
::ReleaseCapture();
|
||||
io.AddMouseButtonEvent(button, false);
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA);
|
||||
return 0;
|
||||
case WM_MOUSEHWHEEL:
|
||||
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
io.AddMouseWheelEvent((float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f);
|
||||
return 0;
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
bool down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
||||
const bool is_key_down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
||||
if (wParam < 256)
|
||||
io.KeysDown[wParam] = down;
|
||||
if (wParam == VK_CONTROL)
|
||||
io.KeyCtrl = down;
|
||||
if (wParam == VK_SHIFT)
|
||||
io.KeyShift = down;
|
||||
if (wParam == VK_MENU)
|
||||
io.KeyAlt = down;
|
||||
{
|
||||
// Submit modifiers
|
||||
ImGui_ImplWin32_UpdateKeyModifiers();
|
||||
|
||||
// Obtain virtual key code
|
||||
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
||||
int vk = (int)wParam;
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
vk = IM_VK_KEYPAD_ENTER;
|
||||
|
||||
// Submit key event
|
||||
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||
if (key != ImGuiKey_None)
|
||||
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
||||
|
||||
// Submit individual left/right modifier events
|
||||
if (vk == VK_SHIFT)
|
||||
{
|
||||
// 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_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||
}
|
||||
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_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||
}
|
||||
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_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_SETFOCUS:
|
||||
@@ -449,6 +702,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
||||
bd->WantUpdateHasGamepad = true;
|
||||
return 0;
|
||||
case WM_DISPLAYCHANGE:
|
||||
bd->WantUpdateMonitors = true;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -513,6 +769,10 @@ typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWAR
|
||||
// Helper function to enable DPI awareness without setting up a manifest
|
||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||
{
|
||||
// Make sure monitors will be updated with latest correct scaling
|
||||
if (ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData())
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
if (_IsWindows10OrGreater())
|
||||
{
|
||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||
@@ -572,6 +832,326 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||
struct ImGui_ImplWin32_ViewportData
|
||||
{
|
||||
HWND Hwnd;
|
||||
bool HwndOwned;
|
||||
DWORD DwStyle;
|
||||
DWORD DwExStyle;
|
||||
|
||||
ImGui_ImplWin32_ViewportData() { Hwnd = NULL; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
||||
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == NULL); }
|
||||
};
|
||||
|
||||
static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags flags, DWORD* out_style, DWORD* out_ex_style)
|
||||
{
|
||||
if (flags & ImGuiViewportFlags_NoDecoration)
|
||||
*out_style = WS_POPUP;
|
||||
else
|
||||
*out_style = WS_OVERLAPPEDWINDOW;
|
||||
|
||||
if (flags & ImGuiViewportFlags_NoTaskBarIcon)
|
||||
*out_ex_style = WS_EX_TOOLWINDOW;
|
||||
else
|
||||
*out_ex_style = WS_EX_APPWINDOW;
|
||||
|
||||
if (flags & ImGuiViewportFlags_TopMost)
|
||||
*out_ex_style |= WS_EX_TOPMOST;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
// Select style and parent window
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
||||
HWND parent_window = NULL;
|
||||
if (viewport->ParentViewportId != 0)
|
||||
if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId))
|
||||
parent_window = (HWND)parent_viewport->PlatformHandle;
|
||||
|
||||
// Create window
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
vd->Hwnd = ::CreateWindowEx(
|
||||
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
||||
parent_window, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param
|
||||
vd->HwndOwned = true;
|
||||
viewport->PlatformRequestResize = false;
|
||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
if (ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData)
|
||||
{
|
||||
if (::GetCapture() == vd->Hwnd)
|
||||
{
|
||||
// Transfer capture so if we started dragging from a window that later disappears, we'll still receive the MOUSEUP event.
|
||||
::ReleaseCapture();
|
||||
::SetCapture(bd->hWnd);
|
||||
}
|
||||
if (vd->Hwnd && vd->HwndOwned)
|
||||
::DestroyWindow(vd->Hwnd);
|
||||
vd->Hwnd = NULL;
|
||||
IM_DELETE(vd);
|
||||
}
|
||||
viewport->PlatformUserData = viewport->PlatformHandle = NULL;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA);
|
||||
else
|
||||
::ShowWindow(vd->Hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// (Optional) Update Win32 style if it changed _after_ creation.
|
||||
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
DWORD new_style;
|
||||
DWORD new_ex_style;
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
|
||||
|
||||
// Only reapply the flags that have been changed from our point of view (as other flags are being modified by Windows)
|
||||
if (vd->DwStyle != new_style || vd->DwExStyle != new_ex_style)
|
||||
{
|
||||
// (Optional) Update TopMost state if it changed _after_ creation
|
||||
bool top_most_changed = (vd->DwExStyle & WS_EX_TOPMOST) != (new_ex_style & WS_EX_TOPMOST);
|
||||
HWND insert_after = top_most_changed ? ((viewport->Flags & ImGuiViewportFlags_TopMost) ? HWND_TOPMOST : HWND_NOTOPMOST) : 0;
|
||||
UINT swp_flag = top_most_changed ? 0 : SWP_NOZORDER;
|
||||
|
||||
// Apply flags and position (since it is affected by flags)
|
||||
vd->DwStyle = new_style;
|
||||
vd->DwExStyle = new_ex_style;
|
||||
::SetWindowLong(vd->Hwnd, GWL_STYLE, vd->DwStyle);
|
||||
::SetWindowLong(vd->Hwnd, GWL_EXSTYLE, vd->DwExStyle);
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(vd->Hwnd, insert_after, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, swp_flag | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA); // This is necessary when we alter the style
|
||||
viewport->PlatformRequestMove = viewport->PlatformRequestResize = true;
|
||||
}
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
POINT pos = { 0, 0 };
|
||||
::ClientToScreen(vd->Hwnd, &pos);
|
||||
return ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
::SetWindowPos(vd->Hwnd, NULL, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect;
|
||||
::GetClientRect(vd->Hwnd, &rect);
|
||||
return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top));
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(vd->Hwnd, NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
::BringWindowToTop(vd->Hwnd);
|
||||
::SetForegroundWindow(vd->Hwnd);
|
||||
::SetFocus(vd->Hwnd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ::GetForegroundWindow() == vd->Hwnd;
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ::IsIconic(vd->Hwnd) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
||||
{
|
||||
// ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string.
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
int n = ::MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
|
||||
ImVector<wchar_t> title_w;
|
||||
title_w.resize(n);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n);
|
||||
::SetWindowTextW(vd->Hwnd, title_w.Data);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||
if (alpha < 1.0f)
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
::SetLayeredWindowAttributes(vd->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
}
|
||||
}
|
||||
|
||||
static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
return ImGui_ImplWin32_GetDpiScaleForHwnd(vd->Hwnd);
|
||||
}
|
||||
|
||||
// FIXME-DPI: Testing DPI related ideas
|
||||
static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
(void)viewport;
|
||||
#if 0
|
||||
ImGuiStyle default_style;
|
||||
//default_style.WindowPadding = ImVec2(0, 0);
|
||||
//default_style.WindowBorderSize = 0.0f;
|
||||
//default_style.ItemSpacing.y = 3.0f;
|
||||
//default_style.FramePadding = ImVec2(0, 0);
|
||||
default_style.ScaleAllSizes(viewport->DpiScale);
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style = default_style;
|
||||
#endif
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
||||
return true;
|
||||
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
viewport->PlatformRequestClose = true;
|
||||
return 0;
|
||||
case WM_MOVE:
|
||||
viewport->PlatformRequestMove = true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
viewport->PlatformRequestResize = true;
|
||||
break;
|
||||
case WM_MOUSEACTIVATE:
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick)
|
||||
return MA_NOACTIVATE;
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_InitPlatformInterface()
|
||||
{
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
wcex.hInstance = ::GetModuleHandle(NULL);
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hCursor = NULL;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = _T("ImGui Platform");
|
||||
wcex.hIconSm = NULL;
|
||||
::RegisterClassEx(&wcex);
|
||||
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_CreateWindow = ImGui_ImplWin32_CreateWindow;
|
||||
platform_io.Platform_DestroyWindow = ImGui_ImplWin32_DestroyWindow;
|
||||
platform_io.Platform_ShowWindow = ImGui_ImplWin32_ShowWindow;
|
||||
platform_io.Platform_SetWindowPos = ImGui_ImplWin32_SetWindowPos;
|
||||
platform_io.Platform_GetWindowPos = ImGui_ImplWin32_GetWindowPos;
|
||||
platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize;
|
||||
platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize;
|
||||
platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus;
|
||||
platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus;
|
||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized;
|
||||
platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle;
|
||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha;
|
||||
platform_io.Platform_UpdateWindow = ImGui_ImplWin32_UpdateWindow;
|
||||
platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI
|
||||
platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI
|
||||
|
||||
// Register main window handle (which is owned by the main application, not by us)
|
||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
||||
vd->Hwnd = bd->hWnd;
|
||||
vd->HwndOwned = false;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = (void*)bd->hWnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface()
|
||||
{
|
||||
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(NULL));
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// Transparency related helpers (optional)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
|
||||
// [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: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
@@ -9,10 +9,10 @@ your application or engine to easily integrate Dear ImGui.** Each backend is typ
|
||||
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_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
|
||||
|
||||
- The 'Renderer' backends are in charge of: creating atlas texture, 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.
|
||||
|
||||
- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.<BR>
|
||||
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)), Marmalade ([imgui_impl_marmalade.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_marmalade.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
|
||||
e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
|
||||
|
||||
An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
|
||||
For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
|
||||
@@ -38,7 +38,7 @@ Dear ImGui is highly portable and only requires a few things to run and render,
|
||||
- Optional: multi-viewports support.
|
||||
etc.
|
||||
|
||||
This is essentially what each backends are doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support).
|
||||
This is essentially what each backend is doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support).
|
||||
|
||||
It is important to understand the difference between the core Dear ImGui library (files in the root folder)
|
||||
and backends which we are describing here (backends/ folder).
|
||||
@@ -75,20 +75,20 @@ List of Renderer Backends:
|
||||
imgui_impl_metal.mm ; Metal (with ObjC)
|
||||
imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context)
|
||||
imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline)
|
||||
imgui_impl_sdlrenderer.cpp; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
|
||||
imgui_impl_vulkan.cpp ; Vulkan
|
||||
imgui_impl_wgpu.cpp ; WebGPU
|
||||
|
||||
List of high-level Frameworks Backends (combining Platform + Renderer):
|
||||
|
||||
imgui_impl_allegro5.cpp
|
||||
imgui_impl_marmalade.cpp
|
||||
|
||||
Emscripten is also supported.
|
||||
The [example_emscripten_opengl3](https://github.com/ocornut/imgui/tree/master/examples/example_emscripten_opengl3) app uses imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp, but other combos are possible.
|
||||
|
||||
### Backends for third-party frameworks, graphics API or other languages
|
||||
|
||||
See https://github.com/ocornut/imgui/wiki/Bindings for the full list.
|
||||
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
|
||||
|
||||
@@ -127,7 +127,10 @@ Once it works, if you really need it you can replace parts of backends with your
|
||||
and you have high-level systems everywhere.<BR>
|
||||
Suggestion: try using a non-portable backend first (e.g. win32 + underlying graphics API) to get
|
||||
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:
|
||||
The [multi-viewports feature](https://github.com/ocornut/imgui/issues/1542) of the 'docking' branch allows
|
||||
|
||||
@@ -31,6 +31,533 @@ HOW TO UPDATE?
|
||||
- Please report any issue!
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
DOCKING+MULTI-VIEWPORT BRANCH (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
DOCKING FEATURES
|
||||
(see https://github.com/ocornut/imgui/wiki/Docking for quick intro)
|
||||
|
||||
- Added Docking system: [BETA] (#2109, #351)
|
||||
- Added ImGuiConfigFlags_DockingEnable flag to enable Docking.
|
||||
Set with `io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;`.
|
||||
- Added DockSpace(), DockSpaceOverViewport() API.
|
||||
- Added ImGuiDockNodeFlags flags for DockSpace().
|
||||
- Added SetNextWindowDockID(), SetNextWindowClass() API.
|
||||
- Added GetWindowDockID(), IsWindowDocked() API.
|
||||
- Added ImGuiWindowFlags_NoDocking window flag to disable the possibility for a window to be docked.
|
||||
Popup, Menu and Child windows always have the ImGuiWindowFlags_NoDocking flag set.
|
||||
- Added ImGuiWindowClass to specify advanced docking/viewport related flags via SetNextWindowClass().
|
||||
- Added io.ConfigDockingNoSplit option.
|
||||
- Added io.ConfigDockingWithShift option.
|
||||
- Added io.ConfigDockingAlwaysTabBar option.
|
||||
- Added io.ConfigDockingTransparentPayload option.
|
||||
- Style: Added ImGuiCol_DockingPreview, ImGuiCol_DockingEmptyBg colors.
|
||||
- Demo: Added "DockSpace" example app showcasing use of explicit dockspace nodes.
|
||||
|
||||
MULTI-VIEWPORT FEATURES
|
||||
(see https://github.com/ocornut/imgui/wiki/Multi-Viewports for quick intro)
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- IMPORTANT: When multi-viewports are enabled (with io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable),
|
||||
all coordinates/positions will be in your natural OS coordinates space. It means that:
|
||||
- Reference to hard-coded positions such as in SetNextWindowPos(ImVec2(0,0)) are _probably_ not what you want anymore.
|
||||
Use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos).
|
||||
- Likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them.
|
||||
e.g. subtract GetWindowViewport()->Pos.
|
||||
- IO: Removed io.DisplayVisibleMin, io.DisplayVisibleMax settings (they were marked obsoleted, used to clip within the (0,0)..(DisplaySize) range).
|
||||
|
||||
Other changes:
|
||||
(FIXME: This need a fuller explanation!)
|
||||
|
||||
- Added ImGuiPlatformIO structure and GetPlatformIO().
|
||||
- Similarly to ImGuiIO and GetIO(), this structure is the main point of communication for backends supporting multi-viewports.
|
||||
- Backend sets functions in ImGuiPlatformIO to manipulate platform windows.
|
||||
- ImGuiPlatformIO::Monitors is a list of platform monitors (input from backend)
|
||||
- ImGuiPlatformIO::Viewports is a list of viewports (output from dear imgui)
|
||||
- Added ImGuiPlatformMonitor to feed OS monitor information in the ImGuiPlatformIO::Monitors.
|
||||
- Added GetWindowViewport(), SetNextWindowViewport().
|
||||
- Added GetWindowDpiScale().
|
||||
- Added GetOverlayDrawList(ImGuiViewport* viewport).
|
||||
The no-parameter version of GetOverlayDrawList() return the overlay for the current window's viewport.
|
||||
- Added UpdatePlatformWindows(), RenderPlatformWindowsDefault(), DestroyPlatformWindows() for usage in application setup.
|
||||
- Added FindViewportByID(), FindViewportByPlatformHandle() for usage by backends.
|
||||
- Added ImGuiConfigFlags_ViewportsEnable configuration flag and other viewport options.
|
||||
- Added io.ConfigViewportsNoAutoMerge option.
|
||||
- Added io.ConfigViewportsNoTaskBarIcon option.
|
||||
- Added io.ConfigViewportsNoDecoration option.
|
||||
- Added io.ConfigViewportsNoDefaultParent option.
|
||||
- Added ImGuiBackendFlags_PlatformHasViewports, ImGuiBackendFlags_RendererHasViewports, ImGuiBackendFlags_HasMouseHoveredViewport backend flags.
|
||||
- Added io.AddMouseViewportEvent() (optional _even_ for multi-viewport support, tied to ImGuiBackendFlags_HasMouseHoveredViewport flag).
|
||||
- Expanded ImGuiViewport structure, ImGuiViewportFlags flags.
|
||||
- Added ImGuiWindowClass and SetNextWindowClass() for passing viewport related hints to the OS/platform back-end.
|
||||
- Examples: Renderer: OpenGL2, OpenGL3, DirectX9, DirectX10, DirectX11, DirectX12, Vulkan: Added support for multi-viewports.
|
||||
- Examples: Platforms: Win32, GLFW, SDL2: Added support for multi-viewports.
|
||||
Note that Linux/Mac still have inconsistent support for multi-viewports. If you want to help see https://github.com/ocornut/imgui/issues/2117.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.88 WIP (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Breaking changes:
|
||||
|
||||
Other Changes:
|
||||
|
||||
- IO: Fixed backward-compatibility regression introduced in 1.87: (#4921, #4858)
|
||||
- Direct accesses to io.KeysDown[] with legacy indices didn't work (with new backends).
|
||||
- Direct accesses to io.KeysDown[GetKeyIndex(XXX)] would access invalid data (with old/new backends).
|
||||
- Calling IsKeyDown() didn't have those problems, and is recommended as io.KeysDown[] is obsolete.
|
||||
- IO: Fixed input queue trickling of interleaved keys/chars events (which are frequent especially
|
||||
when holding down a key as OS submits chars repeat events) delaying key presses and mouse movements.
|
||||
In particular, using the input system for fast game-like actions (e.g. WASD camera move) would
|
||||
typically have been impacted, as well as holding a key while dragging mouse. Constraints have
|
||||
been lifted and are now only happening when e.g. an InputText() widget is active. (#4921, #4858)
|
||||
Not that even thought you shouldn't need to disable io.ConfigInputTrickleEventQueue, you can
|
||||
technically dynamically change its setting based on the context (e.g. disable only when hovering
|
||||
or interacting with a game/3D view).
|
||||
- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
|
||||
clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
|
||||
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
|
||||
return value is overriden by focus when gamepad/keyboard navigation is active.
|
||||
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
|
||||
- Stack Tool: Added option to copy item path to clipboard. (#4631)
|
||||
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
|
||||
- Misc: Added constexpr to ImVec2/ImVec4 inline constructors. (#4995) [@Myriachan]
|
||||
- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
|
||||
- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
|
||||
- Drawlist: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed floating docked nodes not being clamped into viewport workrect to stay reachable
|
||||
when g.ConfigWindowsMoveFromTitleBarOnly is set and multi-viewports are disabled. (#5044)
|
||||
- Backends: SDL: Fixed dragging out main viewport broken on some SDL setups. (#5012) [@rokups]
|
||||
- Viewports: Fixed translating a host viewport from briefly altering the size of AlwaysAutoResize windows. (#5057)
|
||||
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
|
||||
when multi-viewports are disabled. (#4900)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.87 (Released 2022-02-07)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.87
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Removed support for pre-C++11 compilers. We'll stop supporting VS2010. (#4537)
|
||||
- Reworked IO mouse input API: (#4921, #4858) [@thedmd, @ocornut]
|
||||
- Added io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions,
|
||||
obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc.
|
||||
- This enable input queue trickling to support low framerates. (#2787, #1992, #3383, #2525, #1320)
|
||||
- Reworked IO keyboard input API: (#4921, #2625, #3724) [@thedmd, @ocornut]
|
||||
- Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays.
|
||||
- For keyboard modifiers, you can call io.AddKeyEvent() with ImGuiKey_ModXXX values,
|
||||
obsoleting writing directly to io.KeyCtrl, io.KeyShift etc.
|
||||
- Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices.
|
||||
- Added full range of key enums in ImGuiKey (e.g. ImGuiKey_F1).
|
||||
- Added GetKeyName() helper function.
|
||||
- Obsoleted GetKeyIndex(): it is now unnecessary and will now return the same value.
|
||||
- All keyboard related functions taking 'int user_key_index' now take 'ImGuiKey key':
|
||||
- IsKeyDown(), IsKeyPressed(), IsKeyReleased(), GetKeyPressedAmount().
|
||||
- Added io.ConfigInputTrickleEventQueue (defaulting to true) to disable input queue trickling.
|
||||
- Backward compatibility:
|
||||
- All backends updated to use new functions.
|
||||
- Old backends populating those arrays should still work!
|
||||
- Calling e.g. IsKeyPressed(MY_NATIVE_KEY_XXX) will still work! (for a while)
|
||||
- Those legacy arrays will only be disabled if '#define IMGUI_DISABLE_OBSOLETE_KEYIO' is set in your imconfig.
|
||||
In a few versions, IMGUI_DISABLE_OBSOLETE_FUNCTIONS will automatically enable IMGUI_DISABLE_OBSOLETE_KEYIO,
|
||||
so this will be moved into the regular obsolescence path.
|
||||
- BREAKING: If your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A")
|
||||
this is a use case that will now assert and be breaking for your old backend.
|
||||
- Transition guide:
|
||||
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
|
||||
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
|
||||
- Backend writing to io.KeyMap[],KeysDown[] -> backend should call io.AddKeyEvent(), if legacy indexing is desired, call io.SetKeyEventNativeData()
|
||||
- Basically the trick we took advantage of is that we previously only supported native keycode from 0 to 511,
|
||||
so ImGuiKey values can still express a legacy native keycode, and new named keys are all >= 512.
|
||||
- This will enable a few things in the future:
|
||||
- Access to portable keys allows for backend-agnostic keyboard input code. Until now it was difficult
|
||||
to share code using keyboard across project because of this gap. (#2625, #3724)
|
||||
- Access to full key ranges will allow us to develop a proper keyboard shortcut system. (#456)
|
||||
- io.SetKeyEventNativeData() include native keycode/scancode which may later be exposed. (#3141, #2959)
|
||||
- Reworked IO nav/gamepad input API and unifying inputs sources: (#4921, #4858, #787)
|
||||
- Added full range of ImGuiKey_GamepadXXXX enums (e.g. ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadR2) to use with
|
||||
io.AddKeyEvent(), io.AddKeyAnalogEvent().
|
||||
- Added io.AddKeyAnalogEvent() function, obsoleting writing directly to io.NavInputs[] arrays.
|
||||
- Renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. (#2625)
|
||||
- Removed support for legacy arithmetic operators (+,+-,*,/) when inputing text into a slider/drag. (#4917, #3184)
|
||||
This doesn't break any api/code but a feature that was accessible by end-users (which seemingly no one used).
|
||||
(Instead you may implement custom expression evaluators to provide a better version of this).
|
||||
- Backends: GLFW: backend now uses glfwSetCursorPosCallback().
|
||||
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: nothing to do. is already done for you.
|
||||
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callback
|
||||
using glfwSetCursorPosCallback() and forward it to the backend function ImGui_ImplGlfw_CursorPosCallback().
|
||||
- Backends: SDL: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so backend can call
|
||||
SDL_GetRendererOutputSize() to obtain framebuffer size valid for hi-dpi. (#4927) [@Clownacy]
|
||||
- Commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019)
|
||||
- ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen()
|
||||
- ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x
|
||||
- ImGui::TreeAdvanceToLabelPos() -> use ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetTreeNodeToLabelSpacing());
|
||||
- ImFontAtlas::CustomRect -> use ImFontAtlasCustomRect
|
||||
- ImGuiColorEditFlags_RGB/HSV/HEX -> use ImGuiColorEditFlags_DisplayRGB/HSV/Hex
|
||||
- Removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn() for IME support.
|
||||
Because this field was mostly only ever used by Dear ImGui internally, not by backends nor the vast majority
|
||||
of user code, this should only affect a very small fraction for users who are already very IME-aware.
|
||||
- Obsoleted 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'.
|
||||
This removes an incompatibility between 'master' and 'multi-viewports' backends and toward enabling
|
||||
better support for IME. Updated backends accordingly. Because the old field is set by existing backends,
|
||||
we are keeping it (marked as obsolete).
|
||||
|
||||
Other Changes:
|
||||
|
||||
- IO: Added event based input queue API, which now trickles events to support low framerates. [@thedmd, @ocornut]
|
||||
Previously the most common issue case (button presses in low framerates) was handled by backend. This is now
|
||||
handled by core automatically for all kind of inputs. (#4858, #2787, #1992, #3383, #2525, #1320)
|
||||
- New IO functions for keyboard/gamepad: AddKeyEvent(), AddKeyAnalogEvent().
|
||||
- New IO functions for mouse: AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent().
|
||||
- IO: Unified key enums allow using key functions on key mods and gamepad values.
|
||||
- Fixed CTRL+Tab into an empty window causing artifacts on the highlight rectangle due to bad reordering on ImDrawCmd.
|
||||
- Fixed a situation where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles,
|
||||
which would makes the draw operation of some backends assert (e.g. Metal with debugging). (#4857)
|
||||
- Popups: Fixed a regression crash when a new window is created after a modal on the same frame. (#4920) [@rokups]
|
||||
- Popups: Fixed an issue when reopening a same popup multiple times would offset them by 1 pixel on the right. (#4936)
|
||||
- Tables, ImDrawListSplitter: Fixed erroneously stripping trailing ImDrawList::AddCallback() when submitted in
|
||||
last column or last channel and when there are no other drawing operation. (#4843, #4844) [@hoffstadt]
|
||||
- Tables: Fixed positioning of Sort icon on right-most column with some settings (not resizable + no borders). (#4918).
|
||||
- Nav: Fixed gamepad navigation in wrapping popups not wrapping all the way. (#4365)
|
||||
- Sliders, Drags: Fixed text input of values with a leading sign, common when using a format enforcing sign. (#4917)
|
||||
- Demo: draw a section of keyboard in "Inputs > Keyboard, Gamepad & Navigation state" to visualize keys. [@thedmd]
|
||||
- Platform IME: changed io.ImeSetInputScreenPosFn() to io.SetPlatformImeDataFn() API,
|
||||
now taking a ImGuiPlatformImeData structure which we can more easily extend in the future.
|
||||
- Platform IME: moved io.ImeWindowHandle to GetMainViewport()->PlatformHandleRaw.
|
||||
- Platform IME: add ImGuiPlatformImeData::WantVisible, hide IME composition window when not used. (#2589) [@actboy168]
|
||||
- Platform IME: add ImGuiPlatformImeData::InputLineHeight. (#3113) [@liuliu]
|
||||
- Platform IME: [windows] call ImmSetCandidateWindow() to position candidate window.
|
||||
- Backends: GLFW: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts.
|
||||
We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of
|
||||
other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625)
|
||||
- Backends: GLFW: Submit keys and key mods using io.AddKeyEvent(). (#2625, #4921)
|
||||
- Backends: GLFW: Submit mouse data using io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() functions. (#4921)
|
||||
- Backends: GLFW: Retrieve mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured.
|
||||
- Backends: GLFW: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921)
|
||||
- Backends: GLFW: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing
|
||||
callbacks after iniitializing backend. (#4981)
|
||||
- Backends: Win32: Submit keys and key mods using io.AddKeyEvent(). (#2625, #4921)
|
||||
- Backends: Win32: Retrieve mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured.
|
||||
- Backends: Win32: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921)
|
||||
- Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||
- Backends: Win32: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921)
|
||||
- Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. (#456, #2625)
|
||||
- Backends: SDL: Submit key data using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
|
||||
- Backends: SDL: Retrieve mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured.
|
||||
- Backends: SDL: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921)
|
||||
- Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted.
|
||||
- Backends: SDL: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921)
|
||||
- Backends: Allegro5: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
|
||||
- Backends: Allegro5: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921)
|
||||
- Backends: OSX: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
|
||||
- Backends: OSX: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4921)
|
||||
- Backends: OSX: Submit gamepad data using io.AddKeyEvent/AddKeyAnalogEvent() functions, stopped writing to io.NavInputs[]. (#4921)
|
||||
- Backends: OSX: Added basic Platform IME support. (#3108, #2598) [@liuliu]
|
||||
- Backends: OSX: Fix Game Controller nav mapping to use shoulder for both focusing and tweak speed. (#4759)
|
||||
- Backends: OSX: Fix building with old Xcode versions that are missing gamepad features. [@rokups]
|
||||
- Backends: OSX: Forward keyDown/keyUp events to OS when unused by Dear ImGui.
|
||||
- Backends: Android, GLUT: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625)
|
||||
- Backends: Android, GLUT: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858)
|
||||
- Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk]
|
||||
It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers.
|
||||
- Backends: OpenGL3: Fix OpenGL ES2 includes on Apple systems. [@rokups]
|
||||
- Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz]
|
||||
Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
|
||||
- Backends: Metal: Ignore ImDrawCmd where ElemCount == 0, which are normally not emitted by the library but
|
||||
can theoretically be created by user code manipulating a ImDrawList. (#4857)
|
||||
- Backends: Vulkan: Added support for ImTextureID as VkDescriptorSet, add ImGui_ImplVulkan_AddTexture(). (#914) [@martty]
|
||||
- Backends: SDL_Renderer: Fix texture atlas format on big-endian hardware (#4927) [@Clownacy]
|
||||
- Backends: WebGPU: Fixed incorrect size parameters in wgpuRenderPassEncoderSetIndexBuffer() and
|
||||
wgpuRenderPassEncoderSetVertexBuffer() calls. (#4891) [@FeepsDev]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed a CTRL+TAB crash when aiming at an empty docked window. (#4792)
|
||||
- Docking: Tabs use their own identifier instead of the Window identifier.
|
||||
(This will invalidate some stored .ini data such as last selected tab, sorry!)
|
||||
- Docking: Fixed size constraints not working on single window holding on a dock id (still doesn't work on docked windows).
|
||||
- Docking: Fixed CTRL+TAB back into a docked window not selecting menu layer when no item are on main layer.
|
||||
- Viewports, IO: Added io.AddMouseViewportEvent() function to queue hovered viewport change (when known by backend).
|
||||
- Viewports: Relaxed specs for backend supporting ImGuiBackendFlags_HasMouseHoveredViewport: it is now _optional_
|
||||
for the backend to have to ignore viewports with the _NoInputs flag when call io.AddMouseViewportEvent(). It is
|
||||
much better if they can (Win32 and GLFW 3.3+ backends can, SDL and GLFW 3.2 backends cannot, they are lacking data).
|
||||
A concrete example is: when dragging a viewport for docking, the viewport is marked with _NoInputs to allow us
|
||||
to pick the target viewports for docking. If the backend reports a viewport with _NoInputs when calling the
|
||||
io.AddMouseViewportEvent() function, then Dear ImGui will revert to its flawed heuristic to find the viewport under.
|
||||
By lowering those specs, we allow the SDL and more backend to support this, only relying on the heuristic in a few
|
||||
drag and drop situations rather that relying on it everywhere.
|
||||
- Viewports: Fixed a CTRL+TAB crash with viewports enabled when the window list needs to appears in
|
||||
its own viewport (regression from 1.86). (#4023, #787)
|
||||
- Viewports: Fixed active InputText() from preventing viewports to merge. (#4212)
|
||||
- Backends: SDL: Added support for ImGuiBackendFlags_HasMouseHoveredViewport now that its specs have been lowered.
|
||||
- (Breaking) Removed ImGuiPlatformIO::Platform_SetImeInputPos() in favor of newly standardized
|
||||
io.SetPlatformImeDataFn() function. Should not affect more than default backends.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.86 (Released 2021-12-22)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.86
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Removed CalcListClipping() function. Prefer using ImGuiListClipper which can return non-contiguous ranges.
|
||||
Please open an issue if you think you really need this function. (#3841)
|
||||
- Backends: OSX: Added NSView* parameter to ImGui_ImplOSX_Init(). (#4759) [@stuartcarnie]
|
||||
- Backends: Marmalade: Removed obsolete Marmalade backend (imgui_impl_marmalade.cpp) + example app. (#368, #375)
|
||||
Find last supported version at https://github.com/ocornut/imgui/wiki/Bindings
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Added an assertion for the common user mistake of using "" as an identifier at the root level of a window
|
||||
instead of using "##something". Empty identifiers are valid and useful in a very small amount of cases,
|
||||
but 99.9% of the time if you need an empty label you should use "##something". (#1414, #2562, #2807, #4008,
|
||||
#4158, #4375, #4548, #4657, #4796). READ THE FAQ ABOUT HOW THE ID STACK WORKS -> https://dearimgui.org/faq
|
||||
- Added GetMouseClickedCount() function, returning the number of successive clicks. (#3229) [@kudaba]
|
||||
(so IsMouseDoubleClicked(ImGuiMouseButton_Left) is same as GetMouseClickedCount(ImGuiMouseButton_Left) == 2,
|
||||
but it allows testing for triple clicks and more).
|
||||
- Modals: fixed issue hovering popups inside a child windows inside a modal. (#4676, #4527)
|
||||
- Modals, Popups, Windows: changes how appearing windows are interrupting popups and modals. (#4317) [@rokups]
|
||||
- appearing windows created from within the begin stack of a popup/modal will no longer close it.
|
||||
- appearing windows created not within the begin stack of a modal will no longer close the modal,
|
||||
and automatically appear behind it.
|
||||
- Fixed IsWindowFocused()/IsWindowHovered() issues with child windows inside popups. (#4676)
|
||||
- Nav: Ctrl+tabbing to cycle through windows is now enabled regardless of using the _NavEnableKeyboard
|
||||
configuration flag. This is part of an effort to generalize the use of keyboard inputs. (#4023, #787).
|
||||
Note that while this is active you can also moving windows (with arrow) and resize (shift+arrows).
|
||||
- Nav: tabbing now cycles through clipped items and scroll accordingly. (#4449)
|
||||
- Nav: pressing PageUp/PageDown/Home/End when in Menu layer automatically moves back to Main layer.
|
||||
- Nav: fixed resizing window from borders setting navigation to Menu layer.
|
||||
- Nav: prevent child from clipping items when using _NavFlattened and parent has a pending request.
|
||||
- Nav: pressing Esc to exit a child window reactivates the Nav highlight if it was disabled by mouse.
|
||||
- Nav: with ImGuiConfigFlags_NavEnableSetMousePos enabled: Fixed absolute mouse position when using
|
||||
Home/End leads to scrolling. Fixed not setting mouse position when a failed move request (e.g. when
|
||||
already at edge) reactivates the navigation highlight.
|
||||
- Menus: fixed closing a menu inside a popup/modal by clicking on the popup/modal. (#3496, #4797)
|
||||
- Menus: fixed closing a menu by clicking on its menu-bar item when inside a popup. (#3496, #4797) [@xndcn]
|
||||
- Menus: fixed menu inside a popup/modal not inhibiting hovering of items in the popup/modal. (#3496, #4797)
|
||||
- Menus: fixed sub-menu items inside a popups from closing the popup.
|
||||
- Menus: fixed top-level menu from not consistently using style.PopupRounding. (#4788)
|
||||
- InputText, Nav: fixed repeated calls to SetKeyboardFocusHere() preventing to use InputText(). (#4682)
|
||||
- Inputtext, Nav: fixed using SetKeyboardFocusHere() on InputTextMultiline(). (#4761)
|
||||
- InputText: made double-click select word, triple-line select line. Word delimitation logic differs
|
||||
slightly from the one used by CTRL+arrows. (#2244)
|
||||
- InputText: fixed ReadOnly flag preventing callbacks from receiving the text buffer. (#4762) [@actondev]
|
||||
- InputText: fixed Shift+Delete from not cutting into clipboard. (#4818, #1541) [@corporateshark]
|
||||
- InputTextMultiline: fixed incorrect padding when FrameBorder > 0. (#3781, #4794)
|
||||
- InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (#3781, #4794)
|
||||
- Separator: fixed cover all columns while called inside a table. (#4787)
|
||||
- Clipper: currently focused item is automatically included in clipper range.
|
||||
Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is
|
||||
still submitted. (#3841, #1725) [@GamingMinds-DanielC, @ocornut]
|
||||
- Clipper: added ForceDisplayRangeByIndices() to force a given item (or several) to be stepped out
|
||||
during a clipping operation. (#3841) [@@GamingMinds-DanielC]
|
||||
- Clipper: rework so gamepad/keyboard navigation doesn't create spikes in number of items requested
|
||||
by the clipper to display. (#3841)
|
||||
- Clipper: fixed content height declaration slightly mismatching the value of when not using a clipper.
|
||||
(an additional ItemSpacing.y was declared, affecting scrollbar range).
|
||||
- Clipper: various and incomplete changes to tame down scrolling and precision issues on very large ranges.
|
||||
Passing an explicit height to the clipper now allows larger ranges. (#3609, #3962).
|
||||
- Clipper: fixed invalid state when number of frozen table row is smaller than ItemCount.
|
||||
- Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceAllowNullID doesn't lose
|
||||
tooltip when scrolling. (#143)
|
||||
- Fonts: fixed infinite loop in ImFontGlyphRangesBuilder::AddRanges() when passing UINT16_MAX or UINT32_MAX
|
||||
without the IMGUI_USE_WCHAR32 compile-time option. (#4802) [@SlavicPotato]
|
||||
- Metrics: Added a node showing windows in submission order and showing the Begin() stack.
|
||||
- Misc: Added missing ImGuiMouseCursor_NotAllowed cursor for software rendering (when the
|
||||
io.MouseDrawCursor flag is enabled). (#4713) [@nobody-special666]
|
||||
- Misc: Fixed software mouse cursor being rendered multiple times if Render() is called more than once.
|
||||
- Misc: Fix MinGW DLL build issue (when IMGUI_API is defined). [@rokups]
|
||||
- CI: Add MinGW DLL build to test suite. [@rokups]
|
||||
- Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce
|
||||
likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling
|
||||
vkCmdSetScissor() explicitly every frame. (#4644)
|
||||
- Backends: OpenGL3: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports
|
||||
with some Intel HD drivers, and perhaps improve performances. (#4468, #4504, #2981, #3381) [@parbo]
|
||||
- Backends: OpenGL2, Allegro5, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field.
|
||||
This is an old bug, but due to the way we created drawlists, it never had any visible side-effect before.
|
||||
The new code for handling Modal and CTRL+Tab dimming/whitening recently made the bug surface. (#4790)
|
||||
- Backends: Win32: Store left/right variants of Ctrl/Shift/Alt mods in KeysDown[] array. (#2625) [@thedmd]
|
||||
- Backends: DX12: Fixed DRAW_EMPTY_SCISSOR_RECTANGLE warnings. (#4775)
|
||||
- Backends: SDL_Renderer: Added support for large meshes (64k+ vertices) with 16-bit indices,
|
||||
enabling 'ImGuiBackendFlags_RendererHasVtxOffset' in the backend. (#3926) [@rokups]
|
||||
- Backends: SDL_Renderer: Fix for SDL 2.0.19+ RenderGeometryRaw() API signature change. (#4819) [@sridenour]
|
||||
- Backends: OSX: Generally fix keyboard support. Keyboard arrays indexed using kVK_* codes, e.g.
|
||||
ImGui::IsKeyPressed(kVK_Space). Don't set mouse cursor shape unconditionally. Handle two fingers scroll
|
||||
cancel event. (#4759, #4253, #1873) [@stuartcarnie]
|
||||
- Backends: OSX: Add Game Controller support (need linking GameController framework) (#4759) [@stuartcarnie]
|
||||
- Backends: WebGPU: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer() and
|
||||
wgpuRenderPassEncoderSetIndexBuffer() functions as validation layers appears to not do what the
|
||||
in-flux specs says. (#4766) [@meshula]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Revert removal of io.ConfigDockingWithShift config option (removed in 1.83). (#4643)
|
||||
- Docking: Fixed a bug undocking windows docked into a non-visible or _KeepAliveOnly dockspace
|
||||
when unrelated windows submitted before the dockspace have dynamic visibility. (#4757)
|
||||
- Docking, Style: Docked windows honor ImGuiCol_WindowBg. (#2700, #2539)
|
||||
- Docking, Style: Docked windows honor display their border properly. (#2522)
|
||||
- Docking: Fixed incorrectly rounded tab bars for dock node that are not at the top of their dock tree.
|
||||
- Docking: Fixed single-frame node pos/size inconsistencies when window stop or start being submitted.
|
||||
- Docking: Prevent docking any window created above a popup/modal. (#4317)
|
||||
- Viewports: Made it possible to explicitly assign ImGuiWindowClass::ParentViewportId to 0 in order
|
||||
to ensure a window is not parented. Previously this would use the global default (which might be 0,
|
||||
but not always as it would depend on io.ConfigViewportsNoDefaultParent). (#3152, #2871)
|
||||
- Viewports: Fixed tooltip in own viewport over modal from being incorrectly dimmed. (#4729)
|
||||
- Viewports: Fixed CTRL+TAB highlight outline on docked windows not always fitting in host viewport.
|
||||
- Backends: Made it possible to shutdown default Platform Backends before the Renderer backends. (#4656)
|
||||
- Disabled: Fixed nested BeginDisabled()/EndDisabled() bug in Docking branch due to bad merge. (#4655, #4452, #4453, #4462)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.85 (Released 2021-10-12)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.85
|
||||
|
||||
This is the last release officially supporting C++03 and Visual Studio 2008/2010. (#4537)
|
||||
We expect that the next release will require a subset of the C++11 language (VS 2012~, GCC 4.8.1, Clang 3.3).
|
||||
We may use some C++11 language features but we will not use any C++ library headers.
|
||||
If you are stuck on ancient compiler you may need to stay at this version onward.
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Removed GetWindowContentRegionWidth() function. keep inline redirection helper.
|
||||
Can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead but it's not
|
||||
very useful in practice, and the only use of it in the demo was illfit.
|
||||
Using 'GetContentRegionAvail().x' is generally a better choice.
|
||||
- (Docking branch) IsWindowFocused() and IsWindowHovered() with only the _ChildWindows flag
|
||||
and without the _RootWindow flag used to leak docking hierarchy, so a docked window would
|
||||
return as the child of the window hosting the dockspace. This was inconsistent and incorrect
|
||||
with other behaviors so we fixed it. Added a new _DockHierarchy flag to opt-in this behavior.
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Debug: Stack Tool: Added "Stack Tool" available in "Demo->Tools->Stack Tool", "Metrics->Tools",
|
||||
or by calling the ShowStackToolWindow() function. The tool run queries on hovered id to display
|
||||
details about individual components that were hashed to create an ID. It helps understanding
|
||||
the ID stack system and debugging potential ID collisions. (#4631) [@ocornut, @rokups]
|
||||
- Windows: Fixed background order of overlapping childs submitted sequentially. (#4493)
|
||||
- IsWindowFocused: Added ImGuiFocusedFlags_NoPopupHierarchy flag allowing to exclude child popups
|
||||
from the tested windows when combined with _ChildWindows.
|
||||
- IsWindowHovered: Added ImGuiHoveredFlags_NoPopupHierarchy flag allowing to exclude child popups
|
||||
from the tested windows when combined with _ChildWindows.
|
||||
- InputTextMultiline: Fixed label size not being included into window contents rect unless
|
||||
the whole widget is clipped.
|
||||
- InputText: Allow activating/cancelling/validating input with gamepad nav events. (#2321, #4552)
|
||||
- InputText: Fixed selection rectangle appearing one frame late when selecting all.
|
||||
- TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform
|
||||
to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615)
|
||||
- Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211)
|
||||
- Nav: Fixed using SetKeyboardFocusHere() on non-visible/clipped items. It now works and will scroll
|
||||
toward the item. When called during a frame where the parent window is appearing, scrolling will
|
||||
aim to center the item in the window. When calling during a frame where the parent window is already
|
||||
visible, scrolling will aim to scroll as little as possible to make the item visible. We will later
|
||||
expose scroll functions and flags in public API to select those behaviors. (#343, #4079, #2352)
|
||||
- Nav: Fixed using SetKeyboardFocusHere() from activating a different item on the next frame if
|
||||
submitted items have changed during that frame. (#432)
|
||||
- Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when
|
||||
the ImGuiConfigFlags_NavEnableSetMousePos config flag is set.
|
||||
- Nav: Fixed a few widgets from not setting reference keyboard/gamepad navigation ID when
|
||||
activated with mouse. More specifically: BeginTabItem(), the scrolling arrows of BeginTabBar(),
|
||||
the arrow section of TreeNode(), the +/- buttons of InputInt()/InputFloat(), Selectable() with
|
||||
ImGuiSelectableFlags_SelectOnRelease. More generally: any direct use of ButtonBehavior() with
|
||||
the PressedOnClick/PressedOnDoubleClick/PressedOnRelease button policy.
|
||||
- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation
|
||||
is disabled. (#4547, #4439) [@PathogenDavid]
|
||||
- Nav: Fixed vertical scoring offset when wrapping on Y in a decorated window.
|
||||
- Nav: Improve scrolling behavior when navigating to an item larger than view.
|
||||
- TreePush(): removed unnecessary/inconsistent legacy behavior where passing a NULL value to
|
||||
the TreePush(const char*) and TreePush(const void*) functions would use an hard-coded replacement.
|
||||
The only situation where that change would make a meaningful difference is TreePush((const char*)NULL)
|
||||
(_explicitly_ casting a null pointer to const char*), which is unlikely and will now crash.
|
||||
You may replace it with anything else.
|
||||
- ColorEdit4: Fixed not being able to change hue when saturation is 0. (#4014) [@rokups]
|
||||
- ColorEdit4: Fixed hue resetting to 0 when it is set to 255. [@rokups]
|
||||
- ColorEdit4: Fixed hue value jitter when source color is stored as RGB in 32-bit integer and perform
|
||||
RGB<>HSV round trips every frames. [@rokups]
|
||||
- ColorPicker4: Fixed picker being unable to select exact 1.0f color when dragging toward the edges
|
||||
of the SV square (previously picked 0.999989986f). (#3517) [@rokups]
|
||||
- Menus: Fixed vertical alignments of MenuItem() calls within a menu bar (broken in 1.84). (#4538)
|
||||
- Menus: Improve closing logic when moving diagonally in empty between between parent and child menus to
|
||||
accommodate for varying font size and dpi.
|
||||
- Menus: Fixed crash when navigating left inside a child window inside a sub-menu. (#4510).
|
||||
- Menus: Fixed an assertion happening in some situations when closing nested menus (broken in 1.83). (#4640)
|
||||
- Drag and Drop: Fixed using BeginDragDropSource() inside a BeginChild() that returned false. (#4515)
|
||||
- PlotHistogram: Fixed zero-line position when manually specifying min<0 and max>0. (#4349) [@filippocrocchini]
|
||||
- Misc: Added asserts for missing PopItemFlag() calls.
|
||||
- Misc: Fixed printf-style format checks on Clang+MinGW. (#4626, #4183, #3592) [@guusw]
|
||||
- IO: Added 'io.WantCaptureMouseUnlessPopupClose' alternative to `io.WantCaptureMouse'. (#4480)
|
||||
This allows apps to receive the click on void when that click is used to close popup (by default,
|
||||
clicking on a void when a popup is open will close the popup but not release io.WantCaptureMouse).
|
||||
- Fonts: imgui_freetype: Fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL
|
||||
(which apparently happens with Freetype 2.11). (#4394, #4145?).
|
||||
- Fonts: Fixed ImFontAtlas::ClearInputData() marking atlas as not built. (#4455, #3487)
|
||||
- Backends: Added more implicit asserts to detect invalid/redundant calls to Shutdown functions. (#4562)
|
||||
- Backends: OpenGL3: Fixed our custom GL loader conflicting with user using GL3W. (#4445) [@rokups]
|
||||
- Backends: WebGPU: Fixed for latest specs. (#4472, #4512) [@Kangz, @bfierz]
|
||||
- Backends: SDL_Renderer: Added SDL_Renderer backend compatible with upcoming SDL 2.0.18. (#3926) [@1bsyl]
|
||||
- Backends: Metal: Fixed a crash when clipping rect larger than framebuffer is submitted via
|
||||
a direct unclipped PushClipRect() call. (#4464)
|
||||
- Backends: OSX: Use mach_absolute_time as CFAbsoluteTimeGetCurrent can jump backwards. (#4557, #4563) [@lfnoise]
|
||||
- Backends: All renderers: Normalize clipping rect handling across backends. (#4464)
|
||||
- Examples: Added SDL + SDL_Renderer example in "examples/example_sdl_sdlrenderer/" folder. (#3926) [@1bsyl]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- IsWindowFocused: Fixed using ImGuiFocusedFlags_ChildWindows (without _RootWindow) from leaking the
|
||||
docking hierarchy. Added ImGuiFocusedFlags_DockHierarchy flag to consider docking hierarchy in the test.
|
||||
- IsWindowHovered: Fixed using ImGuiHoveredFlags_ChildWindows (without _RootWindow) from leaking the
|
||||
docking hierarchy. Added ImGuiHoveredFlags_DockHierarchy flag to consider docking hierarchy in the test.
|
||||
- Nav: Fixed an issue with losing focus on docked windows when pressing Alt while keyboard navigation
|
||||
is disabled. (#4547, #4439) [@PathogenDavid]
|
||||
- Docking: Fixed IsItemHovered() and functions depending on it (e.g. BeginPopupContextItem()) when
|
||||
called after Begin() on a docked window (broken 2021/03/04). (#3851)
|
||||
- Docking: Improved resizing system so that non-central zone are better at keeping their fixed size.
|
||||
The algorithm is still not handling the allocation of size ideally for nested sibling, but it got better.
|
||||
- Docking: Fixed settings load issue when mouse wheeling. (#4310)
|
||||
- Docking: Fixed manually created floating node with a central node from not hiding when windows are gone.
|
||||
- Docking + Drag and Drop: Fixed using BeginDragDropSource() or BeginDragDropTarget() inside a Begin()
|
||||
that returned false because the window is docked. (#4515)
|
||||
- Viewports: Fixed a crash while a window owning its viewport disappear while being dragged.
|
||||
It would manifest when e.g. reconfiguring dock nodes while dragging.
|
||||
- Viewports: Fixed unnecessary creation of temporary viewports when multiple docked windows
|
||||
got reassigned to a new node (created mid-frame) which already has a HostWindow.
|
||||
- Viewports: Fixed window with viewport ini data immediately merged into a host viewport from
|
||||
leaving a temporary viewport alive for a frame (would leak into backend).
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.84.2 (Released 2021-08-23)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.2
|
||||
|
||||
- Disabled: Fixed nested BeginDisabled()/EndDisabled() calls. (#211, #4452, #4453, #4462) [@Legulysse]
|
||||
- Backends: OpenGL3: OpenGL: Fixed ES 3.0 shader ("#version 300 es") to use normal precision
|
||||
floats. Avoid wobbly rendering at HD resolutions. (#4463) [@nicolasnoble]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.84.1 (Released 2021-08-20)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.84.1
|
||||
|
||||
- Disabled: Fixed BeginDisabled(false) - BeginDisabled(true) was working. (#211, #4452, #4453)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.84 (Released 2021-08-20)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -146,6 +673,23 @@ Other Changes:
|
||||
- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg.
|
||||
- Examples: SDL2: Accommodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Clicking on the right-most close button of a docking node closes all windows. (#4186)
|
||||
- Docking: Fix IsWindowAppearing() and ImGuiCond_Appearing on docked windows. (#4177, #3982, #1497, #1061)
|
||||
- Docking: Fix crash using DockBuilderRemoveNode() in some situations. (#3111, #3179, #3203, #4295) [@hsimyu]
|
||||
- Docking: Fix crash when a dock node gets re-qualified as dockspace>floating>dockspace, which tends to happen
|
||||
when incorrectly calling DockBuilderAddNode() without ImGuiDockNodeFlags_Dockspace and using it as a Dockspace
|
||||
on the next frame after the floating window hosting the node has been automatically created. (#3203, #4295)
|
||||
- Docking: Reworked node flags saving/inheritance so that flags enforced by docked windows via the
|
||||
DockNodeFlagsOverrideSet mechanism are are not left in empty dockspace nodes once the windows gets undocked.
|
||||
(#4292, #3834, #3633, #3521, #3492, #3335, #2999, #2648)
|
||||
- Docking: (Internal/Experimental) Removed DockNodeFlagsOverrideClear flags from ImGuiWindowClass as
|
||||
it is ambiguous how to apply them and we haven't got a use out of them yet.
|
||||
- Viewports: Fix popup/tooltip created without a parent window from being given a ParentViewportId value
|
||||
from the implicit/fallback window. (#4236, #2409)
|
||||
- Backends: Vulkan: Fix the use of the incorrect fence for secondary viewports. (#4208) [@FunMiles]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.83 (Released 2021-05-24)
|
||||
@@ -230,6 +774,22 @@ Other Changes:
|
||||
- Docs: Improvements to description of using colored glyphs/emojis. (#4169, #3369)
|
||||
- Docs: Improvements to minor mistakes in documentation comments (#3923) [@ANF-Studios]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- [Breaking] Removed io.ConfigDockingWithShift config option. Behavior always equivalent to having the
|
||||
option set to false (dock/undock by default, hold shift to avoid docking). (#2109)
|
||||
- Docking: DockSpace() returns its node ID.
|
||||
- Docking: Dockspace() never draws a background. (#3924)
|
||||
- Docking: Undocking nodes/windows covering most of the monitor max their size down to 90% to ease manipulations.
|
||||
- Docking: Docking node tab bar honors ItemInnerSpacing.x before first tab. (#4130)
|
||||
- Docking: Tweak rendering and alignment of dock node menu marker. (#4130)
|
||||
- Docking: Fixed restoring of tab order within a dockspace or a split node.
|
||||
- Docking: Fixed reappearing docked windows with no close button showing a tab with extraneous space for one frame.
|
||||
- Docking: Fixed multiple simultaneously reappearing window from appearing undocked for one frame.
|
||||
- Viewports: Hotfix for crash in monitor array access, caused by 4b9bc4902. (#3967)
|
||||
- Backends, Viewports: GLFW: Add a workaround for stuck keys after closing a GLFW window (#3837).
|
||||
- Backends, Viewports: Vulkan: Rebuild swapchain on VK_SUBOPTIMAL_KHR. (#3881)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.82 (Released 2021-02-15)
|
||||
@@ -325,6 +885,13 @@ Other Changes:
|
||||
scheduled builds builds are not required. [@rokups]
|
||||
- Log/Capture: Added LogTextV, a va_list variant of LogText. [@PathogenDavid]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Fix setting of ImGuiViewportFlags_NoRendererClear. (#3213)
|
||||
- Viewports: Added GetViewportPlatformMonitor() with a safety net to keep code portable.
|
||||
- Viewports, Backends: SDL: Fix missing ImGuiBackendFlags_HasSetMousePos flag in docking branch.
|
||||
- Viewports, Backends: GLFW: Fix application of WantSetMousePos. (#1542, #787)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.81 (Released 2021-02-10)
|
||||
@@ -406,6 +973,17 @@ Other Changes:
|
||||
- Examples: WebGPU: Added Emscripten+WebGPU example. (#3632) [@bfierz]
|
||||
- Backends: GLFW: Added ImGui_ImplGlfw_InitForOther() initialization call to use with non OpenGL API. (#3632)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fix losing docking information on closed windows for which the hosting node was split. (#3716) [@GamingMinds-DanielC]
|
||||
- Docking: Fix gap in hit test hole when using ImGuiDockNodeFlags_PassthruCentralNode touching the edge of a viewport. (#3733)
|
||||
- Viewports: (Breaking) removed ImGuiPlatformIO::MainViewport which is now pretty much unused and duplicate
|
||||
(and misleading as we will evolve the concept).
|
||||
- Viewports: (Breaking) turned ImGuiViewport::GetWorkPos(), ImGuiViewport::GetWorkSize() into regular fields
|
||||
(WorkPos, WorkSize) before exposing in master branch.
|
||||
- Viewports: Fix issue inferring viewport z-order when new popups gets created. (#3734) + Metrics updates.
|
||||
- Viewports, Backends: Vulkan: handle VK_ERROR_OUT_OF_DATE_KHR when resizing secondary viewport (#3766, #3758)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.80 (Released 2021-01-21)
|
||||
@@ -525,6 +1103,14 @@ Other Changes:
|
||||
- Docs: Split examples/README.txt into docs/BACKENDS.md and docs/EXAMPLES.md, and improved them.
|
||||
- Docs: Consistently renamed all occurrences of "binding" and "back-end" to "backend" in comments and docs.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Docked windows honor change of tab and text colors. (#2771)
|
||||
- Docking: Support for appending into existing tab-bar made to work with Docking + internal helper DockNodeBeginAmendTabBar().
|
||||
- Docking: Added experimental TabItemFlagsOverrideSet to ImGuiWindowClass.
|
||||
- Viewports: Fixed incorrect whitening of popups above a modal if both use their own viewport.
|
||||
- Viewports: Backends: Vulkan: Fixed build, removed extraneous pipeline creation. (#3459, #3579)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.79 (Released 2020-10-08)
|
||||
@@ -619,6 +1205,21 @@ Other Changes:
|
||||
- Examples: DX12: Added '#define ImTextureID ImU64' in project and build files to also allow building
|
||||
on 32-bit systems. Added project to default Visual Studio solution file. (#301)
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: DockSpace() emits ItemSize() properly (useful when not filling all space).
|
||||
- Docking: Fixed docking while hovering a child window. (#3420) broken by 85a661d. Improve metrics debugging.
|
||||
- Docking: Fix honoring payload filter with overlapping nodes (we incorrectly over-relied on g.HoveredDockNode
|
||||
when making change for #3398).
|
||||
- Docking: Fix handling of WindowMenuButtonPosition == ImGuiDir_None in Docking Nodes. (#3499)
|
||||
- Viewports: Fixed a rare edge-case if the window targeted by CTRL+Tab stops being rendered.
|
||||
- Viewports, Backends: DX12: Make secondary viewport format match main viewport one (#3462) {@BeastLe9enD]
|
||||
- Viewports: Backends: Vulkan: Removed unused shader code. Fix leaks. Avoid unnecessary pipeline creation for main
|
||||
viewport. (#3459) + Add ImGui_ImplVulkanH_CreateWindowSwapChain in ImGui_ImplVulkanH_CreateOrResizeWindow().
|
||||
- Viewports: Backends: DirectX9: Recover from D3DERR_DEVICELOST on secondary viewports. (#3424)
|
||||
- Viewports, Backends: Win32: Fix toggling of ImGuiViewportFlags_TopMost (#3477) [@Kodokuna]
|
||||
- Viewports: Backends: GLFW: Workaround for cases where glfwGetMonitorWorkarea fails (#3457) [@dougbinks]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.78 (Released 2020-08-18)
|
||||
@@ -720,6 +1321,23 @@ Other Changes:
|
||||
- Examples: Vulkan: Fixed GLFW+Vulkan and SDL+Vulkan clear color not being set. (#3390) [@RoryO]
|
||||
- CI: Emscripten has stopped their support for their fastcomp backend, switching to latest sdk [@Xipiryon]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Made DockBuilderAddNode() automatically call DockBuilderRemoveNode(). (#3399, #2109)
|
||||
- Docking: Storing HoveredDockNode in context which can be useful for easily detecting e.g. hovering an
|
||||
empty node. (#3398)
|
||||
- Docking: Fixed docking overlay bits appearing at (0,0), because of 43bd80a. Most typically noticeable
|
||||
when disabling multi-viewport.
|
||||
- Docking: Workaround recovery for node created without the _DockSpace flags later becoming a DockSpace. (#3340)
|
||||
- Docking: Rework size allocations to recover when there's no enough room for nodes + do not hold on
|
||||
_WantLockSizeOnce forever. (#3328)
|
||||
- Docking: Rework size allocation to allow user code to override node sizes. Not all edge cases will be
|
||||
properly handled but this is a step toward toolbar emitting size constraints.
|
||||
- Docking: Added experimental flags to perform more docking filtering and disable resize per axis.
|
||||
Designed for toolbar patterns.
|
||||
- Viewports, Backends, GLFW: Use GLFW_MOUSE_PASSTHROUGH when available.
|
||||
- Viewports, Backends: DX12: Fixed issue on shutdown when viewports are disabled. (#3347)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.77 (Released 2020-06-29)
|
||||
@@ -811,6 +1429,17 @@ Other Changes:
|
||||
- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm
|
||||
not forwarding right and center mouse clicks. (#3260) [@nburrus]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Viewports: Don't set ImGuiViewportFlags_NoRendererClear when ImGuiWindowFlags_NoBackground is set. (#3213)
|
||||
- Viewports: Report minimized viewports as zero DisplaySize to be consistent with main branch. (#1542)
|
||||
- Docking, Settings: Allow reload of settings data at runtime. (#2573)
|
||||
- Backends, GLFW: Fix windows resizing incorrectly on Linux due to GLFW firing window positioning
|
||||
callbacks on next frame after window is resized manually. (#2117)
|
||||
- Backends: DX12: Fix OBJECT_DELETED_WHILE_STILL_IN_USE on viewport resizing. (#3210)
|
||||
- Backends: DX12: Fix for crash caused by early resource release. (#3121)
|
||||
- Backends, Win32: Request monitor update when DPI awareness is enabled to make sure they have the correct DPI settings.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.76 (Released 2020-04-12)
|
||||
@@ -883,6 +1512,20 @@ Other Changes:
|
||||
- Examples: SDL+DX11: Fixed resizing main window. (#3057) [@joeslay]
|
||||
- Examples: Added SDL+Metal example application. (#3017) [@coding-jackalope]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fixed assert preventing dockspace from being created instead a hidden tab. (#3101)
|
||||
- Viewports: Fixed secondary viewports accidentally merging into a minimized host viewport. (#3118)
|
||||
- Viewports, Docking: Added per-viewport work area system for e.g. menu-bars. Fixed DockspaceOverViewport()
|
||||
and demo code (overlay etc) accordingly. (#3035, #2889, #2474, #1542, #2109)
|
||||
- Viewports: Improve menu positioning in multi-monitor setups. [@rokups]
|
||||
- Viewports: Software mouse cursor is also scaled by current DpiScale. (amend #939)
|
||||
- Viewports: Avoid manually clipping resize grips and borders, which messes up with automation ability
|
||||
to locate those items. Also simpler and more standard.
|
||||
- Viewports: Fix for UWP in the imgui_impl_win32.cpp IME handler. (#2895, #2892).
|
||||
- Viewports: Bunch of extra of comments to facilitate setting up multi-viewports.
|
||||
- Viewports, GLFW: Avoid using window positioning workaround for GLFW 3.3+ versions that have it fixed.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.75 (Released 2020-02-10)
|
||||
@@ -981,6 +1624,21 @@ Other Changes:
|
||||
- Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed
|
||||
even if underlying system event loop gets paused due to app nap. (#2910, #2917) [@bear24rw]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking + Nav: Fixed messed up Ctrl+Tab order with docked windows.
|
||||
- Docking + Nav: Fixed failing to restore NavId when refocusing a child within a docked window.
|
||||
- Docking + Nav: Fixed failing to restore NavId when refocusing due to missing nav window (when
|
||||
it stops being submitted).
|
||||
- Docking: Fixed a bug where the tab bar of a hidden dockspace would keep requesting focus. (#2960)
|
||||
- Docking: Added experimental DockNodeFlagsOverrideSet/DockNodeFlagsOverrideClear flags in ImGuiWindowClass
|
||||
(currently experimenting with toolbar idioms).
|
||||
- Viewports: Fix resizing viewport-owning windows when mouse pos is outside the InnerClipRect
|
||||
(can happen with OS decoration enabled).
|
||||
- Viewports: Preserve last known size for minimized main viewport to be consistent with secondary viewports.
|
||||
- Backends: SDL: Honor NoTaskBarIcon flag under non Win32 OS. (#2117)
|
||||
- Backends: GLFW, SDL: Platform monitors declared properly even if multi-viewport is not enabled.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.74 (Released 2019-11-25)
|
||||
@@ -1060,6 +1718,14 @@ Other Changes:
|
||||
- CI: Set up a bunch of continuous-integration tests using GitHub Actions. We now compile many of the example
|
||||
applications on Windows, Linux, MacOS, iOS, Emscripten. Removed Travis integration. (#2865) [@rokups]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Can undock from the small triangle button. (#2109,. #2645)
|
||||
- Docking: Fixed node->HasCloseButton not honoring ImGuiDockNodeFlags_NoCloseButton in a floating node,
|
||||
leading to empty space at the right of tab-bars with those flags. (#2109)
|
||||
- Docking: Made docked windows not use style.ChildRounding.
|
||||
- Multi-viewports: Added multi-viewport support in the DX12 back-end. (#2851) [@obfuscate]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.73 (Released 2019-09-24)
|
||||
@@ -1122,6 +1788,28 @@ Other Changes:
|
||||
- Misc: Updated stb_rect_pack.h from 0.99 to 1.00 (fixes by @rygorous: off-by-1 bug in best-fit heuristic,
|
||||
fix handling of rectangles too large to fit inside texture). (#2762) [@tido64]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Fix BeginDocked() path that creates node so that SetNextWindowDockID() doesn't immediately discard the node. (#2109)
|
||||
- Docking: Fix for node created at the same time as windows that are still resizing (typically with
|
||||
io.ConfigDockingAlwaysTabBar) to not be zero/min sized. (#2109). The fix delays their visibility by one frame,
|
||||
which is not ideal but not very problematic as the .ini data gets populated after that.
|
||||
- Docking: Fix a crash that could occur with a malformed ini file (DockNode Parent value pointing to a missing node).
|
||||
- Viewport: Fix modal/popup window being stuck in unowned hidden viewport associated to fallback window without stealing
|
||||
it back. Fix modal reference viewport when opened outside of another window. (#1542)
|
||||
- Viewport: Modals don't need to set ImGuiViewportFlags_NoFocusOnClick, this also mitigate the issue described by #2445,
|
||||
which becomes particularly bad with unfocused modal. (#1542)
|
||||
- Viewport: better case case where host window gets moved and resized simultaneous (toggling maximized state).
|
||||
There's no perfect solution there, than using io.ConfigViewportsNoAutoMerge = false. (#1542)
|
||||
- Viewport, Docking: Fixed incorrect assignment of IsFallbackWindow which would tag dock node host windows created
|
||||
in NewFrame() as such, messing with popup viewport inheritance.
|
||||
- Viewport: Fixed issue where resize grip would display as hovered while mouse is still off the OS bounds so a click
|
||||
would miss it and focus the OS window behind expected one. (#1542)
|
||||
- Viewport: Fix to allow multiple shutdown / calls to DestroyPlatformWindows(). (#2769)
|
||||
- Viewport: Backends: GLFW: Fix setting window size on macOS (#2767, #2117) [@rokups]
|
||||
- Viewport: Backends: GLFW+Linux: Fix window having incorrect size after uncollapse. (#2756, #2117) [@rokups]
|
||||
- Viewport: Backends: DirectX9: Workaround for windows not refreshing when main viewport has no draw call. (#2560)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.72b (Released 2019-07-31)
|
||||
@@ -1224,6 +1912,25 @@ Other Changes:
|
||||
(#2482, #2632) [@josiahmanson]
|
||||
- Examples: Added SDL2+DirectX11 example application. (#2632, #2612, #2482) [@vincenthamm]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Docking: Making it possible to undock a node by clicking on the tab bar / title bar for the node. (#2645).
|
||||
- Docking: Explicitly inhibit constraint when docked for now. Fix clipping issue related to constraints. (#2690).
|
||||
- Docking: Fixed dragging/resizing from OS decoration not marking settings as dirty.
|
||||
- Docking: Renamed io.ConfigDockingTabBarOnSingleWindows to io.ConfigDockingAlwaysTabBar.
|
||||
Added ImGuiWindowClass::DockingAlwaysTabBar to set on individual windows.
|
||||
- Docking: Perform simple check: assert if Docking or Viewport are enabled exactly on frame 1 (instead of frame 0
|
||||
or later), which is a common user error leading to loss of .ini data on load.
|
||||
- Docking: Fix so that an appearing window making a dock node reappear won't have a zero-size on its first frame.
|
||||
- Docking: Fixed using ImGuiDockNodeFlags_AutoHideTabBar with io.ConfigDockingTabBarOnSingleWindows.
|
||||
- Docking: Added ImGuiDockNode to .natvis file.
|
||||
- Docking: Fixed support for large meshes in GetBackgroundDrawList(), GetForegroundDrawList(). (#2638)
|
||||
- Viewport: Fix monitor dpi info not being copied to main viewport when multi-viewports are not enabled. (#2621, #1676)
|
||||
- Viewport: Refactored ImGuiWindowClass's ViewportFlagsOverrideMask + ViewportFlagsOverrideValue into
|
||||
ViewportFlagsOverrideSet + ViewportFlagsOverrideClear which appears easier to grasp. (#1542)
|
||||
- Viewport: Added ImGuiViewportFlags_NoAutoMerge to prevent merging into host viewport in a per-window basis
|
||||
via the ImGuiWindowClass override mechanism. (#1542)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.71 (Released 2019-06-12)
|
||||
@@ -1563,6 +2270,7 @@ Breaking Changes:
|
||||
- Renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Added BETA api for Tab Bar/Tabs widgets: (#261, #351)
|
||||
- Added BeginTabBar(), EndTabBar(), BeginTabItem(), EndTabItem(), SetTabItemClosed() API.
|
||||
- Added ImGuiTabBarFlags flags for BeginTabBar().
|
||||
|
||||
@@ -72,7 +72,7 @@ Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui
|
||||
Please read the comments and instruction at the top of each file.
|
||||
Please read FAQ at http://www.dearimgui.org/faq
|
||||
|
||||
If you are using of the backend provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h)
|
||||
If you are using any of the backends provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h)
|
||||
files to your project and use as-in. Each imgui_impl_xxxx.cpp file comes with its own individual
|
||||
Changelog, so if you want to update them later it will be easier to catch up with what changed.
|
||||
|
||||
@@ -141,10 +141,6 @@ GLUT (e.g., FreeGLUT on Linux/Windows, GLUT framework on OSX) + OpenGL2 example.
|
||||
= main.cpp + imgui_impl_glut.cpp + imgui_impl_opengl2.cpp <BR>
|
||||
Note that GLUT/FreeGLUT is largely obsolete software, prefer using GLFW or SDL.
|
||||
|
||||
[example_marmalade/](https://github.com/ocornut/imgui/blob/master/examples/example_marmalade/) <BR>
|
||||
Marmalade example using IwGx. <BR>
|
||||
= main.cpp + imgui_impl_marmalade.cpp
|
||||
|
||||
[example_null/](https://github.com/ocornut/imgui/blob/master/examples/example_null/) <BR>
|
||||
Null example, compile and link imgui, create context, run headless with no inputs and no graphics output. <BR>
|
||||
= main.cpp <BR>
|
||||
@@ -175,6 +171,12 @@ SDL2 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR>
|
||||
This uses more modern OpenGL calls and custom shaders. <BR>
|
||||
This may actually also work with OpenGL 2.x contexts! <BR>
|
||||
|
||||
[example_sdl_sdlrenderer/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_sdlrenderer/) <BR>
|
||||
SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer (most graphics backends are supported underneath) <BR>
|
||||
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_sdlrenderer.cpp <BR>
|
||||
This requires SDL 2.0.17+ (expected to release November 2021) <BR>
|
||||
We do not really recommend using SDL_Renderer as it is a rather primitive API.
|
||||
|
||||
[example_sdl_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl_vulkan/) <BR>
|
||||
SDL2 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
||||
= main.cpp + imgui_impl_sdl.cpp + imgui_impl_vulkan.cpp <BR>
|
||||
@@ -220,7 +222,7 @@ If you are interested in using Cmake to build and links examples, see:
|
||||
**About mouse cursor latency**
|
||||
|
||||
Dear ImGui has no particular extra lag for most behaviors,
|
||||
e.g. the value of 'io.MousePos' provided at the time of 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.
|
||||
|
||||
However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated
|
||||
|
||||
33
docs/FAQ.md
33
docs/FAQ.md
@@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
|
||||
| [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) |
|
||||
| **Q&A: Usage** |
|
||||
| **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
|
||||
| **[About the ID Stack system..<br>Why is my widget not reacting when I click on it?<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 use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-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) |
|
||||
@@ -94,6 +94,8 @@ Read [BACKENDS.md](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md
|
||||
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.
|
||||
|
||||
For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
||||
---
|
||||
@@ -112,7 +114,7 @@ void MyLowLevelMouseButtonHandler(int button, bool down)
|
||||
{
|
||||
// (1) ALWAYS forward mouse data to ImGui! This is automatic with default backends. With your own backend:
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseDown[button] = down;
|
||||
io.AddMouseButtonEvent(button, down);
|
||||
|
||||
// (2) ONLY forward mouse data to your underlying app/game.
|
||||
if (!io.WantCaptureMouse)
|
||||
@@ -137,7 +139,7 @@ void MyLowLevelMouseButtonHandler(int button, bool down)
|
||||
- The gamepad/keyboard navigation is fairly functional and keeps being improved. The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. Gamepad support is particularly useful to use Dear ImGui on a game console (e.g. PS4, Switch, XB1) without a mouse connected!
|
||||
- Keyboard: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard` to enable.
|
||||
- Gamepad: set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad` to enable (with a supporting backend).
|
||||
- See [Control Sheets for Gamepads](http://www.dearimgui.org/controls_sheets) (reference PNG/PSD for for PS4, XB1, Switch gamepads).
|
||||
- See [Control Sheets for Gamepads](http://www.dearimgui.org/controls_sheets) (reference PNG/PSD for PS4, XB1, Switch gamepads).
|
||||
- See `USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS` section of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) for more details.
|
||||
|
||||
##### [Return to Index](#index)
|
||||
@@ -160,7 +162,7 @@ Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-lik
|
||||
---
|
||||
|
||||
### Q: I integrated Dear ImGui in my engine and little squares are showing instead of text...
|
||||
Your renderer is not using the font texture correctly or it hasn't be uploaded to GPU.
|
||||
Your renderer 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 could happens if for some reason your texture is too big. Also see [docs/FONTS.md](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md).
|
||||
- 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.
|
||||
|
||||
@@ -184,17 +186,24 @@ Refer to rendering backends in the [examples/](https://github.com/ocornut/imgui/
|
||||
|
||||
# Q&A: Usage
|
||||
|
||||
### Q: About the ID Stack system...
|
||||
### Q: Why is my widget not reacting when I click on it?
|
||||
### Q: How can I have widgets with an empty label?
|
||||
### Q: How can I have multiple widgets with the same label?
|
||||
### Q: How can I have multiple windows with the same label?
|
||||
|
||||
A primer on labels and the ID Stack...
|
||||
|
||||
Dear ImGui internally need to uniquely identify UI elements.
|
||||
Dear ImGui internally needs to uniquely identify UI elements.
|
||||
Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
|
||||
Interactive widgets (such as calls to Button buttons) need a unique ID.
|
||||
Unique ID are used internally to track active widgets and occasionally associate state to widgets.
|
||||
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
|
||||
|
||||
**Unique ID are used internally to track active widgets and occasionally associate state to widgets.<BR>
|
||||
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.**
|
||||
|
||||
Since Dear ImGui 1.85 you can use `Demo>Tools>Stack Tool` or call `ImGui::ShowStackToolWindow()`. The tool display intermediate values leading to the creation of a unique ID, making things easier to debug and understand.
|
||||
|
||||

|
||||
|
||||
- Unique ID are often derived from a string label and at minimum scoped within their host window:
|
||||
```cpp
|
||||
@@ -454,7 +463,7 @@ draw_list->AddCircleFilled(ImVec2(p.x + 50, p.y + 50), 30.0f, IM_COL32(255, 0, 0
|
||||
// Draw a 3 pixel thick yellow line
|
||||
draw_list->AddLine(ImVec2(p.x, p.y), ImVec2(p.x + 100.0f, p.y + 100.0f), IM_COL32(255, 255, 0, 255), 3.0f);
|
||||
|
||||
// Advance the ImGui cursor to claim space in the window (otherwise the window will appears small and needs to be resized)
|
||||
// Advance the ImGui cursor to claim space in the window (otherwise the window will appear small and needs to be resized)
|
||||
ImGui::Dummy(ImVec2(200, 200));
|
||||
|
||||
ImGui::End();
|
||||
@@ -466,7 +475,7 @@ ImGui::End();
|
||||
- Math operators: if you have setup `IM_VEC2_CLASS_EXTRA` in `imconfig.h` to bind your own math types, you can use your own math types and their natural operators instead of ImVec2. ImVec2 by default doesn't export any math operators in the public API. You may use `#define IMGUI_DEFINE_MATH_OPERATORS` `#include "imgui_internal.h"` to use the internally defined math operators, but instead prefer using your own math library and set it up in `imconfig.h`.
|
||||
- You can use `ImGui::GetBackgroundDrawList()` or `ImGui::GetForegroundDrawList()` to access draw lists which will be displayed behind and over every other dear imgui windows (one bg/fg drawlist per viewport). This is very convenient if you need to quickly display something on the screen that is not associated to a dear imgui window.
|
||||
- You can also create your own empty window and draw inside it. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags (The `ImGuiWindowFlags_NoDecoration` flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse). Then you can retrieve the ImDrawList* via `GetWindowDrawList()` and draw to it in any way you like.
|
||||
`- You can create your own ImDrawList instance. You'll need to initialize them with `ImGui::GetDrawListSharedData()`, or create your own instancing ImDrawListSharedData`, and then call your renderer function with your own ImDrawList or ImDrawData data.
|
||||
- You can create your own ImDrawList instance. You'll need to initialize them with `ImGui::GetDrawListSharedData()`, or create your own instancing `ImDrawListSharedData`, and then call your renderer function with your own ImDrawList or ImDrawData data.
|
||||
- Looking for fun? The [ImDrawList coding party 2020](https://github.com/ocornut/imgui/issues/3606) thread is full of "don't do this at home" extreme uses of the ImDrawList API.
|
||||
|
||||
##### [Return to Index](#index)
|
||||
@@ -598,8 +607,8 @@ Text input: it is up to your application to pass the right character code by cal
|
||||
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).
|
||||
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 copy the HWND of your window to io.ImeWindowHandle in order for
|
||||
the default implementation of io.ImeSetInputScreenPosFn() to set your Microsoft IME position correctly.
|
||||
Windows: if your language is relying on an Input Method Editor (IME), you can write your HWND to ImGui::GetMainViewport()->PlatformHandleRaw
|
||||
in order for the default the default implementation of io.SetPlatformImeDataFn() to set your Microsoft IME position correctly.
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
||||
@@ -645,7 +654,7 @@ A reasonably skinned application may look like (screenshot from [#2529](https://
|
||||
|
||||
### Q: Why using C++ (as opposed to C)?
|
||||
|
||||
Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost insanity/quagmire. Dear ImGui does NOT require C++11 so it can be used with most old C++ compilers. Dear ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience.
|
||||
Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost insanity/quagmire. Dear ImGui doesn't use any C++ header file. Dear ImGui uses a very small subset of C++11 features. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience.
|
||||
|
||||
There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/cimgui/cimgui) by Sonoro1234 and Stephan Dilly. It is designed for creating bindings to other languages. If possible, I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for various third-party bindings.
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo
|
||||
---------------------------------------
|
||||
## Readme First
|
||||
|
||||
- You can use the `Metrics/Debugger` window (available in `Demo>Tools`) to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`. The same information are also available in the Style Editor under Fonts.
|
||||
|
||||

|
||||
|
||||
- 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.
|
||||
|
||||
- You can use the style editor `ImGui::ShowStyleEditor()` in the "Fonts" section to browse your fonts and understand what's going on if you have an issue. You can also reach it in `Demo->Tools->Style Editor->Fonts`:
|
||||
|
||||

|
||||
|
||||
- Make sure your font ranges data are persistent (available during the calls to `GetTexDataAsAlpha8()`/`GetTexDataAsRGBA32()/`Build()`.
|
||||
|
||||
- Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.:
|
||||
@@ -292,8 +292,8 @@ for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
|
||||
## Using Font Data Embedded In Source Code
|
||||
|
||||
- Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code.
|
||||
- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instruction on how to use the tool.
|
||||
- You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)).
|
||||
- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool.
|
||||
- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)).
|
||||
- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger.
|
||||
|
||||
Then load the font with:
|
||||
@@ -309,7 +309,7 @@ ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_ba
|
||||
|
||||
## About filenames
|
||||
|
||||
**Please note that many new C/C++ users have issues their files _because the filename they provide is wrong_.**
|
||||
**Please note that many new C/C++ users have issues loading their files _because the filename they provide is wrong_.**
|
||||
|
||||
Two things to watch for:
|
||||
- Make sure your IDE/debugger settings starts your executable from the right working directory. In Visual Studio you can change your working directory in project `Properties > General > Debugging > Working Directory`. People assume that their execution will start from the root folder of the project, where by default it oftens start from the folder where object or executable files are stored.
|
||||
|
||||
@@ -116,9 +116,9 @@ On most platforms and when using C++, **you should be able to use a combination
|
||||
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui in your custom engine. **Make sure to spend time reading the [FAQ](https://www.dearimgui.org/faq), comments, and some of the examples/ application!**
|
||||
|
||||
Officially maintained backends/bindings (in repository):
|
||||
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, Vulkan, WebGPU.
|
||||
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU.
|
||||
- Platforms: GLFW, SDL2, Win32, Glut, OSX, Android.
|
||||
- Frameworks: Emscripten, Allegro5, Marmalade.
|
||||
- Frameworks: Allegro5, Emscripten.
|
||||
|
||||
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
|
||||
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
|
||||
@@ -132,7 +132,7 @@ Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
|
||||
|
||||
### Upcoming Changes
|
||||
|
||||
Some of the goals for 2021 are:
|
||||
Some of the goals for 2022 are:
|
||||
- Work on Docking (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch)
|
||||
- Work on Multi-Viewport / Multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
|
||||
- Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
|
||||
@@ -162,7 +162,9 @@ See: [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, a
|
||||
|
||||
See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#about-the-imgui-paradigm) to read/learn about the Immediate Mode GUI paradigm.
|
||||
|
||||
For questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues) or [GitHub Discussions](https://github.com/ocornut/imgui/discussions). Please read and fill the New Issue template carefully.
|
||||
Getting started? For first-time users having issues compiling/linking/running or issues loading fonts, please use [GitHub Discussions](https://github.com/ocornut/imgui/discussions).
|
||||
|
||||
For other questions, bug reports, requests, feedback, you may post on [GitHub Issues](https://github.com/ocornut/imgui/issues). Please read and fill the New Issue template carefully.
|
||||
|
||||
Private support is available for paying business customers (E-mail: _contact @ dearimgui dot com_).
|
||||
|
||||
@@ -199,13 +201,13 @@ Ongoing Dear ImGui development is currently financially supported by users and p
|
||||
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1)
|
||||
|
||||
*Double-chocolate sponsors*
|
||||
- [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui)
|
||||
- [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui), [Supercell](https://supercell.com)
|
||||
|
||||
*Chocolate sponsors*
|
||||
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Adobe](https://www.adobe.com/products/medium.html), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Epic](https://www.unrealengine.com/en-US/megagrants), [RAD Game Tools](http://www.radgametools.com/)
|
||||
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [Adobe](https://www.adobe.com/products/medium.html), [Aras Pranckevičius](https://aras-p.info), [Arkane Studios](https://www.arkane-studios.com), [Epic](https://www.unrealengine.com/en-US/megagrants), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [RAD Game Tools](http://www.radgametools.com/)
|
||||
|
||||
*Salty-caramel sponsors*
|
||||
- [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [O-Net Communications (USA)](http://en.o-netcom.com), [Supercell](https://supercell.com).
|
||||
- [Framefield](http://framefield.com), [Grinding Gear Games](https://www.grindinggear.com), [Kylotonn](https://www.kylotonn.com), [Next Level Games](https://www.nextlevelgames.com), [O-Net Communications (USA)](http://en.o-netcom.com)
|
||||
|
||||
Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors) for past sponsors.
|
||||
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations.
|
||||
|
||||
@@ -113,7 +113,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- input number: optional range min/max for Input*() functions
|
||||
- input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
|
||||
- input number: use mouse wheel to step up/down
|
||||
- input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack.
|
||||
|
||||
- layout: helper or a way to express ImGui::SameLine(ImGui::GetCursorStartPos().x + ImGui::CalcItemWidth() + ImGui::GetStyle().ItemInnerSpacing.x); in a simpler manner.
|
||||
- layout, font: horizontal tab support, A) text mode: forward only tabs (e.g. every 4 characters/N pixels from pos x1), B) manual mode: explicit tab stops acting as mini columns, no clipping (for menu items, many kind of uses, also vaguely relate to #267, #395)
|
||||
@@ -142,7 +141,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- plot: option/feature: draw unit
|
||||
- plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
|
||||
|
||||
- clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.)
|
||||
- clipper: ability to disable the clipping through a simple flag/bool.
|
||||
- clipper: ability to run without knowing full count in advance.
|
||||
- clipper: horizontal clipping support. (#2580)
|
||||
@@ -152,8 +150,36 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- separator: width, thickness, centering (#1643)
|
||||
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
|
||||
|
||||
- dock: merge docking branch (#2109)
|
||||
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
|
||||
- docking: merge docking branch (#2109)
|
||||
- docking: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304)
|
||||
- docking: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8)
|
||||
- docking: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode?
|
||||
- docking: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions.
|
||||
- docking: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished.
|
||||
- docking: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized.
|
||||
- docking: B~ central node resizing behavior incorrect.
|
||||
- docking: B: changing title font/style per-window is not supported as dock nodes are created in NewFrame.
|
||||
- docking: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary)
|
||||
- docking: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level?
|
||||
- docking: B- single visible node part of a hidden split hierarchy (OnlyNodeWithWindows != NULL) should show a normal title bar (not a tab bar)
|
||||
- docking: B~ SetNextWindowDock() calls (with conditional) -> defer everything to DockContextUpdate (repro: Documents->[X]Windows->Dock 1 elsewhere->Click Redock All
|
||||
- docking: B~ tidy up tab list popup buttons features (available with manual tab-bar, see ImGuiTabBarFlags_NoTabListPopupButton code, not used by docking nodes)
|
||||
- docking: B- SetNextWindowDockId(0) with a second Begin() in the frame will asserts
|
||||
- docking: B: resize grip drawn in host window typically appears under scrollbar.
|
||||
- docking: B: resize grip auto-resize on multiple node hierarchy doesn't make much sense or should be improved?
|
||||
- docking: B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4)
|
||||
- docking: B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.)
|
||||
- docking: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff.
|
||||
- docking: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar()
|
||||
- docking: B- tab bar: make selected tab always shows its full title?
|
||||
- docking: B- hide close button on single tab bar?
|
||||
- docking: B- nav: design interactions so nav controls can dock/undock
|
||||
- docking: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?)
|
||||
- docking: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node!
|
||||
- docking: B- allow dragging a non-floating dock node by clicking on the title-bar-looking section (not just the collapse/menu button)
|
||||
- docking: B- option to remember undocked window size? (instead of keeping their docked size) (relate to #2104)
|
||||
- docking: C- nav: CTRL+TAB highlighting tabs shows the mismatch between focus-stack and tab-order (not visible in VS because it doesn't highlight the tabs)
|
||||
- docking: C- after a dock/undock, the Scrollbar Status update in Begin() should use an updated e.g. size_y_for_scrollbars to avoid a 1 frame scrollbar flicker.
|
||||
|
||||
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work
|
||||
- tabs: close button tends to overlap unsaved-document star
|
||||
@@ -326,6 +352,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?)
|
||||
- nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ?
|
||||
! nav: never clear NavId on some setup (e.g. gamepad centric)
|
||||
- nav: scroll up/down if possible when move request fails
|
||||
- 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: code to focus child-window on restoring NavId appears to have issue: e.g. when focus change is implicit because of window closure.
|
||||
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
|
||||
@@ -334,12 +361,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- 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: 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: 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: ESC on a flattened child should select something.
|
||||
- nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child.
|
||||
- nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child
|
||||
- nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..).
|
||||
- nav: simulate right-click or context activation? (SHIFT+F10)
|
||||
- nav/tabbing: refactor old tabbing system and turn into navigation, should pass through all widgets (in submission order?).
|
||||
- nav/popup: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys, default validation button, etc.
|
||||
- nav/treenode: left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?)
|
||||
- nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons.
|
||||
@@ -352,8 +379,20 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- nav/windowing: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
|
||||
- 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: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
|
||||
- focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787, #343)
|
||||
|
||||
- viewport: make it possible to have no main/hosting viewport
|
||||
- viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without
|
||||
on a custom e.g. Win32 bindings. It prevents newly dragged-out viewports from taking the focus, which makes ALT+F4 more ambiguous.
|
||||
- viewport: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front.
|
||||
- viewport: with platform decoration enabled, platform may force constraint (e.g. minimum size)
|
||||
- viewport: use getfocus/setfocus api to synchronize imgui<>platform focus better (e.g imgui-side ctrl-tab can focus os window, OS initial setup and alt-tab can focus imgui window etc.)
|
||||
- viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for.
|
||||
- viewport: implicit/fallback Debug window can hog a zombie viewport (harmless, noisy?) > could at least clear out the reference on a per session basis?
|
||||
- viewport: need to clarify how to use GetMousePos() from a user point of view.
|
||||
- platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport.
|
||||
- platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set
|
||||
- platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it).
|
||||
- platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32).
|
||||
|
||||
- inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors.
|
||||
- inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71)
|
||||
|
||||
@@ -36,6 +36,7 @@ int main(int, char**)
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; };
|
||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
||||
@@ -32,6 +33,7 @@
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||
07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
|
||||
07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
||||
5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = "<group>"; };
|
||||
@@ -76,6 +78,7 @@
|
||||
files = (
|
||||
8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */,
|
||||
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */,
|
||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */,
|
||||
83BBE9ED20EB471700295997 /* Metal.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -133,6 +136,7 @@
|
||||
83BBE9E320EB46B800295997 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05318E0E274C397200A8DE2E /* GameController.framework */,
|
||||
8309BDC5253CCCFE0045E2A1 /* AppKit.framework */,
|
||||
8309BD8E253CCAAA0045E2A1 /* UIKit.framework */,
|
||||
83BBE9EE20EB471C00295997 /* ModelIO.framework */,
|
||||
|
||||
@@ -107,19 +107,7 @@
|
||||
userInfo:nil];
|
||||
[self.view addTrackingArea:trackingArea];
|
||||
|
||||
// If we want to receive key events, we either need to be in the responder chain of the key view,
|
||||
// or else we can install a local monitor. The consequence of this heavy-handed approach is that
|
||||
// we receive events for all controls, not just Dear ImGui widgets. If we had native controls in our
|
||||
// window, we'd want to be much more careful than just ingesting the complete event stream.
|
||||
// To match the behavior of other backends, we pass every event down to the OS.
|
||||
NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
|
||||
{
|
||||
ImGui_ImplOSX_HandleEvent(event, self.view);
|
||||
return event;
|
||||
}];
|
||||
|
||||
ImGui_ImplOSX_Init();
|
||||
ImGui_ImplOSX_Init(self.view);
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -223,8 +211,7 @@
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
|
||||
// Forward Mouse/Keyboard events to Dear ImGui OSX backend.
|
||||
// Other events are registered via addLocalMonitorForEventsMatchingMask()
|
||||
// Forward Mouse events to Dear ImGui OSX backend.
|
||||
-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
||||
-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
||||
-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); }
|
||||
@@ -251,7 +238,7 @@
|
||||
UITouch *anyTouch = event.allTouches.anyObject;
|
||||
CGPoint touchLocation = [anyTouch locationInView:self.view];
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.MousePos = ImVec2(touchLocation.x, touchLocation.y);
|
||||
io.AddMousePosEvent(touchLocation.x, touchLocation.y);
|
||||
|
||||
BOOL hasActiveTouch = NO;
|
||||
for (UITouch *touch in event.allTouches)
|
||||
@@ -262,7 +249,7 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
io.MouseDown[0] = hasActiveTouch;
|
||||
io.AddMouseButtonEvent(0, hasActiveTouch);
|
||||
}
|
||||
|
||||
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self updateIOWithTouchEvent:event]; }
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05E31B57274EF0360083FCB6 /* GameController.framework */; };
|
||||
07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82EDA213941D00078D120 /* imgui_widgets.cpp */; };
|
||||
4080A99820B02D340036BA46 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A98A20B02CD90036BA46 /* main.mm */; };
|
||||
4080A9A220B034280036BA46 /* imgui_impl_opengl2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99E20B034280036BA46 /* imgui_impl_opengl2.cpp */; };
|
||||
@@ -32,6 +33,7 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
05E31B57274EF0360083FCB6 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||
07A82EDA213941D00078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
||||
4080A96B20B029B00036BA46 /* example_osx_opengl2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_osx_opengl2; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4080A98A20B02CD90036BA46 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; };
|
||||
@@ -57,6 +59,7 @@
|
||||
files = (
|
||||
4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */,
|
||||
4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */,
|
||||
05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -95,6 +98,7 @@
|
||||
4080A9B120B034E40036BA46 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
05E31B57274EF0360083FCB6 /* GameController.framework */,
|
||||
4080A9B420B034EA0036BA46 /* OpenGL.framework */,
|
||||
4080A9B220B034E40036BA46 /* Cocoa.framework */,
|
||||
);
|
||||
|
||||
@@ -36,15 +36,6 @@
|
||||
|
||||
-(void)initialize
|
||||
{
|
||||
// Some events do not raise callbacks of AppView in some circumstances (for example when CMD key is held down).
|
||||
// This monitor taps into global event stream and captures these events.
|
||||
NSEventMask eventMask = NSEventMaskKeyDown | NSEventMaskKeyUp | NSEventMaskFlagsChanged;
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:eventMask handler:^NSEvent * _Nullable(NSEvent *event)
|
||||
{
|
||||
ImGui_ImplOSX_HandleEvent(event, self);
|
||||
return event;
|
||||
}];
|
||||
|
||||
// Setup Dear ImGui context
|
||||
// FIXME: This example doesn't have proper cleanup...
|
||||
IMGUI_CHECKVERSION();
|
||||
@@ -52,13 +43,14 @@
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplOSX_Init();
|
||||
ImGui_ImplOSX_Init(self);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
|
||||
// Load Fonts
|
||||
@@ -146,12 +138,9 @@
|
||||
animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES];
|
||||
}
|
||||
|
||||
-(void)reshape { [[self openGLContext] update]; [self updateAndDrawDemoView]; }
|
||||
-(void)reshape { [super reshape]; [[self openGLContext] update]; [self updateAndDrawDemoView]; }
|
||||
-(void)drawRect:(NSRect)bounds { [self updateAndDrawDemoView]; }
|
||||
-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
|
||||
-(BOOL)acceptsFirstResponder { return (YES); }
|
||||
-(BOOL)becomeFirstResponder { return (YES); }
|
||||
-(BOOL)resignFirstResponder { return (YES); }
|
||||
-(void)dealloc { animationTimer = nil; }
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
## How to Build
|
||||
|
||||
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
|
||||
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
|
||||
|
||||
- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools.
|
||||
|
||||
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
|
||||
|
||||
- Then build using `make` while in the `example_emscripten_opengl3/` directory.
|
||||
|
||||
## How to Run
|
||||
@@ -15,6 +18,7 @@ _"Unfortunately several browsers (including Chrome, Safari, and Internet Explore
|
||||
- Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
|
||||
- You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses).
|
||||
- You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`.
|
||||
- If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only).
|
||||
|
||||
## Obsolete features:
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
|
||||
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
|
||||
# How to Build
|
||||
## How to Build
|
||||
|
||||
- You need to install Emscripten from https://emscripten.org/docs/getting_started/downloads.html, and have the environment variables set, as described in https://emscripten.org/docs/getting_started/downloads.html#installation-instructions
|
||||
|
||||
- Depending on your configuration, in Windows you may need to run `emsdk/emsdk_env.bat` in your console to access the Emscripten command-line tools.
|
||||
|
||||
- You may also refer to our [Continuous Integration setup](https://github.com/ocornut/imgui/tree/master/.github/workflows) for Emscripten setup.
|
||||
|
||||
- Then build using `make` while in the `example_emscripten_wgpu/` directory.
|
||||
|
||||
- Requires Emscripten 2.0.10 (December 2020) due to GLFW adaptations
|
||||
- Requires recent Emscripten as WGPU is still a work-in-progress API.
|
||||
|
||||
## How to Run
|
||||
|
||||
To run on a local machine:
|
||||
- Make sure your browse supports WGPU and it is enabled. WGPU is still WIP not enabled by default in most browser.
|
||||
- `make serve` will use Python3 to spawn a local webserver, you can then browse http://localhost:8000 to access your build.
|
||||
- Otherwise, generally you will need a local webserver:
|
||||
- Quoting [https://emscripten.org/docs/getting_started](https://emscripten.org/docs/getting_started/Tutorial.html#generating-html):<br>
|
||||
_"Unfortunately several browsers (including Chrome, Safari, and Internet Explorer) do not support file:// [XHR](https://emscripten.org/docs/site/glossary.html#term-xhr) requests, and can’t load extra files needed by the HTML (like a .wasm file, or packaged file data as mentioned lower down). For these browsers you’ll need to serve the files using a [local webserver](https://emscripten.org/docs/getting_started/FAQ.html#faq-local-webserver) and then open http://localhost:8000/hello.html."_
|
||||
- Emscripten SDK has a handy `emrun` command: `emrun web/example_emscripten_opengl3.html --browser firefox` which will spawn a temporary local webserver (in Firefox). See https://emscripten.org/docs/compiling/Running-html-files-with-emrun.html for details.
|
||||
- You may use Python 3 builtin webserver: `python -m http.server -d web` (this is what `make serve` uses).
|
||||
- You may use Python 2 builtin webserver: `cd web && python -m SimpleHTTPServer`.
|
||||
- If you are accessing the files over a network, certain browsers, such as Firefox, will restrict Gamepad API access to secure contexts only (e.g. https only).
|
||||
|
||||
@@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
|
||||
LIBS += -L/usr/local/lib -L/opt/homebrew/lib
|
||||
LIBS += -lglfw
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
|
||||
CXXFLAGS += -Wall -Wformat
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -44,13 +44,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
@@ -143,7 +155,17 @@ int main(int, char**)
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
//glUseProgram(last_program);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
LINUX_GL_LIBS = -lGL
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -65,13 +65,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
@@ -156,6 +168,17 @@ int main(int, char**)
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
glfwMakeContextCurrent(backup_current_context);
|
||||
}
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
}
|
||||
|
||||
@@ -41,3 +41,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)
|
||||
target_link_libraries(example_glfw_vulkan ${LIBRARIES})
|
||||
target_compile_definitions(example_glfw_vulkan PUBLIC -DImTextureID=ImU64)
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
@set OUT_DIR=Debug
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
|
||||
@set OUT_DIR=Release
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
@set OUT_DIR=Debug
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
|
||||
@set OUT_DIR=Release
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
cl /nologo /Zi /MD /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -105,6 +106,7 @@
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -122,6 +124,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -142,6 +145,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -387,13 +387,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
@@ -404,9 +416,11 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||
|
||||
@@ -528,17 +542,25 @@ int main(int, char**)
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
ImDrawData* main_draw_data = ImGui::GetDrawData();
|
||||
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
if (!main_is_minimized)
|
||||
FrameRender(wd, main_draw_data);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
// Present Main Platform Window
|
||||
if (!main_is_minimized)
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -119,6 +119,7 @@ int main(int argc, char** argv)
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# This file is for configuration settings for your
|
||||
# application.
|
||||
#
|
||||
# The syntax is similar to windows .ini files ie
|
||||
#
|
||||
# [GroupName]
|
||||
# Setting = Value
|
||||
#
|
||||
# Which can be read by your application using
|
||||
# e.g s3eConfigGetString("GroupName", "Setting", string)
|
||||
#
|
||||
# All settings must be documented in .config.txt files.
|
||||
# New settings specific to this application should be
|
||||
# documented in app.config.txt
|
||||
#
|
||||
# Some conditional operations are also permitted, see the
|
||||
# S3E documentation for details.
|
||||
|
||||
[S3E]
|
||||
MemSize=6000000
|
||||
MemSizeDebug=6000000
|
||||
DispFixRot=FixedLandscape
|
||||
|
||||
# emulate iphone 5 resolution, change these settings to emulate other display resolution
|
||||
WinWidth=1136
|
||||
WinHeight=640
|
||||
|
||||
[GX]
|
||||
DataCacheSize=131070
|
||||
|
||||
[Util]
|
||||
#MemoryBreakpoint=1282
|
||||
@@ -1,47 +0,0 @@
|
||||
#!/usr/bin/env mkb
|
||||
|
||||
# ImGui - standalone example application for Marmalade
|
||||
# Copyright (C) 2015 by Giovanni Zito
|
||||
# This file is part of ImGui
|
||||
# https://github.com/ocornut/imgui
|
||||
|
||||
define IMGUI_DISABLE_INCLUDE_IMCONFIG_H
|
||||
define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
|
||||
define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS
|
||||
define _snprintf=snprintf
|
||||
|
||||
options
|
||||
{
|
||||
optimise-speed=1
|
||||
}
|
||||
|
||||
includepaths
|
||||
{
|
||||
../..
|
||||
../../backends
|
||||
}
|
||||
|
||||
subprojects
|
||||
{
|
||||
iwgx
|
||||
}
|
||||
|
||||
files
|
||||
{
|
||||
(.)
|
||||
["imgui"]
|
||||
../../imgui.cpp
|
||||
../../imgui_demo.cpp
|
||||
../../imgui_draw.cpp
|
||||
../../imgui_tables.cpp
|
||||
../../imgui_widgets.cpp
|
||||
../../imconfig.h
|
||||
../../imgui.h
|
||||
../../imgui_internal.h
|
||||
|
||||
["imgui","Marmalade backend"]
|
||||
../../backends/imgui_impl_marmalade.h
|
||||
../../backends/imgui_impl_marmalade.cpp
|
||||
main.cpp
|
||||
|
||||
}
|
||||
@@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS += -I$(IMGUI_DIR)
|
||||
CXXFLAGS += -std=c++11 -I$(IMGUI_DIR)
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
@@ -52,7 +52,7 @@ endif
|
||||
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
ECHO_MESSAGE = "Mac OS X"
|
||||
ifeq ($(WITH_EXTRA_WARNINGS), 1)
|
||||
CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-c++11-long-long -Wno-poison-system-directories
|
||||
CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-poison-system-directories
|
||||
endif
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
@@ -54,13 +54,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForD3D(window);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
@@ -160,6 +172,13 @@ int main(int, char**)
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
|
||||
LIBS += `sdl2-config --libs`
|
||||
LIBS += -L/usr/local/lib
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
|
||||
CXXFLAGS += `sdl2-config --cflags`
|
||||
CXXFLAGS += -Wall -Wformat
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
@@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -42,13 +42,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||
ImGui_ImplOpenGL2_Init();
|
||||
@@ -141,6 +153,19 @@ int main(int, char**)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
|
||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
LINUX_GL_LIBS = -lGL
|
||||
|
||||
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
LIBS =
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#include <SDL_opengles2.h>
|
||||
#else
|
||||
#include <SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
// Main code
|
||||
@@ -63,13 +64,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
@@ -161,6 +174,19 @@ int main(int, char**)
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window, gl_context) directly)
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
SDL_Window* backup_current_window = SDL_GL_GetCurrentWindow();
|
||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
SDL_GL_SwapWindow(window);
|
||||
}
|
||||
|
||||
|
||||
79
examples/example_sdl_sdlrenderer/Makefile
Normal file
79
examples/example_sdl_sdlrenderer/Makefile
Normal file
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# 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_sdl_sdlrenderer
|
||||
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_sdl.cpp $(IMGUI_DIR)/backends/imgui_impl_sdlrenderer.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 `sdl2-config --libs`
|
||||
|
||||
CXXFLAGS += `sdl2-config --cflags`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
ECHO_MESSAGE = "Mac OS X"
|
||||
LIBS += -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
|
||||
CXXFLAGS += `sdl2-config --cflags`
|
||||
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`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags sdl2`
|
||||
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)
|
||||
25
examples/example_sdl_sdlrenderer/README.md
Normal file
25
examples/example_sdl_sdlrenderer/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
# How to Build
|
||||
|
||||
- On Windows with Visual Studio's CLI
|
||||
|
||||
```
|
||||
set SDL2_DIR=path_to_your_sdl2_folder
|
||||
cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_sdlrenderer.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib /subsystem:console
|
||||
# ^^ include paths ^^ source files ^^ output exe ^^ output dir ^^ libraries
|
||||
# or for 64-bit:
|
||||
cl /Zi /MD /I.. /I..\.. /I%SDL2_DIR%\include main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp /FeDebug/example_sdl_sdlrenderer.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x64 SDL2.lib SDL2main.lib /subsystem:console
|
||||
```
|
||||
|
||||
- On Linux and similar Unixes
|
||||
|
||||
```
|
||||
c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_sdlrenderer.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL
|
||||
```
|
||||
|
||||
- On Mac OS X
|
||||
|
||||
```
|
||||
brew install sdl2
|
||||
c++ `sdl2-config --cflags` -I .. -I ../.. main.cpp ../../backends/imgui_impl_sdl.cpp ../../backends/imgui_impl_sdlrenderer.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl
|
||||
```
|
||||
8
examples/example_sdl_sdlrenderer/build_win32.bat
Normal file
8
examples/example_sdl_sdlrenderer/build_win32.bat
Normal file
@@ -0,0 +1,8 @@
|
||||
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
|
||||
@set OUT_DIR=Debug
|
||||
@set OUT_EXE=example_sdl_sdlrenderer_
|
||||
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL2_DIR%\include
|
||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl.cpp ..\..\backends\imgui_impl_sdlrenderer.cpp ..\..\imgui*.cpp
|
||||
@set LIBS=/LIBPATH:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
181
examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj
Normal file
181
examples/example_sdl_sdlrenderer/example_sdl_sdlrenderer.vcxproj
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}</ProjectGuid>
|
||||
<RootNamespace>example_sdl_sdlrenderer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL2.lib;SDL2main.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp" />
|
||||
<ClCompile Include="..\..\imgui_demo.cpp" />
|
||||
<ClCompile Include="..\..\imgui_draw.cpp" />
|
||||
<ClCompile Include="..\..\imgui_tables.cpp" />
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdlrenderer.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h" />
|
||||
<ClInclude Include="..\..\imgui.h" />
|
||||
<ClInclude Include="..\..\imgui_internal.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdlrenderer.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis" />
|
||||
<None Include="..\README.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="imgui">
|
||||
<UniqueIdentifier>{20b90ce4-7fcb-4731-b9a0-075f875de82d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sources">
|
||||
<UniqueIdentifier>{f18ab499-84e1-499f-8eff-9754361e0e52}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_demo.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_draw.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_tables.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdlrenderer.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui_internal.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdlrenderer.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.txt" />
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis">
|
||||
<Filter>sources</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,34 +1,63 @@
|
||||
// Dear ImGui: standalone example application for Marmalade
|
||||
// Dear ImGui: standalone example application for SDL2 + SDL_Renderer
|
||||
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// Copyright (C) 2015 by Giovanni Zito
|
||||
// This file is part of Dear ImGui
|
||||
// Important to understand: SDL_Renderer is an _optional_ component of SDL. We do not recommend you use SDL_Renderer
|
||||
// because it provide a rather limited API to the end-user. We provide this backend for the sake of completeness.
|
||||
// For a multi-platform app consider using e.g. SDL+DirectX on Windows and SDL+OpenGL on Linux/OSX.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_marmalade.h"
|
||||
#include "imgui_impl_sdl.h"
|
||||
#include "imgui_impl_sdlrenderer.h"
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <s3eKeyboard.h>
|
||||
#include <s3ePointer.h>
|
||||
#include <IwGx.h>
|
||||
#if !SDL_VERSION_ATLEAST(2,0,17)
|
||||
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
||||
#endif
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
IwGxInit();
|
||||
// Setup SDL
|
||||
// (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 latest version of SDL is recommended!)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Setup window
|
||||
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);
|
||||
|
||||
// Setup SDL_Renderer instance
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == NULL)
|
||||
{
|
||||
SDL_Log("Error creating SDL_Renderer!");
|
||||
return false;
|
||||
}
|
||||
//SDL_RendererInfo info;
|
||||
//SDL_GetRendererInfo(renderer, &info);
|
||||
//SDL_Log("Current SDL_Renderer: %s", info.name);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_Marmalade_Init(true);
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer_Init(renderer);
|
||||
|
||||
// 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.
|
||||
@@ -51,21 +80,27 @@ int main(int, char**)
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
while (true)
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
if (s3eDeviceCheckQuitRequest())
|
||||
break;
|
||||
|
||||
// Poll and handle inputs
|
||||
// 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.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
s3eKeyboardUpdate();
|
||||
s3ePointerUpdate();
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
if (event.type == SDL_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_Marmalade_NewFrame();
|
||||
ImGui_ImplSDLRenderer_NewFrame();
|
||||
ImGui_ImplSDL2_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!).
|
||||
@@ -107,18 +142,20 @@ int main(int, char**)
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
IwGxSetColClear(clear_color.x * 255, clear_color.y * 255, clear_color.z * 255, clear_color.w * 255);
|
||||
IwGxClear();
|
||||
ImGui_Marmalade_RenderDrawData(ImGui::GetDrawData());
|
||||
IwGxSwapBuffers();
|
||||
|
||||
s3eDeviceYield(0);
|
||||
SDL_SetRenderDrawColor(renderer, (Uint8)(clear_color.x * 255), (Uint8)(clear_color.y * 255), (Uint8)(clear_color.z * 255), (Uint8)(clear_color.w * 255));
|
||||
SDL_RenderClear(renderer);
|
||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
ImGui_Marmalade_Shutdown();
|
||||
ImGui_ImplSDLRenderer_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
IwGxTerminate();
|
||||
|
||||
SDL_DestroyRenderer(renderer);
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -7,4 +7,4 @@
|
||||
|
||||
@set OUT_DIR=Debug
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
cl /nologo /Zi /MD %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -105,6 +106,7 @@
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -122,6 +124,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@@ -142,6 +145,7 @@
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<PreprocessorDefinitions>ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@@ -379,13 +379,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL2_InitForVulkan(window);
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
@@ -396,9 +408,11 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info, wd->RenderPass);
|
||||
|
||||
@@ -529,17 +543,25 @@ int main(int, char**)
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||
if (!is_minimized)
|
||||
ImDrawData* main_draw_data = ImGui::GetDrawData();
|
||||
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
if (!main_is_minimized)
|
||||
FrameRender(wd, main_draw_data);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||
FrameRender(wd, draw_data);
|
||||
FramePresent(wd);
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
// Present Main Platform Window
|
||||
if (!main_is_minimized)
|
||||
FramePresent(wd);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
|
||||
@@ -46,13 +46,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX10_Init(g_pd3dDevice);
|
||||
@@ -146,6 +158,13 @@ int main(int, char**)
|
||||
g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
@@ -46,13 +46,30 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
//io.ConfigViewportsNoDefaultParent = true;
|
||||
//io.ConfigDockingAlwaysTabBar = true;
|
||||
//io.ConfigDockingTransparentPayload = true;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: Experimental. THIS CURRENTLY DOESN'T WORK AS EXPECTED. DON'T USE IN USER APP!
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI: Experimental.
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
@@ -146,6 +163,13 @@ int main(int, char**)
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
@@ -215,6 +239,10 @@ void CleanupRenderTarget()
|
||||
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
|
||||
}
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers
|
||||
#endif
|
||||
|
||||
// Forward declare message handler from imgui_impl_win32.cpp
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
@@ -241,6 +269,15 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DPICHANGED:
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports)
|
||||
{
|
||||
//const int dpi = HIWORD(wParam);
|
||||
//printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f);
|
||||
const RECT* suggested_rect = (RECT*)lParam;
|
||||
::SetWindowPos(hWnd, NULL, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ::DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -81,13 +81,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX12_Init(g_pd3dDevice, NUM_FRAMES_IN_FLIGHT,
|
||||
@@ -207,6 +219,13 @@ int main(int, char**)
|
||||
|
||||
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault(NULL, (void*)g_pd3dCommandList);
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
|
||||
|
||||
@@ -44,13 +44,25 @@ int main(int, char**)
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplWin32_Init(hwnd);
|
||||
ImGui_ImplDX9_Init(g_pd3dDevice);
|
||||
@@ -150,6 +162,14 @@ int main(int, char**)
|
||||
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
|
||||
g_pd3dDevice->EndScene();
|
||||
}
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
|
||||
|
||||
// Handle loss of D3D9 device
|
||||
@@ -205,6 +225,10 @@ void ResetDevice()
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers
|
||||
#endif
|
||||
|
||||
// Forward declare message handler from imgui_impl_win32.cpp
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
@@ -231,6 +255,15 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_DESTROY:
|
||||
::PostQuitMessage(0);
|
||||
return 0;
|
||||
case WM_DPICHANGED:
|
||||
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_DpiEnableScaleViewports)
|
||||
{
|
||||
//const int dpi = HIWORD(wParam);
|
||||
//printf("WM_DPICHANGED to %d (%.0f%%)\n", dpi, (float)dpi / 96.0f * 100.0f);
|
||||
const RECT* suggested_rect = (RECT*)lParam;
|
||||
::SetWindowPos(hWnd, NULL, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ::DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
@@ -9,11 +9,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl3", "example_glfw_opengl3\example_glfw_opengl3.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_vulkan", "example_glfw_vulkan\example_glfw_vulkan.vcxproj", "{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_opengl2", "example_sdl_opengl2\example_sdl_opengl2.vcxproj", "{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_opengl3", "example_sdl_opengl3\example_sdl_opengl3.vcxproj", "{BBAEB705-1669-40F3-8567-04CF6A991F4C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_vulkan", "example_sdl_vulkan\example_sdl_vulkan.vcxproj", "{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl_directx11", "example_sdl_directx11\example_sdl_directx11.vcxproj", "{9E1987E3-1F19-45CA-B9C9-D31E791836D8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -47,6 +57,14 @@ Global
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.ActiveCfg = Release|x64
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.Build.0 = Release|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.Build.0 = Debug|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.Build.0 = Release|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.ActiveCfg = Release|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.Build.0 = Release|x64
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|x64.ActiveCfg = Debug|x64
|
||||
@@ -63,14 +81,46 @@ Global
|
||||
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|Win32.Build.0 = Release|Win32
|
||||
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|x64.ActiveCfg = Release|x64
|
||||
{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Release|x64.Build.0 = Release|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.Build.0 = Debug|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.Build.0 = Release|Win32
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.ActiveCfg = Release|x64
|
||||
{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.Build.0 = Release|x64
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Debug|x64.Build.0 = Debug|x64
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|Win32.Build.0 = Release|Win32
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|x64.ActiveCfg = Release|x64
|
||||
{57E2DF5A-6FC8-45BB-99DD-91A18C646E80}.Release|x64.Build.0 = Release|x64
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Debug|x64.Build.0 = Debug|x64
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|Win32.Build.0 = Release|Win32
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|x64.ActiveCfg = Release|x64
|
||||
{2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741}.Release|x64.Build.0 = Release|x64
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Debug|x64.Build.0 = Debug|x64
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|Win32.Build.0 = Release|Win32
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|x64.ActiveCfg = Release|x64
|
||||
{BBAEB705-1669-40F3-8567-04CF6A991F4C}.Release|x64.Build.0 = Release|x64
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Debug|x64.Build.0 = Debug|x64
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|Win32.Build.0 = Release|Win32
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.ActiveCfg = Release|x64
|
||||
{BAE3D0B5-9695-4EB1-AD0F-75890EB4A3B3}.Release|x64.Build.0 = Release|x64
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Debug|x64.Build.0 = Debug|x64
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|Win32.Build.0 = Release|Win32
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|x64.ActiveCfg = Release|x64
|
||||
{9E1987E3-1F19-45CA-B9C9-D31E791836D8}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
11
imconfig.h
11
imconfig.h
@@ -28,12 +28,13 @@
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger window: ShowMetricsWindow() will be empty.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
@@ -80,12 +81,12 @@
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
|
||||
701
imgui_demo.cpp
701
imgui_demo.cpp
File diff suppressed because it is too large
Load Diff
159
imgui_draw.cpp
159
imgui_draw.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.84
|
||||
// dear imgui, v1.88 WIP
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -230,6 +230,8 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -290,6 +292,8 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -351,6 +355,8 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabActive] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f);
|
||||
colors[ImGuiCol_TabUnfocused] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f);
|
||||
colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@@ -402,10 +408,11 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||
void ImDrawList::_ResetForNewFrame()
|
||||
{
|
||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
||||
// (those should be IM_STATIC_ASSERT() in theory but with our pre C++11 setup the whole check doesn't compile with GCC)
|
||||
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
|
||||
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
|
||||
IM_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
|
||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
|
||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
|
||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
|
||||
if (_Splitter._Count > 1)
|
||||
_Splitter.Merge(this);
|
||||
|
||||
CmdBuffer.resize(0);
|
||||
IdxBuffer.resize(0);
|
||||
@@ -473,6 +480,7 @@ void ImDrawList::_PopUnusedDrawCmd()
|
||||
|
||||
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||
{
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||
if (curr_cmd->ElemCount != 0)
|
||||
@@ -487,16 +495,18 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||
}
|
||||
|
||||
// Compare ClipRect, TextureId and VtxOffset with a single memcmp()
|
||||
#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
|
||||
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
|
||||
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
|
||||
#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
|
||||
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
|
||||
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
|
||||
#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset)
|
||||
|
||||
// Try to merge two last draw commands
|
||||
void ImDrawList::_TryMergeDrawCmds()
|
||||
{
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
ImDrawCmd* prev_cmd = curr_cmd - 1;
|
||||
if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL)
|
||||
if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL)
|
||||
{
|
||||
prev_cmd->ElemCount += curr_cmd->ElemCount;
|
||||
CmdBuffer.pop_back();
|
||||
@@ -508,6 +518,7 @@ void ImDrawList::_TryMergeDrawCmds()
|
||||
void ImDrawList::_OnChangedClipRect()
|
||||
{
|
||||
// If current command is used with different settings we need to add a new command
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
if (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &_CmdHeader.ClipRect, sizeof(ImVec4)) != 0)
|
||||
{
|
||||
@@ -518,7 +529,7 @@ void ImDrawList::_OnChangedClipRect()
|
||||
|
||||
// Try to merge with previous command if it matches, else use current command
|
||||
ImDrawCmd* prev_cmd = curr_cmd - 1;
|
||||
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL)
|
||||
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL)
|
||||
{
|
||||
CmdBuffer.pop_back();
|
||||
return;
|
||||
@@ -530,6 +541,7 @@ void ImDrawList::_OnChangedClipRect()
|
||||
void ImDrawList::_OnChangedTextureID()
|
||||
{
|
||||
// If current command is used with different settings we need to add a new command
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
if (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != _CmdHeader.TextureId)
|
||||
{
|
||||
@@ -540,7 +552,7 @@ void ImDrawList::_OnChangedTextureID()
|
||||
|
||||
// Try to merge with previous command if it matches, else use current command
|
||||
ImDrawCmd* prev_cmd = curr_cmd - 1;
|
||||
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL)
|
||||
if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL)
|
||||
{
|
||||
CmdBuffer.pop_back();
|
||||
return;
|
||||
@@ -553,6 +565,7 @@ void ImDrawList::_OnChangedVtxOffset()
|
||||
{
|
||||
// We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this.
|
||||
_VtxCurrentIdx = 0;
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
//IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349
|
||||
if (curr_cmd->ElemCount != 0)
|
||||
@@ -1201,8 +1214,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
|
||||
|
||||
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
|
||||
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
|
||||
const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f;
|
||||
const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f;
|
||||
const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f;
|
||||
const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f;
|
||||
|
||||
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
|
||||
if (a_emit_start)
|
||||
@@ -1728,13 +1741,13 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
|
||||
for (int i = 1; i < _Count; i++)
|
||||
{
|
||||
ImDrawChannel& ch = _Channels[i];
|
||||
|
||||
// Equivalent of PopUnusedDrawCmd() for this channel's cmdbuffer and except we don't need to test for UserCallback.
|
||||
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0)
|
||||
if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0 && ch._CmdBuffer.back().UserCallback == NULL) // Equivalent of PopUnusedDrawCmd()
|
||||
ch._CmdBuffer.pop_back();
|
||||
|
||||
if (ch._CmdBuffer.Size > 0 && last_cmd != NULL)
|
||||
{
|
||||
// Do not include ImDrawCmd_AreSequentialIdxOffset() in the compare as we rebuild IdxOffset values ourselves.
|
||||
// Manipulating IdxOffset (e.g. by reordering draw commands like done by RenderDimmedBackgroundBehindWindow()) is not supported within a splitter.
|
||||
ImDrawCmd* next_cmd = &ch._CmdBuffer[0];
|
||||
if (ImDrawCmd_HeaderCompare(last_cmd, next_cmd) == 0 && last_cmd->UserCallback == NULL && next_cmd->UserCallback == NULL)
|
||||
{
|
||||
@@ -1919,37 +1932,38 @@ ImFontConfig::ImFontConfig()
|
||||
|
||||
// A work of art lies ahead! (. = white layer, X = black layer, others are blank)
|
||||
// The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 108; // Actual texture will be 2 times that + 1 spacing.
|
||||
// (This is used when io.MouseDrawCursor = true)
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 122; // Actual texture will be 2 times that + 1 spacing.
|
||||
const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27;
|
||||
static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
|
||||
{
|
||||
"..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX "
|
||||
"..- -X.....X- X.X - X.X -X.....X - X.....X- X..X "
|
||||
"--- -XXX.XXX- X...X - X...X -X....X - X....X- X..X "
|
||||
"X - X.X - X.....X - X.....X -X...X - X...X- X..X "
|
||||
"XX - X.X -X.......X- X.......X -X..X.X - X.X..X- X..X "
|
||||
"X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X- X..XXX "
|
||||
"X..X - X.X - X.X - X.X -XX X.X - X.X XX- X..X..XXX "
|
||||
"X...X - X.X - X.X - XX X.X XX - X.X - X.X - X..X..X..XX "
|
||||
"X....X - X.X - X.X - X.X X.X X.X - X.X - X.X - X..X..X..X.X "
|
||||
"X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X -XXX X..X..X..X..X"
|
||||
"X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X -X..XX........X..X"
|
||||
"X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X -X...X...........X"
|
||||
"X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X - X..............X"
|
||||
"X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X - X.............X"
|
||||
"X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X - X.............X"
|
||||
"X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X - X............X"
|
||||
"X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX - X...........X "
|
||||
"X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------- X..........X "
|
||||
"X.X X..X - -X.......X- X.......X - XX XX - - X..........X "
|
||||
"XX X..X - - X.....X - X.....X - X.X X.X - - X........X "
|
||||
" X..X - X...X - X...X - X..X X..X - - X........X "
|
||||
" XX - X.X - X.X - X...XXXXXXXXXXXXX...X - - XXXXXXXXXX "
|
||||
"------------ - X - X -X.....................X- ------------------"
|
||||
" ----------------------------------- X...XXXXXXXXXXXXX...X - "
|
||||
" - X..X X..X - "
|
||||
" - X.X X.X - "
|
||||
" - XX XX - "
|
||||
"..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX - XX XX "
|
||||
"..- -X.....X- X.X - X.X -X.....X - X.....X- X..X -X..X X..X"
|
||||
"--- -XXX.XXX- X...X - X...X -X....X - X....X- X..X -X...X X...X"
|
||||
"X - X.X - X.....X - X.....X -X...X - X...X- X..X - X...X X...X "
|
||||
"XX - X.X -X.......X- X.......X -X..X.X - X.X..X- X..X - X...X...X "
|
||||
"X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X- X..XXX - X.....X "
|
||||
"X..X - X.X - X.X - X.X -XX X.X - X.X XX- X..X..XXX - X...X "
|
||||
"X...X - X.X - X.X - XX X.X XX - X.X - X.X - X..X..X..XX - X.X "
|
||||
"X....X - X.X - X.X - X.X X.X X.X - X.X - X.X - X..X..X..X.X - X...X "
|
||||
"X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X -XXX X..X..X..X..X- X.....X "
|
||||
"X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X -X..XX........X..X- X...X...X "
|
||||
"X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X -X...X...........X- X...X X...X "
|
||||
"X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X - X..............X-X...X X...X"
|
||||
"X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X - X.............X-X..X X..X"
|
||||
"X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X - X.............X- XX XX "
|
||||
"X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X - X............X--------------"
|
||||
"X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX - X...........X - "
|
||||
"X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------- X..........X - "
|
||||
"X.X X..X - -X.......X- X.......X - XX XX - - X..........X - "
|
||||
"XX X..X - - X.....X - X.....X - X.X X.X - - X........X - "
|
||||
" X..X - - X...X - X...X - X..X X..X - - X........X - "
|
||||
" XX - - X.X - X.X - X...XXXXXXXXXXXXX...X - - XXXXXXXXXX - "
|
||||
"------------- - X - X -X.....................X- ------------------- "
|
||||
" ----------------------------------- X...XXXXXXXXXXXXX...X - "
|
||||
" - X..X X..X - "
|
||||
" - X.X X.X - "
|
||||
" - XX XX - "
|
||||
};
|
||||
|
||||
static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3] =
|
||||
@@ -1963,6 +1977,7 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3
|
||||
{ ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW
|
||||
{ ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE
|
||||
{ ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand
|
||||
{ ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed
|
||||
};
|
||||
|
||||
ImFontAtlas::ImFontAtlas()
|
||||
@@ -1998,7 +2013,7 @@ void ImFontAtlas::ClearInputData()
|
||||
ConfigData.clear();
|
||||
CustomRects.clear();
|
||||
PackIdMouseCursors = PackIdLines = -1;
|
||||
TexReady = false;
|
||||
// Important: we leave TexReady untouched
|
||||
}
|
||||
|
||||
void ImFontAtlas::ClearTexData()
|
||||
@@ -3073,8 +3088,8 @@ void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end)
|
||||
void ImFontGlyphRangesBuilder::AddRanges(const ImWchar* ranges)
|
||||
{
|
||||
for (; ranges[0]; ranges += 2)
|
||||
for (ImWchar c = ranges[0]; c <= ranges[1]; c++)
|
||||
AddChar(c);
|
||||
for (unsigned int c = ranges[0]; c <= ranges[1] && c <= IM_UNICODE_CODEPOINT_MAX; c++) //-V560
|
||||
AddChar((ImWchar)c);
|
||||
}
|
||||
|
||||
void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
|
||||
@@ -3729,7 +3744,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col
|
||||
// - RenderArrow()
|
||||
// - RenderBullet()
|
||||
// - RenderCheckMark()
|
||||
// - RenderMouseCursor()
|
||||
// - RenderArrowDockMenu()
|
||||
// - RenderArrowPointingAt()
|
||||
// - RenderRectFilledRangeH()
|
||||
// - RenderRectFilledWithHole()
|
||||
@@ -3790,27 +3805,6 @@ void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float
|
||||
draw_list->PathStroke(col, 0, thickness);
|
||||
}
|
||||
|
||||
void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow)
|
||||
{
|
||||
if (mouse_cursor == ImGuiMouseCursor_None)
|
||||
return;
|
||||
IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT);
|
||||
|
||||
ImFontAtlas* font_atlas = draw_list->_Data->Font->ContainerAtlas;
|
||||
ImVec2 offset, size, uv[4];
|
||||
if (font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2]))
|
||||
{
|
||||
pos -= offset;
|
||||
ImTextureID tex_id = font_atlas->TexID;
|
||||
draw_list->PushTextureID(tex_id);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow);
|
||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border);
|
||||
draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill);
|
||||
draw_list->PopTextureID();
|
||||
}
|
||||
}
|
||||
|
||||
// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
|
||||
void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col)
|
||||
{
|
||||
@@ -3824,6 +3818,14 @@ void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half
|
||||
}
|
||||
}
|
||||
|
||||
// This is less wide than RenderArrow() and we use in dock nodes instead of the regular RenderArrow() to denote a change of functionality,
|
||||
// and because the saved space means that the left-most tab label can stay at exactly the same position as the label of a loose window.
|
||||
void ImGui::RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col)
|
||||
{
|
||||
draw_list->AddRectFilled(p_min + ImVec2(sz * 0.20f, sz * 0.15f), p_min + ImVec2(sz * 0.80f, sz * 0.30f), col);
|
||||
RenderArrowPointingAt(draw_list, p_min + ImVec2(sz * 0.50f, sz * 0.85f), ImVec2(sz * 0.30f, sz * 0.40f), ImGuiDir_Down, col);
|
||||
}
|
||||
|
||||
static inline float ImAcos01(float x)
|
||||
{
|
||||
if (x <= 0.0f) return IM_PI * 0.5f;
|
||||
@@ -3899,16 +3901,27 @@ void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect
|
||||
const bool fill_R = (inner.Max.x < outer.Max.x);
|
||||
const bool fill_U = (inner.Min.y > outer.Min.y);
|
||||
const bool fill_D = (inner.Max.y < outer.Max.y);
|
||||
if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft));
|
||||
if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight));
|
||||
if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight));
|
||||
if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight));
|
||||
if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft));
|
||||
if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight));
|
||||
if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight));
|
||||
if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight));
|
||||
if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopLeft);
|
||||
if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopRight);
|
||||
if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomLeft);
|
||||
if (fill_R && fill_D) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Max.y), ImVec2(outer.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomRight);
|
||||
}
|
||||
|
||||
ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold)
|
||||
{
|
||||
bool round_l = r_in.Min.x <= r_outer.Min.x + threshold;
|
||||
bool round_r = r_in.Max.x >= r_outer.Max.x - threshold;
|
||||
bool round_t = r_in.Min.y <= r_outer.Min.y + threshold;
|
||||
bool round_b = r_in.Max.y >= r_outer.Max.y - threshold;
|
||||
return ImDrawFlags_RoundCornersNone
|
||||
| ((round_t && round_l) ? ImDrawFlags_RoundCornersTopLeft : 0) | ((round_t && round_r) ? ImDrawFlags_RoundCornersTopRight : 0)
|
||||
| ((round_b && round_l) ? ImDrawFlags_RoundCornersBottomLeft : 0) | ((round_b && round_r) ? ImDrawFlags_RoundCornersBottomRight : 0);
|
||||
}
|
||||
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
|
||||
1000
imgui_internal.h
1000
imgui_internal.h
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.84
|
||||
// dear imgui, v1.88 WIP
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -324,7 +324,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
const ImVec2 avail_size = GetContentRegionAvail();
|
||||
ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
|
||||
ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
|
||||
if (use_child_window && IsClippedEx(outer_rect, 0, false))
|
||||
if (use_child_window && IsClippedEx(outer_rect, 0))
|
||||
{
|
||||
ItemSize(outer_rect);
|
||||
return false;
|
||||
@@ -340,10 +340,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
|
||||
// Acquire temporary buffers
|
||||
const int table_idx = g.Tables.GetIndex(table);
|
||||
g.CurrentTableStackIdx++;
|
||||
if (g.CurrentTableStackIdx + 1 > g.TablesTempDataStack.Size)
|
||||
g.TablesTempDataStack.resize(g.CurrentTableStackIdx + 1, ImGuiTableTempData());
|
||||
ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempDataStack[g.CurrentTableStackIdx];
|
||||
if (++g.TablesTempDataStacked > g.TablesTempData.Size)
|
||||
g.TablesTempData.resize(g.TablesTempDataStacked, ImGuiTableTempData());
|
||||
ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempData[g.TablesTempDataStacked - 1];
|
||||
temp_data->TableIndex = table_idx;
|
||||
table->DrawSplitter = &table->TempData->DrawSplitter;
|
||||
table->DrawSplitter->Clear();
|
||||
@@ -564,6 +563,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables)
|
||||
// + 1 (for table->RawData allocated below)
|
||||
// + 1 (for table->ColumnsNames, if names are used)
|
||||
// Shared allocations per number of nested tables
|
||||
// + 1 (for table->Splitter._Channels)
|
||||
// + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels)
|
||||
// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableSetupDrawChannels() for details.
|
||||
@@ -1170,7 +1170,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
|
||||
KeepAliveID(column_id);
|
||||
|
||||
bool hovered = false, held = false;
|
||||
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
|
||||
bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
|
||||
if (pressed && IsMouseDoubleClicked(0))
|
||||
{
|
||||
TableSetColumnWidthAutoSingle(table, column_n);
|
||||
@@ -1381,9 +1381,8 @@ void ImGui::EndTable()
|
||||
|
||||
// Clear or restore current table, if any
|
||||
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
|
||||
IM_ASSERT(g.CurrentTableStackIdx >= 0);
|
||||
g.CurrentTableStackIdx--;
|
||||
temp_data = g.CurrentTableStackIdx >= 0 ? &g.TablesTempDataStack[g.CurrentTableStackIdx] : NULL;
|
||||
IM_ASSERT(g.TablesTempDataStacked > 0);
|
||||
temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL;
|
||||
g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL;
|
||||
if (g.CurrentTable)
|
||||
{
|
||||
@@ -1479,6 +1478,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
|
||||
|
||||
// Ensure frozen columns are ordered in their section. We still allow multiple frozen columns to be reordered.
|
||||
// FIXME-TABLE: This work for preserving 2143 into 21|43. How about 4321 turning into 21|43? (preserve relative order in each section)
|
||||
for (int column_n = 0; column_n < table->FreezeColumnsRequest; column_n++)
|
||||
{
|
||||
int order_n = table->DisplayOrderToIndex[column_n];
|
||||
@@ -1569,18 +1569,21 @@ ImGuiTableColumnFlags ImGui::TableGetColumnFlags(int column_n)
|
||||
|
||||
// Return the cell rectangle based on currently known height.
|
||||
// - Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations.
|
||||
// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it.
|
||||
// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it, or in TableEndRow() when we locked that height.
|
||||
// - Important: if ImGuiTableFlags_PadOuterX is set but ImGuiTableFlags_PadInnerX is not set, the outer-most left and right
|
||||
// columns report a small offset so their CellBgRect can extend up to the outer border.
|
||||
// FIXME: But the rendering code in TableEndRow() nullifies that with clamping required for scrolling.
|
||||
ImRect ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n)
|
||||
{
|
||||
const ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
float x1 = column->MinX;
|
||||
float x2 = column->MaxX;
|
||||
if (column->PrevEnabledColumn == -1)
|
||||
x1 -= table->CellSpacingX1;
|
||||
if (column->NextEnabledColumn == -1)
|
||||
x2 += table->CellSpacingX2;
|
||||
//if (column->PrevEnabledColumn == -1)
|
||||
// x1 -= table->OuterPaddingX;
|
||||
//if (column->NextEnabledColumn == -1)
|
||||
// x2 += table->OuterPaddingX;
|
||||
x1 = ImMax(x1, table->WorkRect.Min.x);
|
||||
x2 = ImMin(x2, table->WorkRect.Max.x);
|
||||
return ImRect(x1, table->RowPosY1, x2, table->RowPosY2);
|
||||
}
|
||||
|
||||
@@ -1797,10 +1800,12 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCurrent];
|
||||
for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++)
|
||||
{
|
||||
// As we render the BG here we need to clip things (for layout we would not)
|
||||
// FIXME: This cancels the OuterPadding addition done by TableGetCellBgRect(), need to keep it while rendering correctly while scrolling.
|
||||
const ImGuiTableColumn* column = &table->Columns[cell_data->Column];
|
||||
ImRect cell_bg_rect = TableGetCellBgRect(table, cell_data->Column);
|
||||
cell_bg_rect.ClipWith(table->BgClipRect);
|
||||
cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped
|
||||
cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling
|
||||
cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX);
|
||||
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
|
||||
}
|
||||
@@ -2353,7 +2358,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
||||
|
||||
// Don't attempt to merge if there are multiple draw calls within the column
|
||||
ImDrawChannel* src_channel = &splitter->_Channels[channel_no];
|
||||
if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0)
|
||||
if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0 && src_channel->_CmdBuffer.back().UserCallback != NULL) // Equivalent of PopUnusedDrawCmd()
|
||||
src_channel->_CmdBuffer.pop_back();
|
||||
if (src_channel->_CmdBuffer.Size != 1)
|
||||
continue;
|
||||
@@ -3987,7 +3992,7 @@ void ImGui::EndColumns()
|
||||
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
|
||||
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
|
||||
KeepAliveID(column_id);
|
||||
if (IsClippedEx(column_hit_rect, column_id, false))
|
||||
if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test
|
||||
continue;
|
||||
|
||||
bool hovered = false, held = false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,6 @@
|
||||
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
|
||||
// This is also an example of how you may wrap your own similar types.
|
||||
|
||||
// Compatibility:
|
||||
// - std::string support is only guaranteed to work from C++11.
|
||||
// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture)
|
||||
|
||||
// Changelog:
|
||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
|
||||
// This is also an example of how you may wrap your own similar types.
|
||||
|
||||
// Compatibility:
|
||||
// - std::string support is only guaranteed to work from C++11.
|
||||
// If you try to use it pre-C++11, please share your findings (w/ info about compiler/architecture)
|
||||
|
||||
// Changelog:
|
||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user