Compare commits
773 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07d6aebafc | ||
|
|
32604e2c57 | ||
|
|
adb107afc2 | ||
|
|
8d9bd5f4fa | ||
|
|
c88bbc21d0 | ||
|
|
917edec0a7 | ||
|
|
34959dd5e8 | ||
|
|
82ab74efb0 | ||
|
|
968dbdb847 | ||
|
|
e43466d2bc | ||
|
|
cdf03f91c9 | ||
|
|
abe70caeae | ||
|
|
4891bb6157 | ||
|
|
f5e6ec42b3 | ||
|
|
92b2dd835d | ||
|
|
76f0309b58 | ||
|
|
d9e9fabec5 | ||
|
|
a922e914b4 | ||
|
|
4b7677fd13 | ||
|
|
0474a6b8b5 | ||
|
|
241f08bd74 | ||
|
|
b8f8067a87 | ||
|
|
965777da85 | ||
|
|
ffa62d4236 | ||
|
|
94a01c6010 | ||
|
|
232bf728c6 | ||
|
|
0e367580da | ||
|
|
40aad197da | ||
|
|
124fd2c978 | ||
|
|
0d32c58e41 | ||
|
|
09fa87ddfa | ||
|
|
cb356606d9 | ||
|
|
3de9cc1533 | ||
|
|
f1aaf16082 | ||
|
|
4c23f7a436 | ||
|
|
2188923153 | ||
|
|
2f47bab237 | ||
|
|
fe547a7690 | ||
|
|
b4f5a4a0a0 | ||
|
|
5929d5d9dd | ||
|
|
0b7de0ec65 | ||
|
|
87ac282014 | ||
|
|
e525a7c7c4 | ||
|
|
8a84c7f0a3 | ||
|
|
e462c22a07 | ||
|
|
3ea8a25127 | ||
|
|
45df197bd6 | ||
|
|
1ecb83bf73 | ||
|
|
aefa03291e | ||
|
|
6e02fa186a | ||
|
|
756074d8bd | ||
|
|
2caa09bebd | ||
|
|
72a182122a | ||
|
|
0688db7da3 | ||
|
|
0c6d96c407 | ||
|
|
1f48bd3e79 | ||
|
|
7103f4f0b3 | ||
|
|
210234255c | ||
|
|
73312bc6bb | ||
|
|
6ea9872a3e | ||
|
|
d54ceff7a3 | ||
|
|
6cf3e86c8a | ||
|
|
acc36e8d9b | ||
|
|
1670e73287 | ||
|
|
3b52b89fd6 | ||
|
|
c132ede510 | ||
|
|
4e62e4f696 | ||
|
|
c0addf22ed | ||
|
|
880642ef4a | ||
|
|
2f94e5990c | ||
|
|
4a5ce16322 | ||
|
|
454b08362d | ||
|
|
f80c584db0 | ||
|
|
68bcd6c159 | ||
|
|
a9a9061f96 | ||
|
|
196c98fc2a | ||
|
|
9ea2e69579 | ||
|
|
f4da2ef8ec | ||
|
|
8fb65a19b4 | ||
|
|
a2c6c34739 | ||
|
|
a2818037b3 | ||
|
|
02c7a22d43 | ||
|
|
f6e993dfc8 | ||
|
|
8866e2829f | ||
|
|
d016e0f443 | ||
|
|
0cbf6f8d76 | ||
|
|
641b58c409 | ||
|
|
5f0204f7b1 | ||
|
|
660d1a1800 | ||
|
|
8d209a16c5 | ||
|
|
ed786701fc | ||
|
|
4842b1ca13 | ||
|
|
0990550f45 | ||
|
|
84b215c3b0 | ||
|
|
2a7724f601 | ||
|
|
b119d763da | ||
|
|
ff25e6c18f | ||
|
|
2677f05f0d | ||
|
|
bbfa47bbf0 | ||
|
|
060c0d2e6f | ||
|
|
414396efb6 | ||
|
|
6825781718 | ||
|
|
2494fff094 | ||
|
|
924422261f | ||
|
|
f81e819901 | ||
|
|
81a2d70251 | ||
|
|
3a2a40c76a | ||
|
|
6c3fa13e41 | ||
|
|
0ea2354be5 | ||
|
|
079056cfbc | ||
|
|
1230fccbf9 | ||
|
|
73e0facaed | ||
|
|
94b1ad52fa | ||
|
|
6878d0d6e6 | ||
|
|
76e7568994 | ||
|
|
b176b2f0e6 | ||
|
|
af5805e396 | ||
|
|
b98f45df60 | ||
|
|
bb2571233d | ||
|
|
00629bac48 | ||
|
|
81e7f619eb | ||
|
|
b0ab9bb697 | ||
|
|
ae1e6f43f2 | ||
|
|
6eba2f145e | ||
|
|
13666027cc | ||
|
|
62cef096e1 | ||
|
|
af48b60876 | ||
|
|
b71357a955 | ||
|
|
9865a609da | ||
|
|
77bafb295e | ||
|
|
ba4c9dbd09 | ||
|
|
4e9cf8ac02 | ||
|
|
108dae11e9 | ||
|
|
16de98291f | ||
|
|
547f8917b4 | ||
|
|
f1da2ca643 | ||
|
|
9e6ea9454f | ||
|
|
fcd7e198c2 | ||
|
|
82523bd1d3 | ||
|
|
4ec5fac95c | ||
|
|
7fb3810eb1 | ||
|
|
ed2fe83491 | ||
|
|
3fd9c49fb9 | ||
|
|
69c0843d20 | ||
|
|
3f7ef9738d | ||
|
|
3cfc6981a4 | ||
|
|
8b2ea72be2 | ||
|
|
8eaa1f5e88 | ||
|
|
c72f622a87 | ||
|
|
8a0505eb6f | ||
|
|
799e837f35 | ||
|
|
4690ce5602 | ||
|
|
e972126cea | ||
|
|
db40fd8983 | ||
|
|
c2db7b8afd | ||
|
|
f403876784 | ||
|
|
3a9d4c7c77 | ||
|
|
e737ece570 | ||
|
|
948d19c446 | ||
|
|
ee81c9516a | ||
|
|
675012a2eb | ||
|
|
31a4ef10e1 | ||
|
|
a0d43d51c9 | ||
|
|
31035d2b3c | ||
|
|
4e8f323e47 | ||
|
|
4dd3d7ab5e | ||
|
|
63a7bf5ee9 | ||
|
|
0473da9f05 | ||
|
|
e5447f7417 | ||
|
|
62810d8c87 | ||
|
|
ca81d48432 | ||
|
|
b9c857130a | ||
|
|
a9bbc6d3c4 | ||
|
|
3a273b1837 | ||
|
|
5e6ff5a44f | ||
|
|
65129d1b52 | ||
|
|
54d9d870ee | ||
|
|
ffff6dd580 | ||
|
|
dc4a1ed5e5 | ||
|
|
8bbf0ce9ef | ||
|
|
a4e4021950 | ||
|
|
87fe48225f | ||
|
|
af47fa9b6d | ||
|
|
3de1e197aa | ||
|
|
2a1cbe67c6 | ||
|
|
f57404a3f0 | ||
|
|
87d815c659 | ||
|
|
651ccb183e | ||
|
|
67406c42ec | ||
|
|
cb953b4203 | ||
|
|
c0e2cfb684 | ||
|
|
9358c7313e | ||
|
|
02b377c244 | ||
|
|
d2287f584a | ||
|
|
cc94820cb3 | ||
|
|
b17c51e340 | ||
|
|
34dcc90ac7 | ||
|
|
8a1dc0ac65 | ||
|
|
a61bc51271 | ||
|
|
bccb8260e2 | ||
|
|
bedc609051 | ||
|
|
f1cab9296a | ||
|
|
4665f6027f | ||
|
|
891e85ba2b | ||
|
|
6957f54547 | ||
|
|
48ba111ccc | ||
|
|
8f2df79a96 | ||
|
|
415aeef95b | ||
|
|
cabd9be5f0 | ||
|
|
45e6e6eb18 | ||
|
|
b89cac48c5 | ||
|
|
00d55cddb5 | ||
|
|
88dd32b1a7 | ||
|
|
20e7acd24d | ||
|
|
9be871f14b | ||
|
|
0b358081c3 | ||
|
|
d172ae78fd | ||
|
|
5f1c9bc41b | ||
|
|
317d78d7c6 | ||
|
|
46090793a8 | ||
|
|
c3a995dd3d | ||
|
|
8020f7eb78 | ||
|
|
e8e847a662 | ||
|
|
d2c883877d | ||
|
|
0f7f6f6004 | ||
|
|
ebadf9d6a3 | ||
|
|
94fb74d6aa | ||
|
|
60b664d3b9 | ||
|
|
eee9249dfc | ||
|
|
7f7625b4a0 | ||
|
|
c681cd243a | ||
|
|
503e66790b | ||
|
|
a8dc91c238 | ||
|
|
bc554f77f4 | ||
|
|
dada7332c6 | ||
|
|
02b1d0a950 | ||
|
|
bcde742bbc | ||
|
|
79a83e8c46 | ||
|
|
3d56ff3547 | ||
|
|
218c3af11b | ||
|
|
ad20a312d6 | ||
|
|
ad788d6338 | ||
|
|
02b2b79060 | ||
|
|
610dca88a3 | ||
|
|
00a6a68b9c | ||
|
|
7852fd2ffb | ||
|
|
ead4b1d222 | ||
|
|
f290742f1b | ||
|
|
b31f267467 | ||
|
|
47db11a205 | ||
|
|
b263a89b07 | ||
|
|
dbe01d76a2 | ||
|
|
aa3b0a4e16 | ||
|
|
ff66e980eb | ||
|
|
6fbf8a8be0 | ||
|
|
1452ce62f4 | ||
|
|
d84d095c97 | ||
|
|
e1b498f82c | ||
|
|
06726fe361 | ||
|
|
ba3a274357 | ||
|
|
30a3d31a3d | ||
|
|
191c89c3b1 | ||
|
|
42b739154e | ||
|
|
721a251b34 | ||
|
|
1a66f85b67 | ||
|
|
3bba92f813 | ||
|
|
93c9674e2a | ||
|
|
a4b879227d | ||
|
|
485dfa6cde | ||
|
|
3105a8330e | ||
|
|
88e8661bf3 | ||
|
|
3a9629d93c | ||
|
|
29c14b1053 | ||
|
|
bd5aeb6b69 | ||
|
|
3674361f20 | ||
|
|
4a29456a7a | ||
|
|
3179a83cfb | ||
|
|
5fe1fe73c4 | ||
|
|
5025d8eb6e | ||
|
|
71697b59a3 | ||
|
|
518ae9658f | ||
|
|
41ad8b5c18 | ||
|
|
51cef3b5ca | ||
|
|
491d16a4e5 | ||
|
|
e752b6fb6f | ||
|
|
46bf6fbfdd | ||
|
|
fd5fe3d18d | ||
|
|
ca2da39614 | ||
|
|
067dad2d38 | ||
|
|
f91a8890a6 | ||
|
|
dd9b84f06e | ||
|
|
9ac17a88b3 | ||
|
|
9ea8148d84 | ||
|
|
16c65550bb | ||
|
|
961860adee | ||
|
|
6146b4d2d9 | ||
|
|
274cd3a1f3 | ||
|
|
762e8b8b6a | ||
|
|
a5a6e9be8a | ||
|
|
4ab65975f4 | ||
|
|
041f26a7c5 | ||
|
|
b351e709c1 | ||
|
|
fbad683810 | ||
|
|
2854c0627d | ||
|
|
c5fa6fe7f2 | ||
|
|
40c7232bb2 | ||
|
|
59e3465b6b | ||
|
|
2c591d2dca | ||
|
|
4673545f45 | ||
|
|
4703a45ff5 | ||
|
|
35aabd5e44 | ||
|
|
118944be9a | ||
|
|
8e1ecbb0ea | ||
|
|
00ba8c09f8 | ||
|
|
15b071acaa | ||
|
|
aa3dfb9a4b | ||
|
|
95e22d878a | ||
|
|
4f8c495563 | ||
|
|
1d6ea1db0f | ||
|
|
393cc5c634 | ||
|
|
34c2772a60 | ||
|
|
4d258ab5e8 | ||
|
|
a306f9074a | ||
|
|
6e30566363 | ||
|
|
2908224c95 | ||
|
|
e011853e7e | ||
|
|
104105c937 | ||
|
|
3fa98419a6 | ||
|
|
44d08ce41e | ||
|
|
0a1c1be00e | ||
|
|
7efd7abffe | ||
|
|
e27158507e | ||
|
|
d9ee2fa10d | ||
|
|
b30a7aa5a2 | ||
|
|
34c1aaac18 | ||
|
|
8dbb4c6b7e | ||
|
|
f5d5afba74 | ||
|
|
e09f0bb99f | ||
|
|
fddf51dc74 | ||
|
|
b8d4b981e0 | ||
|
|
892302442f | ||
|
|
39046ddfe1 | ||
|
|
ac14074bc4 | ||
|
|
7d548151d7 | ||
|
|
898ed70aa0 | ||
|
|
78842b59c9 | ||
|
|
f4f4f9ccd5 | ||
|
|
2ef9d72dbd | ||
|
|
b030f67eb7 | ||
|
|
8380a87a6e | ||
|
|
06b9bb0c34 | ||
|
|
17893ecefd | ||
|
|
efc1b01901 | ||
|
|
88fa93f1de | ||
|
|
36385a2432 | ||
|
|
1e05327c5d | ||
|
|
0b7a08a2d8 | ||
|
|
237e0ee367 | ||
|
|
f9230856af | ||
|
|
9bf9c3a439 | ||
|
|
25c4efd2db | ||
|
|
8f6f0ef511 | ||
|
|
a924fbb490 | ||
|
|
4c01dfc9fd | ||
|
|
5ee15239fd | ||
|
|
69d36b0226 | ||
|
|
87db1aaa57 | ||
|
|
5e096de534 | ||
|
|
97d53bf7e9 | ||
|
|
6fbc690097 | ||
|
|
311f6eacd7 | ||
|
|
0dee8c5f34 | ||
|
|
ddf85bae72 | ||
|
|
695d61f87c | ||
|
|
9584371f89 | ||
|
|
509bfb5b5e | ||
|
|
f853b7dc40 | ||
|
|
0693a97577 | ||
|
|
8e00df1de5 | ||
|
|
28f0536b31 | ||
|
|
639bfbfc9a | ||
|
|
0c734d6db0 | ||
|
|
e0f5b5125c | ||
|
|
28065e36e8 | ||
|
|
8088f0cd6f | ||
|
|
36cdadd238 | ||
|
|
1061d5c5fa | ||
|
|
c1bd438d89 | ||
|
|
dd8c0a759f | ||
|
|
0f16f3177e | ||
|
|
acc2fd9c94 | ||
|
|
8feb842717 | ||
|
|
f19eaaa557 | ||
|
|
3fa0c2d18b | ||
|
|
9393e1369b | ||
|
|
8342b0ecec | ||
|
|
9a291b6543 | ||
|
|
ec403f8940 | ||
|
|
047dab769d | ||
|
|
5d8cd288d3 | ||
|
|
8a63682382 | ||
|
|
036f151a42 | ||
|
|
5bc1356192 | ||
|
|
c04a111d10 | ||
|
|
da5eabc91f | ||
|
|
79f8947bfa | ||
|
|
160a22519e | ||
|
|
cc9a1d446c | ||
|
|
b78ea90c27 | ||
|
|
cbb5d2b423 | ||
|
|
c759743e40 | ||
|
|
3b2ecc6003 | ||
|
|
4790cb5009 | ||
|
|
ee0080487a | ||
|
|
f70b820cbe | ||
|
|
1ccae61d40 | ||
|
|
f670472e55 | ||
|
|
f94aa731ed | ||
|
|
5c80bfe430 | ||
|
|
8d7866b58d | ||
|
|
179bf03caf | ||
|
|
0371a805ed | ||
|
|
57b48e0719 | ||
|
|
eb767abc55 | ||
|
|
dbda77b091 | ||
|
|
2c1454270e | ||
|
|
1ec72e606b | ||
|
|
24bfdd741a | ||
|
|
f0ce4094dd | ||
|
|
9cbcd88d4e | ||
|
|
8ea6e6ce59 | ||
|
|
6d0f8c9ead | ||
|
|
43d91a5c40 | ||
|
|
564e527ac7 | ||
|
|
6d3b733cb1 | ||
|
|
0e967726de | ||
|
|
001a4c46db | ||
|
|
1a9d0926ee | ||
|
|
05a756beaa | ||
|
|
1014847e9d | ||
|
|
d3309c2e84 | ||
|
|
565002a918 | ||
|
|
08b83e7ed1 | ||
|
|
b4c2f523fe | ||
|
|
4ba5d6b9a8 | ||
|
|
59ceb05f99 | ||
|
|
929c8e96c6 | ||
|
|
1b5a730358 | ||
|
|
79255e8e7d | ||
|
|
50845261fe | ||
|
|
da090f0ff6 | ||
|
|
60ead8c5f3 | ||
|
|
6942569409 | ||
|
|
498a608941 | ||
|
|
eee7154c33 | ||
|
|
a735660af8 | ||
|
|
c5ed7172b3 | ||
|
|
4b28362920 | ||
|
|
dfeaa416c0 | ||
|
|
3ce4dd94f7 | ||
|
|
0ee1d406e0 | ||
|
|
dad814e046 | ||
|
|
6246f20e63 | ||
|
|
f4ad55f6d7 | ||
|
|
027c4b42f7 | ||
|
|
fb6c9f8b7d | ||
|
|
33d2eaee5b | ||
|
|
ae3ccd7fb6 | ||
|
|
72dbea256a | ||
|
|
ea0ff1bc01 | ||
|
|
2bca33f535 | ||
|
|
75c5bb846b | ||
|
|
0da551c7fd | ||
|
|
5583dc26f9 | ||
|
|
339fa3bd60 | ||
|
|
dbaaa977e7 | ||
|
|
b10e99d374 | ||
|
|
a7d572f060 | ||
|
|
127234f655 | ||
|
|
2c13c8fe6e | ||
|
|
c0b9900cdc | ||
|
|
44e8d57935 | ||
|
|
d85f8164c0 | ||
|
|
32407c2ba5 | ||
|
|
51e82a5561 | ||
|
|
3fb75ca904 | ||
|
|
64a70c7c18 | ||
|
|
b9a68090b1 | ||
|
|
5344854056 | ||
|
|
abad894fd5 | ||
|
|
8872227af5 | ||
|
|
30a07a49d0 | ||
|
|
0a37cce5fe | ||
|
|
fc76ed9949 | ||
|
|
d55d042a14 | ||
|
|
d7e07f4d51 | ||
|
|
22a6ecadbb | ||
|
|
53ff133b03 | ||
|
|
d1ab68ebfa | ||
|
|
655b7dc13c | ||
|
|
48bfe0453b | ||
|
|
87a05f057a | ||
|
|
4f540fe7fd | ||
|
|
1fd675fd09 | ||
|
|
bf72adbb57 | ||
|
|
dd45703d73 | ||
|
|
7c0d3cdb10 | ||
|
|
5462cc0fcf | ||
|
|
8fe9f15b3b | ||
|
|
c49c6e5d19 | ||
|
|
636c54ec6f | ||
|
|
52ee07f2fd | ||
|
|
02ef4a99b7 | ||
|
|
73a4431a34 | ||
|
|
e252558ef6 | ||
|
|
5680b5d9a6 | ||
|
|
86c0a68ccd | ||
|
|
9379e7ce45 | ||
|
|
04d2234169 | ||
|
|
66f4419518 | ||
|
|
be4ad2ec07 | ||
|
|
853b2205dd | ||
|
|
80f104c522 | ||
|
|
1fa2fd9b7f | ||
|
|
fa108d6a65 | ||
|
|
a82d93914e | ||
|
|
389349198f | ||
|
|
225a844e0f | ||
|
|
f018c719a6 | ||
|
|
2a229571ad | ||
|
|
35959b547c | ||
|
|
796007377d | ||
|
|
5c73d0ae75 | ||
|
|
bb90103e74 | ||
|
|
0149bc504d | ||
|
|
3db035520b | ||
|
|
618b59932c | ||
|
|
9ef05ad456 | ||
|
|
c8a0dbb59a | ||
|
|
35a0b045f8 | ||
|
|
a4369c833d | ||
|
|
354f1da708 | ||
|
|
7e47d257d1 | ||
|
|
c3d2b3578d | ||
|
|
783aa06a46 | ||
|
|
faa82ff35a | ||
|
|
3008123d6b | ||
|
|
2d2987066d | ||
|
|
c84ec04efa | ||
|
|
197b45c1d1 | ||
|
|
af9ecf0a61 | ||
|
|
530fb58337 | ||
|
|
6a891021b1 | ||
|
|
0e7c68b50d | ||
|
|
32a32d3d21 | ||
|
|
fca71813d4 | ||
|
|
3618f14531 | ||
|
|
9de3e76a53 | ||
|
|
e472fdbce4 | ||
|
|
c9fcedb40b | ||
|
|
bd8c3e9181 | ||
|
|
26d0aa76f8 | ||
|
|
20f4ec6576 | ||
|
|
d0bc23473c | ||
|
|
c33f6adf62 | ||
|
|
d4efa105b7 | ||
|
|
e8641ce257 | ||
|
|
d7a4bdc3f1 | ||
|
|
e66215295c | ||
|
|
552bb3e6db | ||
|
|
a96da05ab8 | ||
|
|
fb5ee4a9d0 | ||
|
|
da13067b57 | ||
|
|
d48d69c765 | ||
|
|
5098b2af77 | ||
|
|
5576d6b014 | ||
|
|
b072399229 | ||
|
|
4f0ab43d58 | ||
|
|
3f742880b5 | ||
|
|
0704194460 | ||
|
|
56e747f558 | ||
|
|
61c22f2295 | ||
|
|
c4bbaeda86 | ||
|
|
678ffc7503 | ||
|
|
a080a47268 | ||
|
|
82e8104539 | ||
|
|
11bd8e72ef | ||
|
|
03c2a90206 | ||
|
|
c38ab64b6a | ||
|
|
2548da9aed | ||
|
|
2fa08123a0 | ||
|
|
20c3d45b9c | ||
|
|
c8af3226de | ||
|
|
4b669fb1c7 | ||
|
|
340f6d721a | ||
|
|
489f3ff3c9 | ||
|
|
566d3613d1 | ||
|
|
e691cfa9e3 | ||
|
|
a4a1bf07aa | ||
|
|
7ea7d1d5f2 | ||
|
|
686c68c627 | ||
|
|
c652dcfd2a | ||
|
|
01fab5a6e4 | ||
|
|
16a5adcfde | ||
|
|
d550d36637 | ||
|
|
3857c1a9b2 | ||
|
|
2f8bc9239b | ||
|
|
9de934e2bd | ||
|
|
769f1db011 | ||
|
|
da72c58146 | ||
|
|
ef34dd2461 | ||
|
|
90fdb95429 | ||
|
|
d5c0d11404 | ||
|
|
b0d116632c | ||
|
|
a67d92c2ca | ||
|
|
21b208398b | ||
|
|
65b3e956df | ||
|
|
c8d0715b16 | ||
|
|
16d307e543 | ||
|
|
5ed07639af | ||
|
|
e2655e93bc | ||
|
|
3a20be1d1a | ||
|
|
8244f8e9cb | ||
|
|
c575fd7395 | ||
|
|
6a67cf0009 | ||
|
|
79292481b3 | ||
|
|
829f341de3 | ||
|
|
b509ef4dad | ||
|
|
422c8d9a64 | ||
|
|
d0b5c5cee8 | ||
|
|
9b9548306d | ||
|
|
b28e535540 | ||
|
|
1f7584ace2 | ||
|
|
21512e8228 | ||
|
|
a34903aa33 | ||
|
|
4eba402adb | ||
|
|
64c5f5aee7 | ||
|
|
1bda37776b | ||
|
|
1c5d7d6cc3 | ||
|
|
b81ff060ae | ||
|
|
0cebbfca23 | ||
|
|
b9c7814dfd | ||
|
|
ba9fd6719a | ||
|
|
f0ad12ce2e | ||
|
|
21acf53d3f | ||
|
|
2f5927d531 | ||
|
|
cf950a8d6f | ||
|
|
48b73ad998 | ||
|
|
8fc94f127b | ||
|
|
ce33f42e62 | ||
|
|
61032e55b5 | ||
|
|
6160d3f51e | ||
|
|
5d725f6de9 | ||
|
|
020e9e59ed | ||
|
|
bd777c1e56 | ||
|
|
087b12c802 | ||
|
|
42f2642d72 | ||
|
|
9c8d0ed5a1 | ||
|
|
9fd1705acf | ||
|
|
c981b52832 | ||
|
|
d074b6fd1a | ||
|
|
7da5a25e2f | ||
|
|
b96b8eb787 | ||
|
|
a25be5ee6e | ||
|
|
bf9d1f1967 | ||
|
|
561221fdc3 | ||
|
|
8548afa231 | ||
|
|
803e695d5c | ||
|
|
5c58776313 | ||
|
|
0db39ea08a | ||
|
|
d76fb5d7e5 | ||
|
|
f37ab8158c | ||
|
|
33db5acd13 | ||
|
|
e068204876 | ||
|
|
d849231caf | ||
|
|
996bd58fcb | ||
|
|
9b70dc5253 | ||
|
|
31af9ca80f | ||
|
|
08aa2ec4ca | ||
|
|
95be2e24ce | ||
|
|
7b200ec85e | ||
|
|
cf1b45c052 | ||
|
|
57e7280ac9 | ||
|
|
64d432cb34 | ||
|
|
fde23c89e2 | ||
|
|
0e3bc8a443 | ||
|
|
88bcd133f2 | ||
|
|
2072b67e04 | ||
|
|
2a2974580c | ||
|
|
65f72a48fb | ||
|
|
65674c7c51 | ||
|
|
8d1b630b24 | ||
|
|
1235a66f83 | ||
|
|
411e7f4511 | ||
|
|
cf095cbdd2 | ||
|
|
394db90ec9 | ||
|
|
72644f1416 | ||
|
|
ed2fc0e391 | ||
|
|
c9f4d983a0 | ||
|
|
694db54d9d | ||
|
|
15b663ba0b | ||
|
|
23ee5e276c | ||
|
|
7c24a1bbaa | ||
|
|
32eee2cdf1 | ||
|
|
7dbad8928f | ||
|
|
0e81207758 | ||
|
|
c67266833a | ||
|
|
d6b0b6ff52 | ||
|
|
9d0ad3586d | ||
|
|
7393d5d98c | ||
|
|
7a819a60ae | ||
|
|
c735659592 | ||
|
|
c36745db97 | ||
|
|
a5284af2b8 | ||
|
|
4989c3dc48 | ||
|
|
3925b0a8ec | ||
|
|
356610ba1d | ||
|
|
9eae72f99d | ||
|
|
1d12fc1aaa | ||
|
|
f9bd085757 | ||
|
|
1003926665 | ||
|
|
709180932e | ||
|
|
132326f8f2 | ||
|
|
92e86de630 | ||
|
|
3e8a145fce | ||
|
|
a5db6a84b6 | ||
|
|
f192b89ef9 | ||
|
|
637395b075 | ||
|
|
b03172f4a2 | ||
|
|
24225315fa | ||
|
|
2bc9256a7a | ||
|
|
264cf020b6 | ||
|
|
ceafc7835b | ||
|
|
db8d4ee076 | ||
|
|
26f7907b17 | ||
|
|
c35f1e0b29 | ||
|
|
e2ee00e36e | ||
|
|
d87f77c41a | ||
|
|
13fcce2d9a | ||
|
|
216761656f | ||
|
|
05e9d708ed | ||
|
|
cc321385cd | ||
|
|
038d39f294 | ||
|
|
3555a01541 | ||
|
|
5d52266eac | ||
|
|
5368756983 | ||
|
|
f74e136f46 | ||
|
|
040c1c686a | ||
|
|
e74c33ce04 | ||
|
|
ab24634637 | ||
|
|
8f3bdc20ba | ||
|
|
74aaaed4db | ||
|
|
9c64c20ceb | ||
|
|
b92c748fcc | ||
|
|
844dde4e6d | ||
|
|
c0de0ca36d | ||
|
|
ad3bc4a6f7 | ||
|
|
572b2cff57 | ||
|
|
fb9cf43768 | ||
|
|
f41db8bb91 | ||
|
|
89c8e7c51a | ||
|
|
0ad21cd47a | ||
|
|
7dbf81fe3d | ||
|
|
3072309574 | ||
|
|
573e9220a2 | ||
|
|
e22f02d228 | ||
|
|
b620b7efa1 | ||
|
|
d1593326cb | ||
|
|
6a8e6d45b5 | ||
|
|
11336964a1 | ||
|
|
71e98d54f5 | ||
|
|
417ba87fcb | ||
|
|
f71fea4ef5 |
41
.github/workflows/android-continuous.yml
vendored
Normal file
41
.github/workflows/android-continuous.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Android
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-android
|
||||
path: out/filament-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filamat-android-full
|
||||
path: out/filamat-android-full-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filamat-android-lite
|
||||
path: out/filamat-android-lite-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: gltfio-android-release
|
||||
path: out/gltfio-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: gltfio-android-lite-release
|
||||
path: out/gltfio-android-lite-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-utils-android-release
|
||||
path: out/filament-utils-android-release.aar
|
||||
24
.github/workflows/ios-continuous.yml
vendored
Normal file
24
.github/workflows/ios-continuous.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: iOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-ios
|
||||
path: out/filament-release-ios.tgz
|
||||
- name: Build iOS samples
|
||||
run: |
|
||||
cd build/ios && ./build-samples.sh continuous
|
||||
21
.github/workflows/linux-continuous.yml
vendored
Normal file
21
.github/workflows/linux-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: build-linux
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/linux && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-linux
|
||||
path: out/filament-release-linux.tgz
|
||||
21
.github/workflows/mac-continuous.yml
vendored
Normal file
21
.github/workflows/mac-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: macOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/mac && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-mac
|
||||
path: out/filament-release-darwin.tgz
|
||||
63
.github/workflows/presubmit.yml
vendored
Normal file
63
.github/workflows/presubmit.yml
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
name: Presubmit
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build-desktop:
|
||||
name: build-desktop
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
cd build/$WORKFLOW_OS && ./build.sh presubmit
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat presubmit
|
||||
shell: cmd
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh presubmit
|
||||
|
||||
build-ios:
|
||||
name: build-iOS
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh presubmit
|
||||
- name: Build iOS samples
|
||||
run: |
|
||||
cd build/ios && ./build-samples.sh presubmit
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh presubmit
|
||||
178
.github/workflows/release.yml
vendored
Normal file
178
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
name: Release
|
||||
|
||||
# This Workflow can be triggered two ways:
|
||||
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to build and upload assets.
|
||||
# 2. A repository_dispatch API event is sent. This triggers a build for only the platform specified in the dispatch event.
|
||||
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.client_payload.release_tag }}
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
build-desktop:
|
||||
name: build-desktop
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'desktop'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
cd build/$WORKFLOW_OS && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${DATE}-mac.tgz; fi;
|
||||
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${DATE}-linux.tgz; fi;
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'web'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-release-web.tgz out/filament-${DATE}-web.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'android'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-android-release.aar out/filament-${DATE}-android.aar
|
||||
mv out/filamat-android-full-release.aar out/filamat-${DATE}-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${DATE}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${DATE}-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${DATE}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${DATE}-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${DATE}-lite-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'ios'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-release-ios.tgz out/filament-${DATE}-ios.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'windows'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
run: |
|
||||
REF=${RELEASE_TAG:-${GITHUB_REF}}
|
||||
TAG=${REF##*/}
|
||||
echo ::set-output name=ref::${REF}
|
||||
echo ::set-output name=tag::${TAG}
|
||||
shell: bash
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat release
|
||||
shell: cmd
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install PyGithub
|
||||
DATE=`date +%Y%m%d`
|
||||
mv out/filament-windows.tgz out/filament-${DATE}-windows.tgz
|
||||
python build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
21
.github/workflows/web-continuous.yml
vendored
Normal file
21
.github/workflows/web-continuous.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && ./build.sh continuous
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-web
|
||||
path: out/filament-release-web.tgz
|
||||
22
.github/workflows/windows-continuous.yml
vendored
Normal file
22
.github/workflows/windows-continuous.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Windows
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat continuous
|
||||
shell: cmd
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-windows
|
||||
path: out/filament-windows.tgz
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,7 +3,7 @@
|
||||
imgui.ini
|
||||
cmake-*
|
||||
ImportExecutables-*.cmake
|
||||
out
|
||||
/out*
|
||||
dist
|
||||
dist-*
|
||||
toolchains
|
||||
@@ -11,3 +11,5 @@ filament/docs/html/**
|
||||
.vscode
|
||||
gltf_baker.ini
|
||||
*tmp*.png
|
||||
civetweb.txt
|
||||
/TAGS
|
||||
|
||||
451
BUILDING.md
Normal file
451
BUILDING.md
Normal file
@@ -0,0 +1,451 @@
|
||||
## Building Filament
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (or more recent)
|
||||
- clang 7.0 (or more recent)
|
||||
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
To build the Java based components of the project you can optionally install (recommended):
|
||||
|
||||
- OpenJDK 1.8 (or more recent)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
section below.
|
||||
|
||||
Building the `rays` library (used for light baking) is optional and requires the following packages:
|
||||
|
||||
- embree 3.0+
|
||||
- libtbb-dev
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.6 or more recent
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 21 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
Make sure the environment variable `ANDROID_HOME` points to the location of your Android SDK.
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. To do so, the environment
|
||||
variable `JAVA_HOME` should point to the location of your JDK.
|
||||
|
||||
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
|
||||
|
||||
### IDE
|
||||
|
||||
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
||||
in CLion to obtain a usable project.
|
||||
|
||||
### Easy build
|
||||
|
||||
Once the required OS specific dependencies listed below are installed, you can use the script
|
||||
located in `build.sh` to build Filament easily on macOS and Linux.
|
||||
|
||||
This script can be invoked from anywhere and will produce build artifacts in the `out/` directory
|
||||
inside the Filament source tree.
|
||||
|
||||
To trigger an incremental debug build:
|
||||
|
||||
```
|
||||
$ ./build.sh debug
|
||||
```
|
||||
|
||||
To trigger an incremental release build:
|
||||
|
||||
```
|
||||
$ ./build.sh release
|
||||
```
|
||||
|
||||
To trigger both incremental debug and release builds:
|
||||
|
||||
```
|
||||
$ ./build.sh debug release
|
||||
```
|
||||
|
||||
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
|
||||
You can force a clean build by adding the `-c` flag. The script offers more features described
|
||||
by executing `build.sh -h`.
|
||||
|
||||
### Disabling Java builds
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. If you wish to skip this
|
||||
compilation step simply pass the `-j` flag to `build.sh`:
|
||||
|
||||
```
|
||||
$ ./build.sh -j release
|
||||
```
|
||||
|
||||
If you use CMake directly instead of the build script, pass `-DFILAMENT_ENABLE_JAVA=OFF`
|
||||
to CMake instead.
|
||||
|
||||
### Filament-specific CMake Options
|
||||
|
||||
The following CMake options are boolean options specific to Filament:
|
||||
|
||||
- `FILAMENT_ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
|
||||
- `FILAMENT_ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
|
||||
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
|
||||
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
|
||||
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
|
||||
- `FILAMENT_GENERATE_JS_DOCS`: Build WebGL documentation and tutorials
|
||||
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
|
||||
- `FILAMENT_USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
|
||||
- `FILAMENT_SKIP_SAMPLES`: Don't build sample apps
|
||||
|
||||
To turn an option on or off:
|
||||
|
||||
```
|
||||
$ cd <cmake-build-directory>
|
||||
$ cmake . -DOPTION=ON # Relace OPTION with the option name, set to ON / OFF
|
||||
```
|
||||
|
||||
Options can also be set with the CMake GUI.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7` or higher
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
If you'd like to run `cmake` directly rather than using the build script, it can be invoked as
|
||||
follows, with some caveats that are explained further down.
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
Your Linux distribution might default to `gcc` instead of `clang`, if that's the case invoke
|
||||
`cmake` with the following command:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-7
|
||||
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
You can also export the `CC` and `CXX` environment variables to always point to `clang`. Another
|
||||
solution is to use `update-alternatives` to both change the default compiler, and point to a
|
||||
specific version of clang:
|
||||
|
||||
```
|
||||
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
|
||||
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
|
||||
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```
|
||||
|
||||
Finally, invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja
|
||||
```
|
||||
|
||||
This will build Filament, its tests and samples, and various host tools.
|
||||
|
||||
### macOS
|
||||
|
||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||
make sure the command line tools are setup by running:
|
||||
|
||||
```
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
After installing Java 1.8 you must also ensure that your `JAVA_HOME` environment variable is
|
||||
properly set. If it doesn't already point to the appropriate JDK, you can simply add the following
|
||||
to your `.profile`:
|
||||
|
||||
```
|
||||
export JAVA_HOME="$(/usr/libexec/java_home)"
|
||||
```
|
||||
|
||||
Then run `cmake` and `ninja` to trigger a build:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
$ ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Building on Windows with Visual Studio 2019
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Visual Studio 2019](https://www.visualstudio.com/downloads)
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [CMake 3.14 or later](https://github.com/Kitware/CMake/releases/download/v3.14.7/cmake-3.14.7-win64-x64.msi)
|
||||
|
||||
The latest Windows SDK can also by installed by opening Visual Studio and selecting _Get Tools and
|
||||
Features..._ under the _Tools_ menu.
|
||||
|
||||
Open the `x64 Native Tools Command Prompt for VS 2019`.
|
||||
|
||||
Create a working directory, and run cmake in it:
|
||||
|
||||
```
|
||||
> mkdir out
|
||||
> cd out
|
||||
> cmake ..
|
||||
```
|
||||
|
||||
Open the generated solution file `TNT.sln` in Visual Studio.
|
||||
|
||||
To build all targets, run _Build Solution_ from the _Build_ menu. Alternatively, right click on a
|
||||
target in the _Solution Explorer_ and choose _Build_ to build a specific target.
|
||||
|
||||
For example, build the `material_sandbox` sample and run it from the `out` directory with:
|
||||
|
||||
```
|
||||
> samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
### Android
|
||||
|
||||
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
||||
host tools are required to successfully build for Android.
|
||||
|
||||
Filament can be built for the following architectures:
|
||||
|
||||
- ARM 64-bit (`arm64-v8a`)
|
||||
- ARM 32-bit (`armeabi-v7a`)
|
||||
- Intel 64-bit (`x86_64`)
|
||||
- Intel 32-bit (`x86`)
|
||||
|
||||
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
|
||||
foremost for `arm64-v8a`.
|
||||
|
||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||
|
||||
#### Easy Android build
|
||||
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
`-p android` flag. For instance to build the release target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p android release
|
||||
```
|
||||
|
||||
Run `build.sh -h` for more information.
|
||||
|
||||
#### Manual builds
|
||||
|
||||
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
|
||||
below show how to build Filament for ARM 64-bit (`aarch64`).
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-aarch64
|
||||
$ cd out/android-build-release-aarch64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||
|
||||
#### AAR
|
||||
|
||||
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
||||
as explained in the sections above. You must have the following ABIs built in
|
||||
`out/android-release/filament/lib/`:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To build Filament's AAR simply open the Android Studio project in `android/`. The
|
||||
AAR is a universal AAR that contains all supported build targets:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To filter out unneeded ABIs, rely on the `abiFilters` of the project that links against Filament's
|
||||
AAR.
|
||||
|
||||
Alternatively you can build the AAR from the command line by executing the following in the
|
||||
`android/` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
|
||||
the CMake install prefix used in the previous steps).
|
||||
|
||||
#### Using Filament's AAR
|
||||
|
||||
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
||||
sure to add the newly created module as a dependency to your application.
|
||||
|
||||
If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
|
||||
your Gradle build file. For example:
|
||||
|
||||
```
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
arm7 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
x86_64 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86_64'.
|
||||
}
|
||||
}
|
||||
x86 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86'
|
||||
}
|
||||
}
|
||||
universal {
|
||||
dimension 'cpuArch'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WebAssembly
|
||||
|
||||
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
||||
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
||||
[linux](#linux)), which will ensure you have the proper dependencies installed.
|
||||
|
||||
Next, you need to install the Emscripten SDK. The following instructions show how to install the
|
||||
same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/1b1f08f.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
source ./emsdk_env.sh
|
||||
```
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```
|
||||
export EMSDK=<your chosen home for the emscripten SDK>
|
||||
./build.sh -p webgl release
|
||||
```
|
||||
|
||||
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
|
||||
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
|
||||
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
|
||||
use Python to create a quick localhost server:
|
||||
|
||||
```
|
||||
cd out/cmake-webgl-release/web/samples
|
||||
python3 -m http.server # Python 3
|
||||
python -m SimpleHTTPServer # Python 2.7
|
||||
```
|
||||
|
||||
You can then open http://localhost:8000/suzanne.html in your web browser.
|
||||
|
||||
Alternatively, if you have node installed you can use the
|
||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||
web page when it detects a change.
|
||||
|
||||
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||
such as meshes, textures, and materials.
|
||||
|
||||
## Running the native samples
|
||||
|
||||
The `samples/` directory contains several examples of how to use Filament with SDL2.
|
||||
|
||||
Some of the samples accept FBX/OBJ meshes while others rely on the `filamesh` file format. To
|
||||
generate a `filamesh ` file from an FBX/OBJ asset, run the `filamesh` tool
|
||||
(`./tools/filamesh/filamesh` in your build directory):
|
||||
|
||||
```
|
||||
filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
|
||||
```
|
||||
|
||||
Most samples accept an IBL that must be generated using the `cmgen` tool (`./tools/filamesh/cmgen`
|
||||
in your build directory). These sample apps expect a path to a directory containing the '.rgb32f'
|
||||
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data). To generate an IBL simply use
|
||||
this command:
|
||||
|
||||
```
|
||||
cmgen -x ./ibls/ my_ibl.exr
|
||||
```
|
||||
|
||||
The source environment map can be a PNG (8 or 16 bit), a PSD (16 or 32 bit), an HDR or an OpenEXR
|
||||
file. The environment map can be an equirectangular projection, a horizontal cross, a vertical
|
||||
cross, or a list of cubemap faces (horizontal or vertical).
|
||||
|
||||
`cmgen` will automatically create a directory based on the name of the source environment map. In
|
||||
the example above, the final directory will be `./ibls/my_ibl/`. This directory should contain the
|
||||
pre-filtered environment map (one file per cubemap face and per mip level), the environment map
|
||||
texture for the skybox and a text file containing the level harmonics for indirect diffuse
|
||||
lighting.
|
||||
|
||||
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.1`. The numerical
|
||||
value is the desired roughness between 0 and 1.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
$ doxygen docs/doxygen/filament.doxygen
|
||||
```
|
||||
|
||||
Finally simply open `docs/html/index.html` in your web browser.
|
||||
155
CMakeLists.txt
155
CMakeLists.txt
@@ -11,14 +11,49 @@ project(TNT)
|
||||
# ==================================================================================================
|
||||
# Options
|
||||
# ==================================================================================================
|
||||
option(FILAMENT_ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
|
||||
|
||||
option(ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
|
||||
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
|
||||
|
||||
option(USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
|
||||
option(FILAMENT_GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
|
||||
|
||||
option(GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
|
||||
option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
|
||||
|
||||
option(ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
|
||||
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
|
||||
|
||||
# ==================================================================================================
|
||||
# CMake policies
|
||||
# ==================================================================================================
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
|
||||
cmake_policy(SET CMP0074 NEW)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Support for ccache
|
||||
# ==================================================================================================
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if (CCACHE_PROGRAM)
|
||||
set(C_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
|
||||
|
||||
configure_file(build/launch-c.in launch-c)
|
||||
configure_file(build/launch-cxx.in launch-cxx)
|
||||
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_BINARY_DIR}/launch-cxx"
|
||||
)
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# OS specific
|
||||
@@ -69,16 +104,15 @@ endif()
|
||||
# Check if embree is available.
|
||||
# This is an optional dependency and can be installed with homebrew, apt-get, etc.
|
||||
# ==================================================================================================
|
||||
|
||||
find_package(embree 3.0 QUIET PATHS /usr/lib64/cmake)
|
||||
if (embree_FOUND AND NOT ANDROID)
|
||||
if (embree_FOUND AND NOT ANDROID AND NOT IOS)
|
||||
message("Found embree in ${embree_DIR}")
|
||||
set(MKLDNN_THREADING "TBB")
|
||||
include(third_party/OpenImageDenoise/cmake/resource.cmake)
|
||||
include(third_party/OpenImageDenoise/mkl-dnn/cmake/Threading.cmake)
|
||||
include(third_party/OpenImageDenoise/mkl-dnn/cmake/TBB.cmake)
|
||||
find_package(TBB QUIET)
|
||||
if (TBB_FOUND AND "${TBB_VERSION_MAJOR}" VERSION_EQUAL 2019)
|
||||
if (TBB_FOUND)
|
||||
message("Found TBB ${TBB_VERSION}")
|
||||
add_definitions(-DFILAMENT_HAS_EMBREE)
|
||||
set(DENOISE_LIBRARY OpenImageDenoise)
|
||||
@@ -113,7 +147,7 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if (CMAKE_C_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
|
||||
message(FATAL_ERROR "Detected C compiler Clang ${CMAKE_C_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
elseif (NOT MSVC)
|
||||
message(FATAL_ERROR "Detected C compiler ${CMAKE_C_COMPILER_ID} is unsupported")
|
||||
endif()
|
||||
|
||||
@@ -121,19 +155,21 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
|
||||
message(FATAL_ERROR "Detected CXX compiler Clang ${CMAKE_CXX_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
|
||||
endif()
|
||||
else()
|
||||
elseif (NOT MSVC)
|
||||
message(FATAL_ERROR "Detected CXX compiler ${CMAKE_CXX_COMPILER_ID} is unsupported")
|
||||
endif()
|
||||
|
||||
# Detect use of the clang-cl.exe frontend, which does not support all of clangs normal options
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
|
||||
set(CLANG_CL true)
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
|
||||
message(FATAL_ERROR "Building with Clang on Windows is no longer supported. Use MSVC 2019 instead.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Link time optimizations (LTO)
|
||||
# ==================================================================================================
|
||||
if (ENABLE_LTO)
|
||||
if (FILAMENT_ENABLE_LTO)
|
||||
include(CheckIPOSupported)
|
||||
|
||||
check_ipo_supported(RESULT IPO_SUPPORT)
|
||||
@@ -152,9 +188,14 @@ if (WIN32)
|
||||
set(CXX_STANDARD "/std:c++14")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function")
|
||||
if (MSVC)
|
||||
set(CXX_STANDARD "/std:c++latest")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} /W0 /Zc:__cplusplus")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function")
|
||||
endif()
|
||||
|
||||
if (USE_EXTERNAL_GLES3)
|
||||
if (FILAMENT_USE_EXTERNAL_GLES3)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
|
||||
endif()
|
||||
|
||||
@@ -173,7 +214,7 @@ if (CYGWIN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
|
||||
endif()
|
||||
|
||||
if (CLANG_CL)
|
||||
if (MSVC)
|
||||
# Since the "secure" replacements that MSVC suggests are not portable, disable
|
||||
# the deprecation warnings. Also disable warnings about use of POSIX functions (i.e. "unlink").
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE")
|
||||
@@ -189,7 +230,7 @@ endif()
|
||||
# ==================================================================================================
|
||||
# Release compiler flags
|
||||
# ==================================================================================================
|
||||
if (NOT CLANG_CL)
|
||||
if (NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
|
||||
endif()
|
||||
|
||||
@@ -199,6 +240,13 @@ if (ANDROID OR WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
endif()
|
||||
|
||||
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
|
||||
# between C++ and JavaScript in order to efficiently access typed arrays, which are unbound.
|
||||
# NOTE: This is not documented in emscripten so we should consider a different approach.
|
||||
if (WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Debug compiler flags
|
||||
# ==================================================================================================
|
||||
@@ -206,17 +254,24 @@ endif()
|
||||
# -fsanitize=undefined causes extremely long link times
|
||||
# -fsanitize=address causes a crash with assimp, which we can't explain for now
|
||||
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
|
||||
# clang-cl.exe on Windows does not support -fstack-protector.
|
||||
if (NOT CLANG_CL)
|
||||
if (NOT MSVC AND NOT WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
|
||||
|
||||
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
|
||||
# See: https://forums.developer.apple.com/thread/121887
|
||||
if (APPLE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-check")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Linker flags
|
||||
# ==================================================================================================
|
||||
# Strip unused sections
|
||||
set(GC_SECTIONS "-Wl,--gc-sections")
|
||||
if (NOT WEBGL)
|
||||
set(GC_SECTIONS "-Wl,--gc-sections")
|
||||
endif()
|
||||
set(B_SYMBOLIC_FUNCTIONS "-Wl,-Bsymbolic-functions")
|
||||
|
||||
if (APPLE)
|
||||
@@ -229,9 +284,6 @@ if (APPLE)
|
||||
# prevents ar from invoking ranlib, let CMake do it
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc -S <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc -S <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
elseif (CLANG_CL)
|
||||
set(GC_SECTIONS "")
|
||||
set(B_SYMBOLIC_FUNCTIONS "")
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
|
||||
@@ -324,20 +376,47 @@ endif()
|
||||
# ==================================================================================================
|
||||
# Functions
|
||||
# ==================================================================================================
|
||||
## The MSVC compiler has a limitation on literal string length which is reached when all the
|
||||
## licenses are concatenated together into a large string... so split them into multiple strings.
|
||||
function(list_licenses OUTPUT MODULES)
|
||||
file(WRITE ${OUTPUT} "R\"FILAMENT__(\n")
|
||||
set(STR_OPENER "R\"FILAMENT__(")
|
||||
set(STR_CLOSER ")FILAMENT__\"")
|
||||
set(CONTENT)
|
||||
set(_MODULES ${MODULES} ${ARGN})
|
||||
foreach(module ${_MODULES})
|
||||
set(license_path "../../third_party/${module}/LICENSE")
|
||||
get_filename_component(fullname "${license_path}" ABSOLUTE)
|
||||
file(APPEND ${OUTPUT} "License and copyrights for ${module}:\n\n")
|
||||
file(READ ${license_path} license)
|
||||
file(APPEND ${OUTPUT} ${license})
|
||||
file(APPEND ${OUTPUT} "\n\n")
|
||||
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
|
||||
file(READ ${license_path} license_long)
|
||||
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
|
||||
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
|
||||
string(APPEND CONTENT "\n\n")
|
||||
endforeach()
|
||||
file(APPEND ${OUTPUT} ")FILAMENT__\"\n")
|
||||
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
|
||||
endfunction(list_licenses)
|
||||
|
||||
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/linux/combine-static-libs.sh")
|
||||
if (WIN32)
|
||||
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/windows/combine-static-libs.bat")
|
||||
set(CMAKE_AR "lib.exe")
|
||||
endif()
|
||||
|
||||
# Add a custom command to TARGET that combines the static libraries in DEPS into a single archive.
|
||||
function(combine_static_libs TARGET OUTPUT DEPS)
|
||||
# Loop through the dependent libraries and query their location on disk.
|
||||
set(DEPS_FILES )
|
||||
foreach(DEPENDENCY ${DEPS})
|
||||
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${TARGET} POST_BUILD
|
||||
COMMAND "${COMBINE_SCRIPT}" "${CMAKE_AR}" "${OUTPUT}" ${DEPS_FILES}
|
||||
COMMENT "Combining ${target} dependencies into single shared library"
|
||||
VERBATIM
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# ==================================================================================================
|
||||
# Configuration for CMAKE_CROSSCOMPILING.
|
||||
# ==================================================================================================
|
||||
@@ -404,6 +483,7 @@ endfunction()
|
||||
|
||||
# Common to all platforms
|
||||
add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/camutils)
|
||||
add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
@@ -413,17 +493,19 @@ add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/rays)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/mathio)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
add_subdirectory(${FILAMENT}/filament)
|
||||
add_subdirectory(${FILAMENT}/shaders)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/robin-map/tnt)
|
||||
add_subdirectory(${EXTERNAL}/smol-v/tnt)
|
||||
add_subdirectory(${EXTERNAL}/benchmark/tnt)
|
||||
add_subdirectory(${EXTERNAL}/meshoptimizer)
|
||||
add_subdirectory(${EXTERNAL}/cgltf/tnt)
|
||||
add_subdirectory(${EXTERNAL}/draco/tnt)
|
||||
add_subdirectory(${EXTERNAL}/xatlas/tnt)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
|
||||
if (FILAMENT_BUILD_FILAMAT)
|
||||
# spirv-tools must come before filamat, as filamat relies on the presence of the
|
||||
@@ -443,13 +525,13 @@ if (APPLE)
|
||||
add_subdirectory(${EXTERNAL}/moltenvk/tnt)
|
||||
endif()
|
||||
|
||||
set (FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
|
||||
set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
|
||||
|
||||
if (WEBGL)
|
||||
add_subdirectory(web/filament-js)
|
||||
add_subdirectory(web/samples)
|
||||
|
||||
if (GENERATE_JS_DOCS)
|
||||
if (FILAMENT_GENERATE_JS_DOCS)
|
||||
add_subdirectory(web/docs)
|
||||
endif()
|
||||
|
||||
@@ -464,11 +546,12 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
|
||||
add_subdirectory(${FILAMENT}/java/filamat)
|
||||
add_subdirectory(${FILAMENT}/java/filament)
|
||||
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libassimp/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libpng/tnt)
|
||||
@@ -476,6 +559,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${EXTERNAL}/libz/tnt)
|
||||
add_subdirectory(${EXTERNAL}/skylight/tnt)
|
||||
add_subdirectory(${EXTERNAL}/tinyexr/tnt)
|
||||
|
||||
add_subdirectory(${TOOLS}/cmgen)
|
||||
add_subdirectory(${TOOLS}/filamesh)
|
||||
add_subdirectory(${TOOLS}/glslminifier)
|
||||
@@ -487,10 +571,11 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${TOOLS}/roughness-prefilter)
|
||||
add_subdirectory(${TOOLS}/skygen)
|
||||
add_subdirectory(${TOOLS}/specular-color)
|
||||
endif()
|
||||
|
||||
if (DENOISE_LIBRARY)
|
||||
add_subdirectory(${EXTERNAL}/OpenImageDenoise/tnt)
|
||||
if (DENOISE_LIBRARY)
|
||||
add_subdirectory(${EXTERNAL}/OpenImageDenoise/tnt)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
|
||||
|
||||
@@ -40,3 +40,18 @@ information on using pull requests.
|
||||
|
||||
This project follows
|
||||
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).
|
||||
|
||||
## Dependencies
|
||||
|
||||
One of our design goals is that Filament itself should have no dependencies or as few dependencies
|
||||
as possible. The current external dependencies of the runtime library include:
|
||||
|
||||
- STL
|
||||
- robin-map (header only library)
|
||||
|
||||
When building with Vulkan enabled, we have a few additional small dependencies:
|
||||
|
||||
- vkmemalloc
|
||||
- smol-v
|
||||
|
||||
Host tools (such as `matc` or `cmgen`) can use external dependencies freely.
|
||||
|
||||
814
README.md
814
README.md
@@ -1,28 +1,61 @@
|
||||
# Filament
|
||||
|
||||
<img alt="Android" src="build/img/android.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_android.html)
|
||||
<img alt="iOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_ios.html)
|
||||
<img alt="Linux" src="build/img/linux.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_linux.html)
|
||||
<img alt="macOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_mac.html)
|
||||
<img alt="Windows" src="build/img/windows.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_windows.html)
|
||||
<img alt="Web" src="build/img/web.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_web.html)
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows,
|
||||
and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||
|
||||
Filament is currently used in the
|
||||
[Sceneform](https://developers.google.com/ar/develop/java/sceneform/) library both at runtime on
|
||||
Android devices and as the renderer inside the Android Studio plugin.
|
||||
|
||||
## Download
|
||||
|
||||
[Download Filament releases](https://github.com/google/filament/releases) to access stable builds.
|
||||
Filament release archives contains host-side tools that are required to generate assets.
|
||||
|
||||
Make sure you always use tools from the same release as the runtime library. This is particularly
|
||||
important for `matc` (material compiler).
|
||||
|
||||
If you prefer to live on the edge, you can download a continuous build by clicking one of the build
|
||||
badges above.
|
||||
If you'd rather build Filament yourself, please refer to our [build manual](BUILDING.md).
|
||||
|
||||
### Android
|
||||
|
||||
Android projects can simply declare Filament libraries as Maven dependencies:
|
||||
|
||||
```gradle
|
||||
repositories {
|
||||
// ...
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.5.0'
|
||||
}
|
||||
```
|
||||
|
||||
Here are all the libraries available in the group `com.google.android.filament`:
|
||||
|
||||
- `filament-android`: the Filament rendering engine itself
|
||||
- `gltfio-android`: a glTF 2.0 loader for Filament, depends on `filament-android`
|
||||
- `gltfio-android-lite`: trimmed version of `gltfio` that does not support some glTF features
|
||||
- `filament-utils-android`: KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`
|
||||
- `filament-utils-lite-android`: trimmed version of `filament-utils` that does not support some glTF features
|
||||
- `filamat-android`: a runtime material builder/compiler. This library is large but contains
|
||||
a full shader compiler/validator/optimizer
|
||||
- `filamat-android-lite`: a much smaller alternative to `filamat-android` that can only
|
||||
generate OpenGL shaders. It does not provide validation or optimizations
|
||||
|
||||
### Snapshots
|
||||
|
||||
If you prefer to live on the edge, you can download a continuous build by following the following
|
||||
steps:
|
||||
|
||||
1. Find the [commit](https://github.com/google/filament/commits/master) you're interested in.
|
||||
2. Click the green check mark under the commit message.
|
||||
3. Click on the _Details_ link for the platform you're interested in.
|
||||
4. On the top right, click on the _Artifacts_ dropdown and choose an artifact.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -36,27 +69,29 @@ badges above.
|
||||
- [Material Properties](https://google.github.io/filament/Material%20Properties.pdf), a reference
|
||||
sheet for the standard material model.
|
||||
|
||||
## Samples
|
||||
## Examples
|
||||
|
||||
### Materials
|
||||
|
||||
Here are a few sample materials rendered with Filament:
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Applications
|
||||
|
||||
### Applications
|
||||
|
||||
Here are a few screenshots of applications that use Filament in production:
|
||||
|
||||
### Google Maps AR Navigation
|
||||
#### Google Maps AR Navigation
|
||||
|
||||

|
||||
|
||||
### Google Search 3D/AR Viewer on Android
|
||||
#### Google Search 3D/AR Viewer on Android
|
||||
|
||||

|
||||
|
||||
@@ -73,7 +108,7 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- OpenGL 4.1+ for Linux, macOS and Windows
|
||||
- OpenGL ES 3.0+ for Android and iOS
|
||||
- Metal for macOS and iOS
|
||||
- Vulkan 1.0 for Android, Linux, macOS and iOS (with MoltenVk), and Windows
|
||||
- Vulkan 1.0 for Android, Linux, macOS, and Windows
|
||||
- WebGL 2.0 for all platforms
|
||||
|
||||
### Rendering
|
||||
@@ -91,652 +126,18 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Image-based lighting
|
||||
- Physically-based camera (shutter speed, sensitivity and aperture)
|
||||
- Physical light units
|
||||
- Point light, spot light and directional light
|
||||
- SSAO
|
||||
- Point lights, spot lights and directional light
|
||||
- Spot and directional light shadows
|
||||
- Contact shadows
|
||||
- Screen-space ambient occlusion
|
||||
- Screen-space refraction
|
||||
- Global fog
|
||||
- HDR bloom
|
||||
- ACES-like tone-mapping
|
||||
- Temporal dithering
|
||||
- FXAA, MSAA and specular anti-aliasing
|
||||
- Dynamic resolution (on Android and iOS)
|
||||
|
||||
### Future
|
||||
|
||||
Many other features have been either prototyped or planned:
|
||||
|
||||
- IES light profiles/cookies
|
||||
- Area lights
|
||||
- Fog
|
||||
- Color grading
|
||||
- Bloom
|
||||
- TAA
|
||||
- etc.
|
||||
|
||||
## Directory structure
|
||||
|
||||
This repository not only contains the core Filament engine, but also its supporting libraries
|
||||
and tools.
|
||||
|
||||
- `android`: Android libraries and projects
|
||||
- `build`: Custom Gradle tasks for Android builds
|
||||
- `filamat-android`: Filament material generation library (AAR) for Android
|
||||
- `filament-android`: Filament library (AAR) for Android
|
||||
- `samples`: Android-specific Filament samples
|
||||
- `art`: Source for various artworks (logos, PDF manuals, etc.)
|
||||
- `assets`: 3D assets to use with sample applications
|
||||
- `build`: CMake build scripts
|
||||
- `docs`: Documentation
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament rendering engine (minimal dependencies)
|
||||
- `ide`: Configuration files for IDEs (CLion, etc.)
|
||||
- `ios`: Sample projects for iOS
|
||||
- `java`: Java bindings for Filament libraries
|
||||
- `libs`: Libraries
|
||||
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
|
||||
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
|
||||
- `filabridge`: Library shared by the Filament engine and host tools
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
|
||||
- `geometry`: Mesh-related utilities
|
||||
- `gltfio`: Loader and optional pipeline for glTF 2.0
|
||||
- `ibl`: IBL generation tools
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `math`: Math library
|
||||
- `rays`: Simple path tracer used for baking ambient occlusion, etc.
|
||||
- `utils`: Utility library (threads, memory, data structures, etc.)
|
||||
- `samples`: Sample desktop applications
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
|
||||
- `models`: Models under permissive licenses
|
||||
- `textures`: Textures under CC0 license
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
- `filamesh`: Mesh converter
|
||||
- `glslminifier`: Minifies GLSL source code
|
||||
- `matc`: Material compiler
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image
|
||||
- `normal-blending`: Tool to blend normal maps
|
||||
- `resgen` Aggregates binary blobs into embeddable resources
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`: Physically-based sky environment texture generator
|
||||
- `specular-color`: Computes the specular color of conductors based on spectral data
|
||||
- `web`: JavaScript bindings, documentation, and samples
|
||||
|
||||
## Building Filament
|
||||
|
||||
### Prerequisites
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (or more recent)
|
||||
- clang 7.0 (or more recent)
|
||||
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
To build the Java based components of the project you can optionally install (recommended):
|
||||
|
||||
- OpenJDK 1.8 (or more recent)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
section below.
|
||||
|
||||
Building the `rays` library (used for light baking) is optional and requires the following packages:
|
||||
|
||||
- embree 3.0+
|
||||
- libtbb-dev
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.5
|
||||
- Android SDK
|
||||
- Android NDK 19 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
Make sure the environment variable `ANDROID_HOME` points to the location of your Android SDK.
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. To do so, the environment
|
||||
variable `JAVA_HOME` should point to the location of your JDK.
|
||||
|
||||
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
|
||||
|
||||
### IDE
|
||||
|
||||
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
||||
in CLion to obtain a usable project.
|
||||
|
||||
### Easy build
|
||||
|
||||
Once the required OS specific dependencies listed below are installed, you can use the script
|
||||
located in `build.sh` to build Filament easily on macOS and Linux.
|
||||
|
||||
This script can be invoked from anywhere and will produce build artifacts in the `out/` directory
|
||||
inside the Filament source tree.
|
||||
|
||||
To trigger an incremental debug build:
|
||||
|
||||
```
|
||||
$ ./build.sh debug
|
||||
```
|
||||
|
||||
To trigger an incremental release build:
|
||||
|
||||
```
|
||||
$ ./build.sh release
|
||||
```
|
||||
|
||||
To trigger both incremental debug and release builds:
|
||||
|
||||
```
|
||||
$ ./build.sh debug release
|
||||
```
|
||||
|
||||
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
|
||||
You can force a clean build by adding the `-c` flag. The script offers more features described
|
||||
by executing `build.sh -h`.
|
||||
|
||||
### Disabling Java builds
|
||||
|
||||
By default our build system will attempt to compile the Java bindings. If you wish to skip this
|
||||
compilation step simply pass the `-j` flag to `build.sh`:
|
||||
|
||||
```
|
||||
$ ./build.sh -j release
|
||||
```
|
||||
|
||||
If you use CMake directly instead of the build script, pass `-DENABLE_JAVA=OFF` to CMake instead.
|
||||
|
||||
### Linux
|
||||
|
||||
Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7` or higher
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
If you'd like to run `cmake` directly rather than using the build script, it can be invoked as
|
||||
follows, with some caveats that are explained further down.
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
Your Linux distribution might default to `gcc` instead of `clang`, if that's the case invoke
|
||||
`cmake` with the following command:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-7
|
||||
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
You can also export the `CC` and `CXX` environment variables to always point to `clang`. Another
|
||||
solution is to use `update-alternatives` to both change the default compiler, and point to a
|
||||
specific version of clang:
|
||||
|
||||
```
|
||||
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
|
||||
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
|
||||
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```
|
||||
|
||||
Finally, invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja
|
||||
```
|
||||
|
||||
This will build Filament, its tests and samples, and various host tools.
|
||||
|
||||
### macOS
|
||||
|
||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||
make sure the command line tools are setup by running:
|
||||
|
||||
```
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
After installing Java 1.8 you must also ensure that your `JAVA_HOME` environment variable is
|
||||
properly set. If it doesn't already point to the appropriate JDK, you can simply add the following
|
||||
to your `.profile`:
|
||||
|
||||
```
|
||||
export JAVA_HOME="$(/usr/libexec/java_home)"
|
||||
```
|
||||
|
||||
Then run `cmake` and `ninja` to trigger a build:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
$ ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
The following instructions have been tested on a machine running Windows 10. They should take you
|
||||
from a machine with only the operating system to a machine able to build and run Filament.
|
||||
|
||||
Google employees require additional steps which can be found here [go/filawin](http://go/filawin).
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
|
||||
- [Clang 7](http://releases.llvm.org/download.html)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [Cmake 3.13 or later](https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi)
|
||||
|
||||
If you're using Visual Studio 2017, you'll also need to install the [LLVM Compiler
|
||||
Toolchain](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain)
|
||||
extension.
|
||||
|
||||
Open an appropriate Native Tools terminal for the version of Visual Studio you are using:
|
||||
- VS 2015: VS2015 x64 Native Tools Command Prompt
|
||||
- VS 2017: x64 Native Tools Command Prompt for VS 2017
|
||||
|
||||
You can find these by clicking the start button and typing "x64 native tools".
|
||||
|
||||
Create a working directory:
|
||||
```
|
||||
> mkdir out/cmake-release
|
||||
> cd out/cmake-release
|
||||
```
|
||||
|
||||
Create the msBuild project:
|
||||
```
|
||||
# Visual Studio 2015:
|
||||
> cmake -T"LLVM-vs2014" -G "Visual Studio 14 2015 Win64" ../..
|
||||
|
||||
# Visual Studio 2017
|
||||
> cmake ..\.. -T"LLVM" -G "Visual Studio 15 2017 Win64" ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe"
|
||||
```
|
||||
|
||||
Check out the output and make sure Clang for Windows frontend was found. You should see a line
|
||||
showing the following output. Note that for Visual Studio 2017 this line may list Microsoft's
|
||||
compiler, but the build will still in fact use Clang and you can proceed.
|
||||
|
||||
```
|
||||
Clang:C:/Program Files/LLVM/msbuild-bin/cl.exe
|
||||
```
|
||||
|
||||
You are now ready to build:
|
||||
```
|
||||
> msbuild TNT.sln /t:material_sandbox /m /p:configuration=Release
|
||||
```
|
||||
|
||||
Run it:
|
||||
```
|
||||
> samples\Release\material_sandbox.exe ..\..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
#### Tips
|
||||
|
||||
- To troubleshoot an issue, use verbose mode via `/v:d` flag.
|
||||
- To build a specific project, use `/t:NAME` flag (e.g: `/t:material_sandbox`).
|
||||
- To build using more than one core, use parallel build flag: `/m`.
|
||||
- To build a specific profile, use `/p:configuration=` (e.g: `/p:configuration=Debug`,
|
||||
`/p:configuration=Release`, and `/p:configuration=RelWithDebInfo`).
|
||||
- The msBuild project is what is used by Visual Studio behind the scene to build. Building from VS
|
||||
or from the command-line is the same thing.
|
||||
|
||||
#### Building with Ninja on Windows
|
||||
|
||||
Alternatively, you can use [Ninja](https://ninja-build.org/) to build for Windows. An MSVC
|
||||
installation is still necessary.
|
||||
|
||||
First, install the dependencies listed under [Windows](#Windows) as well as Ninja. Then open up a
|
||||
Native Tools terminal as before. Create a build directory inside Filament and run the
|
||||
following CMake command:
|
||||
|
||||
```
|
||||
> cmake .. -G Ninja ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
```
|
||||
|
||||
You should then be able to build by invoking Ninja:
|
||||
|
||||
```
|
||||
> ninja
|
||||
```
|
||||
|
||||
#### Development tips
|
||||
|
||||
- Before shipping a binary, make sure you used Release profile and make sure you have no libc/libc++
|
||||
dependencies with [Dependency Walker](http://www.dependencywalker.com).
|
||||
- Application Verifier and gflags.exe can be of great help to trackdown heap corruption. Application
|
||||
Verifier is easy to setup with a GUI. For gflags, use: `gflags /p /enable pheap-buggy.exe`.
|
||||
|
||||
#### Running a simple test
|
||||
|
||||
To confirm Filament was properly built, run the following command from the build directory:
|
||||
|
||||
```
|
||||
> samples\material_sandbox.exe --ibl=..\..\samples\envs\pillars ..\..\assets\models\sphere\sphere.obj
|
||||
```
|
||||
|
||||
### Android
|
||||
|
||||
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
||||
host tools are required to successfully build for Android.
|
||||
|
||||
Filament can be built for the following architectures:
|
||||
|
||||
- ARM 64-bit (`arm64-v8a`)
|
||||
- ARM 32-bit (`armeabi-v7a`)
|
||||
- Intel 64-bit (`x86_64`)
|
||||
- Intel 32-bit (`x86`)
|
||||
|
||||
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
|
||||
foremost for `arm64-v8a`.
|
||||
|
||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||
|
||||
#### Easy Android build
|
||||
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
`-p android` flag. For instance to build the release target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p android release
|
||||
```
|
||||
|
||||
Run `build.sh -h` for more information.
|
||||
|
||||
#### ARM 64-bit target (arm64-v8a)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-aarch64
|
||||
$ cd out/android-build-release-aarch64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||
|
||||
#### ARM 32-bit target (armeabi-v7a)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-arm
|
||||
$ cd out/android-build-release-arm
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-arm7-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/armeabi-v7a`.
|
||||
|
||||
#### Intel 64-bit target (x86_64)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-x86_64
|
||||
$ cd out/android-build-release-x86_64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../filament/build/toolchain-x86_64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../out/android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/x86_64`.
|
||||
|
||||
#### Intel 32-bit target (x86)
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-x86
|
||||
$ cd out/android-build-release-x86
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../filament/build/toolchain-x86-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../out/android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||
binaries should be found in `out/android-release/filament/lib/x86`.
|
||||
|
||||
### AAR
|
||||
|
||||
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
||||
as explained in the sections above. You must have the following ABIs built in
|
||||
`out/android-release/filament/lib/`:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To build Filament's AAR simply open the Android Studio project in `android/filament-android`. The
|
||||
AAR is a universal AAR that contains all supported build targets:
|
||||
|
||||
- `arm64-v8a`
|
||||
- `armeabi-v7a`
|
||||
- `x86_64`
|
||||
- `x86`
|
||||
|
||||
To filter out unneeded ABIs, rely on the `abiFilters` of the project that links against Filament's
|
||||
AAR.
|
||||
|
||||
Alternatively you can build the AAR from the command line by executing the following the
|
||||
`android/filament-android` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
|
||||
the CMake install prefix used in the previous steps).
|
||||
|
||||
### Using Filament's AAR
|
||||
|
||||
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
||||
sure to add the newly created module as a dependency to your application.
|
||||
|
||||
If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
|
||||
your Gradle build file. For example:
|
||||
|
||||
```
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
arm7 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
x86_64 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86_64'
|
||||
}
|
||||
}
|
||||
x86 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86'
|
||||
}
|
||||
}
|
||||
universal {
|
||||
dimension 'cpuArch'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WebAssembly
|
||||
|
||||
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
||||
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
||||
[linux](#linux)), which will ensure you have the proper dependencies installed.
|
||||
|
||||
Next, you need to install the Emscripten SDK. The following instructions show how to install the
|
||||
same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/a77638d.zip > emsdk.zip
|
||||
unzip emsdk.zip
|
||||
mv emsdk-* emsdk
|
||||
cd emsdk
|
||||
./emsdk update
|
||||
./emsdk install sdk-1.38.28-64bit
|
||||
./emsdk activate sdk-1.38.28-64bit
|
||||
```
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```
|
||||
export EMSDK=<your chosen home for the emscripten SDK>
|
||||
./build.sh -p webgl release
|
||||
```
|
||||
|
||||
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
|
||||
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
|
||||
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
|
||||
use Python to create a quick localhost server:
|
||||
|
||||
```
|
||||
cd out/cmake-webgl-release/web/samples
|
||||
python3 -m http.server # Python 3
|
||||
python -m SimpleHTTPServer # Python 2.7
|
||||
```
|
||||
|
||||
You can then open http://localhost:8000/suzanne.html in your web browser.
|
||||
|
||||
Alternatively, if you have node installed you can use the
|
||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||
web page when it detects a change.
|
||||
|
||||
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||
such as meshes, textures, and materials.
|
||||
|
||||
## Running the native samples
|
||||
|
||||
The `samples/` directory contains several examples of how to use Filament with SDL2.
|
||||
|
||||
Some of the samples accept FBX/OBJ meshes while others rely on the `filamesh` file format. To
|
||||
generate a `filamesh ` file from an FBX/OBJ asset, run the `filamesh` tool
|
||||
(`./tools/filamesh/filamesh` in your build directory):
|
||||
|
||||
```
|
||||
filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
|
||||
```
|
||||
|
||||
Most samples accept an IBL that must be generated using the `cmgen` tool (`./tools/filamesh/cmgen`
|
||||
in your build directory). These sample apps expect a path to a directory containing the '.rgb32f'
|
||||
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data). To generate an IBL simply use
|
||||
this command:
|
||||
|
||||
```
|
||||
cmgen -x ./ibls/ my_ibl.exr
|
||||
```
|
||||
|
||||
The source environment map can be a PNG (8 or 16 bit), a PSD (16 or 32 bit), an HDR or an OpenEXR
|
||||
file. The environment map can be an equirectangular projection, a horizontal cross, a vertical
|
||||
cross, or a list of cubemap faces (horizontal or vertical).
|
||||
|
||||
`cmgen` will automatically create a directory based on the name of the source environment map. In
|
||||
the example above, the final directory will be `./ibls/my_ibl/`. This directory should contain the
|
||||
pre-filtered environment map (one file per cubemap face and per mip level), the environment map
|
||||
texture for the skybox and a text file containing the spherical harmonics for indirect diffuse
|
||||
lighting.
|
||||
|
||||
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.1`. The numerical
|
||||
value is the desired roughness between 0 and 1.
|
||||
|
||||
## Rendering with Filament
|
||||
|
||||
### Native Linux, macOS and Windows
|
||||
@@ -839,44 +240,73 @@ Filament on iOS is largely the same as native rendering with C++. A `CAEAGLLayer
|
||||
is passed to the `createSwapChain` method. Filament for iOS supports both OpenGL ES and Vulkan via
|
||||
MoltenVK.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
$ doxygen docs/doxygen/filament.doxygen
|
||||
```
|
||||
|
||||
Finally simply open `docs/html/index.html` in your web browser.
|
||||
|
||||
## Assets
|
||||
|
||||
To get started you can use the textures and environment maps found respectively in
|
||||
`third_party/textures` and `third_party/environments`. These assets are under CC0 license. Please
|
||||
refer to their respective `URL.txt` files to know more about the original authors.
|
||||
|
||||
## Dependencies
|
||||
|
||||
One of our design goals is that Filament itself should have no dependencies or as few dependencies
|
||||
as possible. The current external dependencies of the runtime library include:
|
||||
|
||||
- STL
|
||||
- robin-map (header only library)
|
||||
|
||||
When building with Vulkan enabled, we have a few additional small dependencies:
|
||||
|
||||
- vkmemalloc
|
||||
- smol-v
|
||||
|
||||
Host tools (such as `matc` or `cmgen`) can use external dependencies freely.
|
||||
|
||||
## How to make contributions
|
||||
|
||||
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
|
||||
familiar with the [code style](/CODE_STYLE.md).
|
||||
|
||||
## Directory structure
|
||||
|
||||
This repository not only contains the core Filament engine, but also its supporting libraries
|
||||
and tools.
|
||||
|
||||
- `android`: Android libraries and projects
|
||||
- `filamat-android`: Filament material generation library (AAR) for Android
|
||||
- `filament-android`: Filament library (AAR) for Android
|
||||
- `gltfio-android`: Filament glTF loading library (AAR) for Android
|
||||
- `samples`: Android-specific Filament samples
|
||||
- `art`: Source for various artworks (logos, PDF manuals, etc.)
|
||||
- `assets`: 3D assets to use with sample applications
|
||||
- `build`: CMake build scripts
|
||||
- `docs`: Documentation
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament rendering engine (minimal dependencies)
|
||||
- `ide`: Configuration files for IDEs (CLion, etc.)
|
||||
- `ios`: Sample projects for iOS
|
||||
- `java`: Java bindings for Filament libraries
|
||||
- `libs`: Libraries
|
||||
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
|
||||
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
|
||||
- `filabridge`: Library shared by the Filament engine and host tools
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
|
||||
- `geometry`: Mesh-related utilities
|
||||
- `gltfio`: Loader and optional pipeline for glTF 2.0
|
||||
- `ibl`: IBL generation tools
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `matdbg`: DebugServer for inspecting shaders at run-time (debug builds only)
|
||||
- `math`: Math library
|
||||
- `rays`: Simple path tracer used for baking ambient occlusion, etc.
|
||||
- `utils`: Utility library (threads, memory, data structures, etc.)
|
||||
- `samples`: Sample desktop applications
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
|
||||
- `models`: Models under permissive licenses
|
||||
- `textures`: Textures under CC0 license
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
- `filamesh`: Mesh converter
|
||||
- `glslminifier`: Minifies GLSL source code
|
||||
- `matc`: Material compiler
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image
|
||||
- `normal-blending`: Tool to blend normal maps
|
||||
- `resgen` Aggregates binary blobs into embeddable resources
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`: Physically-based sky environment texture generator
|
||||
- `specular-color`: Computes the specular color of conductors based on spectral data
|
||||
- `web`: JavaScript bindings, documentation, and samples
|
||||
|
||||
## License
|
||||
|
||||
Please see [LICENSE](/LICENSE).
|
||||
|
||||
126
RELEASE_NOTES.md
126
RELEASE_NOTES.md
@@ -3,8 +3,132 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
- Added a live material debugger with a web-based interface.
|
||||
## Next release
|
||||
|
||||
## v1.5.0
|
||||
|
||||
⚠️ This release breaks compiled materials, use matc to recompile.
|
||||
|
||||
- The Android support libraries (gltfio and filament-utils) now use dynamic linking.
|
||||
- Removed depth-prepass related APIs. (⚠ API Change)
|
||||
- gltfio: add asynchronous API to ResourceLoader.
|
||||
- gltfio: generate normals for flat-shaded models that do not have normals.
|
||||
- Material instances now allow dynamic depth testing and other rasterization state.
|
||||
- Unlit materials now apply emissive in the same way as lit materials.
|
||||
- Screen-space refraction is now supported.
|
||||
- Support for HDR Bloom as a post-process effect.
|
||||
- Alpha masked objects are now part of the SSAO pass.
|
||||
- Added Java bindings for geometry::SurfaceOrientation.
|
||||
- Fixed bug rendering transparent objects with Metal backend.
|
||||
- Fixed crash on macOS Catalina when rendering with Metal backend.
|
||||
- Fixed bug in Camera::setLensProjection() and added the aspect ratio parameter. (⚠ API Change)
|
||||
- WebGL: Improved TypeScript annotations.
|
||||
- WebGL: Simplified callback API for glTF. (⚠ API Change)
|
||||
- gltfio: Removed deprecated "Bindings" API. (⚠ API Change)
|
||||
- gltfio: Added support for Draco.
|
||||
- gltfio: Reduced the size of the library.
|
||||
- Improved performance of SSAO.
|
||||
- Added support for screen-space contact shadows.
|
||||
- Added support for global fog.
|
||||
- Added support for bent normal maps and specular occlusion from bent normal maps.
|
||||
- Added support for shadow-casting spot lights.
|
||||
|
||||
## v1.4.5
|
||||
|
||||
- The depth prepass setting in View is now ignored and deprecated.
|
||||
- Fixed a threading bug with the NOOP backend.
|
||||
- Improved memory management for gltfio on Android.
|
||||
- Introduced `filament-utils` library with `TextureLoader`, `ModelViewer`, and Java bindings for `camutils`.
|
||||
- Fix out-of-bounds bug when glTF has many UV sets.
|
||||
- Added new `setMediaOverlay` API to `UiHelper` for controlling surface ordering.
|
||||
- Implemented sRGB support for DXT encoded textures.
|
||||
- Fix bug with incorrect world transforms computed in `TransformManager`.
|
||||
- gltfio: support external resources on Android.
|
||||
|
||||
|
||||
## v1.4.4
|
||||
|
||||
- Added support for solid and thin layer cubemap and screen-space refraction.
|
||||
- Improved high roughness material rendering by default when regenerating environments maps.
|
||||
- Fix bad instruction exception with macOS Catalina.
|
||||
- Fixed bad state after removing an IBL from the Scene.
|
||||
- Fixed incorrect punctual light binning (affected Metal and Vulkan backends).
|
||||
- Fixed crash when using a Metal headless SwapChain with an Intel integrated GPU.
|
||||
- Added support for ASTC textures on iOS with Metal backend.
|
||||
- Added new heightfield sample.
|
||||
- Removed `<iostream>` from math headers.
|
||||
- cmgen now places KTX files directly in the specified deployment folder.
|
||||
|
||||
## v1.4.3
|
||||
|
||||
- Fixed an assertion when a parameter array occurs last in a material definition.
|
||||
- Fixed morph shapes not rendering in WebGL.
|
||||
- Added support for the latest version of emscripten.
|
||||
- gltfio: fixed blackness seen with default material.
|
||||
- Added ETC2 and BC compressed texture support to Metal backend.
|
||||
- Rendering a `SAMPLER_EXTERNAL` texture before setting an external image no longer results in GPU errors.
|
||||
- Fixed a normals issue when skinning without a normal map or anisotropy.
|
||||
- Fixed an issue where transparent views couldn't be used with post-processing.
|
||||
- Always use higher quality 3-bands SH for indirect lighting, even on mobile.
|
||||
- The Metal backend can now handle binding individual planes of YUV external images.
|
||||
- Added support for depth buffer when post-processing is turned off
|
||||
- Improved performance on GPUs that use tile-based rendering
|
||||
|
||||
## v1.4.2
|
||||
|
||||
- Cleaned up the validation strategy in Engine (checks for use-after-destroy etc).
|
||||
- OpenGL: Fixed ES 3.0 support on iOS.
|
||||
- OpenGL: Added support for KHR_debug in debug builds.
|
||||
- gltfio: Added Java / Kotlin bindings for Animator.
|
||||
- gltfio: Fixed panic with the Android gltf-bloom demo.
|
||||
- gltfio: Java clients should no longer call Filament#init.
|
||||
- Improved IBL diffuse by allowing to use the specular cubemap at `roughness` = 1 instead of Spherical Harmonics
|
||||
|
||||
## v1.4.1
|
||||
|
||||
- Added missing API documentation.
|
||||
- Fixed crash for sandboxed macOS apps using Filament.
|
||||
- Fixed an issue that limited the camera near plane to ~1mm.
|
||||
- Added Android sample for Camera Stream.
|
||||
- Fixed an Xcode assertion when rendering skinned meshes using the Metal backend.
|
||||
- Added support for Core Animation / Metal frame synchronization with Metal backend.
|
||||
- Fixed an issue with culling in `MaterialInstance`.
|
||||
- Fix additional compatibility issues with MSVC, including the Vulkan backend.
|
||||
- matdbg: fixed missing symbol issue when linking against debug builds.
|
||||
- filamat: fixed crash when using the "lite" version of the library.
|
||||
- matinfo: Fix a crash with on Windows.
|
||||
- gltfio: fixed an animation loop bug.
|
||||
- gltfio: added support for sparse accessors.
|
||||
- Add JS binding to unary `Camera::setExposure`.
|
||||
|
||||
## v1.4.0
|
||||
|
||||
- API Breakage: Simplified public-facing Fence API.
|
||||
- Minimum API level on Android is now API 19 instead of API 21.
|
||||
- Filament can now be built with msvc 2019.
|
||||
- Added the ability to modify clip space coordinates in the vertex shader.
|
||||
- Added missing API documentation.
|
||||
- Improved existing API documentation.
|
||||
- Added `Camera::setExposure(float)` to directly control the camera's exposure.
|
||||
- Backface culling can now be toggled on material instances.
|
||||
- Face direction is now reversed when transforms have negative scale.
|
||||
- Dielectrics now behave properly under a white furnace (energy preserving and conserving).
|
||||
- Clear coat roughness now remains in the 0..1 (previously remapped to the 0..0.6 range).
|
||||
- gltfio: Fixed several limitations with ubershader mode.
|
||||
- gltfio: Fixed a transforms issue with non-uniform scale.
|
||||
- webgl: Fixed an issue with JPEG textures.
|
||||
- Windows: Fix link error in debug builds.
|
||||
- matdbg: Web server must now be enabled with an environment variable.
|
||||
- matdbg: Added support for editing GLSL and MSL code.
|
||||
|
||||
## v1.3.2
|
||||
|
||||
- Added optional web server for real-time inspection of shader code.
|
||||
- Added basic #include support in material files.
|
||||
- Fixed potential Metal memory leak.
|
||||
- Fixed intermittent memory overflow in wasm builds.
|
||||
- Fix bad normal mapping with skinning.
|
||||
- Java clients can now call getNativeObject().
|
||||
|
||||
## v1.3.1
|
||||
|
||||
|
||||
9
android/.gitignore
vendored
Normal file
9
android/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build/
|
||||
@@ -25,7 +25,7 @@ cmake ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\release\filament ^
|
||||
-DENABLE_JAVA=NO ^
|
||||
-DFILAMENT_ENABLE_JAVA=NO ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
..\..
|
||||
```
|
||||
@@ -96,12 +96,12 @@ ninja install
|
||||
|
||||
## Generate AAR
|
||||
|
||||
The Gradle project used to generate the AAR is located at `<filament>\android\filament-android`.
|
||||
The Gradle project used to generate the AAR is located at `<filament>\android`.
|
||||
|
||||
```
|
||||
cd android\filament-android
|
||||
gradlew -Pfilament_dist_dir=..\..\out\android-release\filament assembleRelease
|
||||
copy build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
cd android
|
||||
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease
|
||||
copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
```
|
||||
|
||||
If you're only interested in building for a single ABI, you'll need to add an `abiFilters` override
|
||||
@@ -119,5 +119,5 @@ for more information.
|
||||
|
||||
`filament-android-release.aar` should now be present at `<filament>\out\filament-android-release.aar`.
|
||||
|
||||
See [Using Filament's AAR](../README.md#using-filaments-aar) for usage instructions.
|
||||
See [Using Filament's AAR](../README.md) for usage instructions.
|
||||
|
||||
|
||||
105
android/build.gradle
Normal file
105
android/build.gradle
Normal file
@@ -0,0 +1,105 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// filament_tools_dir
|
||||
// Path to the Filament distribution/install directory for desktop.
|
||||
// This directory must contain bin/matc.
|
||||
//
|
||||
// filament_supports_vulkan
|
||||
// When set, support for Vulkan will be enabled.
|
||||
//
|
||||
// filament_skip_samples
|
||||
// Exclude samples from the project. Useful to speed up compilation.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
def filamentPath = file("../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filamentPath = file(project.property("filament_dist_dir")).absolutePath
|
||||
}
|
||||
def hasVulkan = project.hasProperty("filament_supports_vulkan")
|
||||
|
||||
// Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
|
||||
// to increase their minSdkVersion unnecessarily. It is however up to them to
|
||||
// ensure they do not initialize Filament on API levels < 19.
|
||||
ext.versions = [
|
||||
'minSdk': 14,
|
||||
'targetSdk': 29,
|
||||
'compileSdk': 29,
|
||||
'kotlin': '1.3.61',
|
||||
'buildTools': '29.0.3',
|
||||
'ndk': '21.0.6113669'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
'androidx': [
|
||||
'annotations': "androidx.annotation:annotation:1.1.0",
|
||||
'core': "androidx.core:core:1.1.0",
|
||||
],
|
||||
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
ext.cmakeArgs = [
|
||||
"-DANDROID_PIE=ON",
|
||||
"-DANDROID_PLATFORM=21",
|
||||
"-DANDROID_STL=c++_static",
|
||||
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${hasVulkan ? 'ON' : 'OFF'}".toString()
|
||||
]
|
||||
|
||||
ext.cppFlags = [
|
||||
"-std=c++14",
|
||||
"-Wno-unused-command-line-argument",
|
||||
// Required to support API levels below 23
|
||||
"-Wl,--hash-style=both",
|
||||
"-fno-stack-protector",
|
||||
"-fno-exceptions",
|
||||
"-fno-unwind-tables",
|
||||
"-fno-asynchronous-unwind-tables",
|
||||
"-fno-rtti",
|
||||
"-ffast-math",
|
||||
"-ffp-contract=fast",
|
||||
"-fvisibility-inlines-hidden",
|
||||
"-fvisibility=hidden",
|
||||
"-fomit-frame-pointer",
|
||||
"-ffunction-sections",
|
||||
"-fdata-sections",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-Bsymbolic-functions",
|
||||
]
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
subprojects { project ->
|
||||
group = GROUP
|
||||
version = VERSION_NAME
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
gradle.taskGraph.whenReady {
|
||||
gradle.taskGraph.allTasks.each {
|
||||
it.onlyIf {
|
||||
!it.project.ext.has('isSample') || !project.hasProperty('filament_skip_samples')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_tools_dir
|
||||
// Path to the Filament distribution/install directory for desktop
|
||||
// (produced by make/ninja install). This directory must contain bin/matc
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
|
||||
|
||||
import java.nio.file.Paths
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.LogLevel;
|
||||
|
||||
def filamentToolsPath = file("../../../../out/release/filament")
|
||||
if (project.hasProperty("filament_tools_dir")) {
|
||||
filamentToolsPath = file("$filament_tools_dir")
|
||||
}
|
||||
|
||||
List<File> getBinaries(String name, File toolsPath) {
|
||||
def tool = ["/bin/${name}.exe", "/bin/${name}"]
|
||||
def toolFullPath = tool.collect { path -> Paths.get(toolsPath.absolutePath, path).toFile() }
|
||||
|
||||
// Ensure that at least one matc binary and Filament library is present
|
||||
if (!toolFullPath.any { path -> file(path).exists() }) {
|
||||
throw new StopActionException("No ${name} binary could be found in " + toolsPath +
|
||||
"/bin. Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
return toolFullPath
|
||||
}
|
||||
|
||||
ext.matcFullPath = getBinaries('matc', filamentToolsPath)
|
||||
ext.cmgenFullPath = getBinaries('cmgen', filamentToolsPath)
|
||||
ext.filameshFullPath = getBinaries('filamesh', filamentToolsPath)
|
||||
ext.resgenFullPath = getBinaries('resgen', filamentToolsPath)
|
||||
|
||||
class LogOutputStream extends ByteArrayOutputStream {
|
||||
private final Logger logger;
|
||||
private final LogLevel level;
|
||||
|
||||
public LogOutputStream(Logger logger, LogLevel level) {
|
||||
this.logger = logger;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public LogLevel getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
logger.log(level, toString());
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to compile material files using matc
|
||||
// This task handles incremental builds
|
||||
class MaterialCompiler extends DefaultTask {
|
||||
File matcPath
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputDirectory
|
||||
File inputDir
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
MaterialCompiler() {
|
||||
matcPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.matcFullPath[0] : project.ext.matcFullPath[1]
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*.filamat' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
if (outOfDate.file.directory) return
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Compiling material " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${matcPath}"
|
||||
args('-a', 'all', '-p', 'mobile', '-o', getOutputFile(file), file)
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamat')
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to process IBLs using cmgen
|
||||
// This task handles incremental builds
|
||||
class IblGenerator extends DefaultTask {
|
||||
File cmgenPath
|
||||
String cmgenArgs = null;
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
File inputFile
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
IblGenerator() {
|
||||
cmgenPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.cmgenFullPath[0] : project.ext.cmgenFullPath[1]
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Generating IBL " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${cmgenPath}"
|
||||
args('-x', outputDir, file)
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
if (!cmgenArgs) {
|
||||
cmgenArgs = '--format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
|
||||
}
|
||||
cmgenArgs = cmgenArgs + " " + file
|
||||
errorOutput err
|
||||
executable "${cmgenPath}"
|
||||
args(cmgenArgs.split())
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.') - 1])
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to compile mesh files using filamesh
|
||||
// This task handles incremental builds
|
||||
class MeshCompiler extends DefaultTask {
|
||||
File filameshPath
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
File inputFile
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
MeshCompiler() {
|
||||
filameshPath = OperatingSystem.current().isWindows() ?
|
||||
project.ext.filameshFullPath[0] : project.ext.filameshFullPath[1]
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*.filamesh' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Compiling mesh " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${filameshPath}"
|
||||
args(file, getOutputFile(file))
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamesh')
|
||||
}
|
||||
}
|
||||
|
||||
task compileMaterials(type: MaterialCompiler)
|
||||
|
||||
task generateIbl(type: IblGenerator)
|
||||
|
||||
task compileMesh(type: MeshCompiler)
|
||||
9
android/buildSrc/.gitignore
vendored
Normal file
9
android/buildSrc/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build/
|
||||
291
android/buildSrc/src/main/groovy/FilamentPlugin.groovy
Normal file
291
android/buildSrc/src/main/groovy/FilamentPlugin.groovy
Normal file
@@ -0,0 +1,291 @@
|
||||
// This plugin accepts the following parameters:
|
||||
//
|
||||
// filament_tools_dir
|
||||
// Path to the Filament distribution/install directory for desktop.
|
||||
// This directory must contain bin/matc.
|
||||
//
|
||||
// filament_supports_vulkan
|
||||
// When set, support for Vulkan will be enabled
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
|
||||
|
||||
import java.nio.file.Paths
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.api.*
|
||||
import org.gradle.api.logging.*
|
||||
import org.gradle.api.tasks.*
|
||||
import org.gradle.api.tasks.incremental.*
|
||||
|
||||
class TaskWithBinary extends DefaultTask {
|
||||
private final String binaryName
|
||||
private File binaryPath = null
|
||||
|
||||
TaskWithBinary(String name) {
|
||||
binaryName = name
|
||||
}
|
||||
|
||||
String getBinaryName() {
|
||||
return binaryName
|
||||
}
|
||||
|
||||
File getBinary() {
|
||||
if (binaryPath == null) {
|
||||
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
|
||||
def fullPath = tool.collect { path ->
|
||||
Paths.get(project.ext.filamentToolsPath.absolutePath, path).toFile()
|
||||
}
|
||||
|
||||
binaryPath = OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]
|
||||
}
|
||||
return binaryPath
|
||||
}
|
||||
}
|
||||
|
||||
class LogOutputStream extends ByteArrayOutputStream {
|
||||
private final Logger logger
|
||||
private final LogLevel level
|
||||
|
||||
LogOutputStream(Logger logger, LogLevel level) {
|
||||
this.logger = logger
|
||||
this.level = level
|
||||
}
|
||||
|
||||
Logger getLogger() {
|
||||
return logger
|
||||
}
|
||||
|
||||
LogLevel getLevel() {
|
||||
return level
|
||||
}
|
||||
|
||||
@Override
|
||||
void flush() {
|
||||
logger.log(level, toString())
|
||||
reset()
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to compile material files using matc
|
||||
// This task handles incremental builds
|
||||
class MaterialCompiler extends TaskWithBinary {
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputDirectory
|
||||
File inputDir
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
MaterialCompiler() {
|
||||
super("matc")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*.filamat' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
if (outOfDate.file.directory) return
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Compiling material " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
def matcArgs = []
|
||||
if (project.hasProperty("filament_supports_vulkan")) {
|
||||
matcArgs += ['-a', 'vulkan']
|
||||
}
|
||||
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
args matcArgs
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamat')
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to process IBLs using cmgen
|
||||
// This task handles incremental builds
|
||||
class IblGenerator extends TaskWithBinary {
|
||||
String cmgenArgs = null
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
File inputFile
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
IblGenerator() {
|
||||
super("cmgen")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Generating IBL " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
if (!cmgenArgs) {
|
||||
cmgenArgs = '-q -x ' + outputDir +
|
||||
' --format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
|
||||
}
|
||||
cmgenArgs = cmgenArgs + " " + file
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
args(cmgenArgs.split())
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.') - 1])
|
||||
}
|
||||
}
|
||||
|
||||
// Custom task to compile mesh files using filamesh
|
||||
// This task handles incremental builds
|
||||
class MeshCompiler extends TaskWithBinary {
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@InputFile
|
||||
File inputFile
|
||||
|
||||
@OutputDirectory
|
||||
File outputDir
|
||||
|
||||
MeshCompiler() {
|
||||
super("filamesh")
|
||||
}
|
||||
|
||||
@SuppressWarnings("GroovyUnusedDeclaration")
|
||||
@TaskAction
|
||||
void execute(IncrementalTaskInputs inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir).matching { include '*.filamesh' })
|
||||
}
|
||||
|
||||
inputs.outOfDate { InputFileDetails outOfDate ->
|
||||
def file = outOfDate.file
|
||||
|
||||
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||
|
||||
def header = ("Compiling mesh " + file + "\n").getBytes()
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
args(file, getOutputFile(file))
|
||||
}
|
||||
}
|
||||
|
||||
inputs.removed { InputFileDetails removed ->
|
||||
getOutputFile(removed.file).delete()
|
||||
}
|
||||
}
|
||||
|
||||
File getOutputFile(final File file) {
|
||||
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamesh')
|
||||
}
|
||||
}
|
||||
|
||||
class FilamentToolsPluginExtension {
|
||||
File materialInputDir
|
||||
File materialOutputDir
|
||||
|
||||
String cmgenArgs
|
||||
File iblInputFile
|
||||
File iblOutputDir
|
||||
|
||||
File meshInputFile
|
||||
File meshOutputDir
|
||||
}
|
||||
|
||||
class FilamentToolsPlugin implements Plugin<Project> {
|
||||
void apply(Project project) {
|
||||
def extension = project.extensions.create('filamentTools', FilamentToolsPluginExtension)
|
||||
|
||||
project.ext.filamentToolsPath = project.file("../../../out/release/filament")
|
||||
if (project.hasProperty("filament_tools_dir")) {
|
||||
project.ext.filamentToolsPath = project.file(project.property("filament_tools_dir"))
|
||||
}
|
||||
|
||||
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
|
||||
enabled = extension.materialInputDir != null && extension.materialOutputDir != null
|
||||
inputDir = extension.materialInputDir
|
||||
outputDir = extension.materialOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMaterials"
|
||||
|
||||
project.tasks.register("filamentGenerateIbl", IblGenerator) {
|
||||
enabled = extension.iblInputFile != null && extension.iblOutputDir != null
|
||||
cmgenArgs = extension.cmgenArgs
|
||||
inputFile = extension.iblInputFile
|
||||
outputDir = extension.iblOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentGenerateIbl"
|
||||
|
||||
project.tasks.register("filamentCompileMesh", MeshCompiler) {
|
||||
enabled = extension.meshInputFile != null && extension.meshOutputDir != null
|
||||
inputFile = extension.meshInputFile
|
||||
outputDir = extension.meshOutputDir
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMesh"
|
||||
}
|
||||
}
|
||||
@@ -27,39 +27,6 @@ struct {
|
||||
jmethodID execute;
|
||||
} gCallbackUtils;
|
||||
|
||||
JniCallback* JniCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback) {
|
||||
void* that = engine->streamAlloc(sizeof(JniCallback), alignof(JniCallback));
|
||||
return new (that) JniCallback(env, handler, callback);
|
||||
}
|
||||
|
||||
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback)) {
|
||||
}
|
||||
|
||||
JniCallback::~JniCallback() {
|
||||
if (mHandler && mCallback) {
|
||||
#ifdef ANDROID
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
|
||||
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
|
||||
}
|
||||
#endif
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
|
||||
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
|
||||
}
|
||||
}
|
||||
mEnv->DeleteGlobalRef(mHandler);
|
||||
mEnv->DeleteGlobalRef(mCallback);
|
||||
}
|
||||
|
||||
void JniCallback::invoke(void*, size_t, void* user) {
|
||||
JniCallback* data = reinterpret_cast<JniCallback*>(user);
|
||||
// don't call delete here, because we don't own the storage
|
||||
data->~JniCallback();
|
||||
}
|
||||
|
||||
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
|
||||
void* that = engine->streamAlloc(sizeof(JniBufferCallback), alignof(JniBufferCallback));
|
||||
@@ -95,6 +62,37 @@ void JniBufferCallback::invoke(void*, size_t, void* user) {
|
||||
data->~JniBufferCallback();
|
||||
}
|
||||
|
||||
JniImageCallback* JniImageCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, long image) {
|
||||
void* that = engine->streamAlloc(sizeof(JniImageCallback), alignof(JniImageCallback));
|
||||
return new (that) JniImageCallback(env, handler, callback, image);
|
||||
}
|
||||
|
||||
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback))
|
||||
, mImage(image) { }
|
||||
|
||||
JniImageCallback::~JniImageCallback() {
|
||||
if (mHandler && mCallback) {
|
||||
#ifdef ANDROID
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
|
||||
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
|
||||
}
|
||||
#endif
|
||||
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
|
||||
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
|
||||
}
|
||||
}
|
||||
mEnv->DeleteGlobalRef(mHandler);
|
||||
mEnv->DeleteGlobalRef(mCallback);
|
||||
}
|
||||
|
||||
void JniImageCallback::invoke(void* image, void* user) {
|
||||
reinterpret_cast<JniImageCallback*>(user)->~JniImageCallback();
|
||||
}
|
||||
|
||||
void registerCallbackUtils(JNIEnv *env) {
|
||||
#ifdef ANDROID
|
||||
gCallbackUtils.handlerClass = env->FindClass("android/os/Handler");
|
||||
|
||||
@@ -23,21 +23,6 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
struct JniCallback {
|
||||
static JniCallback* make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback);
|
||||
|
||||
static void invoke(void* buffer, size_t n, void* user);
|
||||
|
||||
private:
|
||||
JniCallback(JNIEnv* env, jobject handler, jobject callback);
|
||||
~JniCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
};
|
||||
|
||||
struct JniBufferCallback {
|
||||
static JniBufferCallback* make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
|
||||
@@ -53,3 +38,19 @@ private:
|
||||
jobject mCallback;
|
||||
AutoBuffer mBuffer;
|
||||
};
|
||||
|
||||
struct JniImageCallback {
|
||||
static JniImageCallback* make(filament::Engine* engine, JNIEnv* env, jobject handler,
|
||||
jobject runnable, long image);
|
||||
|
||||
static void invoke(void* image, void* user);
|
||||
|
||||
private:
|
||||
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
|
||||
~JniImageCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
long mImage;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,10 @@ if(FILAMAT_LITE)
|
||||
set(FILAMAT_FLAVOR "filamat_lite")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
message("Library filamat ignores Vulkan settings")
|
||||
endif()
|
||||
|
||||
add_library(${FILAMAT_FLAVOR} STATIC IMPORTED)
|
||||
set_target_properties(${FILAMAT_FLAVOR} PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/lib${FILAMAT_FLAVOR}.a)
|
||||
@@ -29,15 +33,6 @@ set_target_properties(shaders PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
include_directories(${FILAMENT_DIR}/include)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-protector")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -ffp-contract=fast")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic-functions")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
|
||||
|
||||
add_library(filamat-jni SHARED
|
||||
@@ -52,4 +47,3 @@ target_link_libraries(filamat-jni
|
||||
log
|
||||
smol-v
|
||||
)
|
||||
|
||||
|
||||
@@ -1,70 +1,22 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
group = "com.google.android.filament"
|
||||
version = "0.1"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def filament_path = file("../../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filament_path = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
buildToolsVersion versions.buildTools
|
||||
compileSdkVersion versions.compileSdk
|
||||
ndkVersion versions.ndk
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-21")
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
if (project.hasProperty('extra_cmake_args')) {
|
||||
arguments.add(extra_cmake_args)
|
||||
}
|
||||
arguments.addAll(rootProject.ext.cmakeArgs)
|
||||
cppFlags.addAll(rootProject.ext.cppFlags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
@@ -101,6 +53,23 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.android.support:support-annotations:28.0.0'
|
||||
implementation deps.androidx.annotations
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
android/filamat-android/gradle.properties
Normal file
4
android/filamat-android/gradle.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
POM_NAME=Filament Material Builder
|
||||
POM_ARTIFACT_ID_FULL=filamat-android
|
||||
POM_ARTIFACT_ID_LITE=filamat-android-lite
|
||||
POM_PACKAGING=aar
|
||||
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user guide at https://docs.gradle.org/4.6/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
rootProject.name = 'filamat-android'
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialBuilder {
|
||||
@@ -99,14 +99,15 @@ public class MaterialBuilder {
|
||||
UV1, // texture coordinates (float2)
|
||||
BONE_INDICES, // indices of 4 bones (uvec4)
|
||||
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
|
||||
CUSTOM0,
|
||||
CUSTOM1,
|
||||
CUSTOM2,
|
||||
CUSTOM3,
|
||||
CUSTOM4,
|
||||
CUSTOM5,
|
||||
CUSTOM6,
|
||||
CUSTOM7
|
||||
UNUSED, // reserved for future use
|
||||
CUSTOM0, // custom or MORPH_POSITION_0
|
||||
CUSTOM1, // custom or MORPH_POSITION_1
|
||||
CUSTOM2, // custom or MORPH_POSITION_2
|
||||
CUSTOM3, // custom or MORPH_POSITION_3
|
||||
CUSTOM4, // custom or MORPH_TANGENTS_0
|
||||
CUSTOM5, // custom or MORPH_TANGENTS_1
|
||||
CUSTOM6, // custom or MORPH_TANGENTS_2
|
||||
CUSTOM7 // custom or MORPH_TANGENTS_3
|
||||
}
|
||||
|
||||
public enum BlendingMode {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialPackage {
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
15
android/filament-android/.idea/compiler.xml
generated
15
android/filament-android/.idea/compiler.xml
generated
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
</wildcardResourcePatterns>
|
||||
</component>
|
||||
</project>
|
||||
6
android/filament-android/.idea/encodings.xml
generated
6
android/filament-android/.idea/encodings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
34
android/filament-android/.idea/misc.xml
generated
34
android/filament-android/.idea/misc.xml
generated
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="5">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
8
android/filament-android/.idea/modules.xml
generated
8
android/filament-android/.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/filament-android.iml" filepath="$PROJECT_DIR$/filament-android.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
12
android/filament-android/.idea/runConfigurations.xml
generated
12
android/filament-android/.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
android/filament-android/.idea/vcs.xml
generated
6
android/filament-android/.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -38,67 +38,67 @@ add_library(smol-v STATIC IMPORTED)
|
||||
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
|
||||
|
||||
|
||||
include_directories(.. ${FILAMENT_DIR}/include)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-protector")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -ffp-contract=fast")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic-functions")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilament-jni.map")
|
||||
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
|
||||
|
||||
add_library(filament-jni SHARED
|
||||
src/main/cpp/Camera.cpp
|
||||
src/main/cpp/Colors.cpp
|
||||
src/main/cpp/VertexBuffer.cpp
|
||||
src/main/cpp/Engine.cpp
|
||||
src/main/cpp/EntityManager.cpp
|
||||
src/main/cpp/Fence.cpp
|
||||
src/main/cpp/IndexBuffer.cpp
|
||||
src/main/cpp/IndirectLight.cpp
|
||||
src/main/cpp/LightManager.cpp
|
||||
src/main/cpp/Material.cpp
|
||||
src/main/cpp/MaterialInstance.cpp
|
||||
src/main/cpp/MathUtils.cpp
|
||||
src/main/cpp/RenderableManager.cpp
|
||||
src/main/cpp/Renderer.cpp
|
||||
src/main/cpp/RenderTarget.cpp
|
||||
src/main/cpp/Scene.cpp
|
||||
src/main/cpp/SkyBox.cpp
|
||||
src/main/cpp/Stream.cpp
|
||||
src/main/cpp/Texture.cpp
|
||||
src/main/cpp/TextureSampler.cpp
|
||||
src/main/cpp/TransformManager.cpp
|
||||
src/main/cpp/View.cpp
|
||||
# Android specific
|
||||
src/main/cpp/nativewindow/Android.cpp
|
||||
# Private utils
|
||||
src/main/cpp/Filament.cpp
|
||||
# Common utils
|
||||
../common/CallbackUtils.cpp
|
||||
../common/NioUtils.cpp
|
||||
src/main/cpp/Camera.cpp
|
||||
src/main/cpp/Colors.cpp
|
||||
src/main/cpp/VertexBuffer.cpp
|
||||
src/main/cpp/Engine.cpp
|
||||
src/main/cpp/EntityManager.cpp
|
||||
src/main/cpp/Fence.cpp
|
||||
src/main/cpp/IndexBuffer.cpp
|
||||
src/main/cpp/IndirectLight.cpp
|
||||
src/main/cpp/LightManager.cpp
|
||||
src/main/cpp/Material.cpp
|
||||
src/main/cpp/MaterialInstance.cpp
|
||||
src/main/cpp/MathUtils.cpp
|
||||
src/main/cpp/RenderableManager.cpp
|
||||
src/main/cpp/Renderer.cpp
|
||||
src/main/cpp/RenderTarget.cpp
|
||||
src/main/cpp/Scene.cpp
|
||||
src/main/cpp/SkyBox.cpp
|
||||
src/main/cpp/Stream.cpp
|
||||
src/main/cpp/SurfaceOrientation.cpp
|
||||
src/main/cpp/Texture.cpp
|
||||
src/main/cpp/TextureSampler.cpp
|
||||
src/main/cpp/TransformManager.cpp
|
||||
src/main/cpp/View.cpp
|
||||
# Android specific
|
||||
src/main/cpp/nativewindow/Android.cpp
|
||||
# Private utils
|
||||
src/main/cpp/Filament.cpp
|
||||
# Common utils
|
||||
../common/CallbackUtils.cpp
|
||||
../common/NioUtils.cpp
|
||||
)
|
||||
|
||||
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
|
||||
target_link_libraries(filament-jni
|
||||
filament
|
||||
backend
|
||||
filaflat
|
||||
filabridge
|
||||
geometry
|
||||
ibl
|
||||
utils
|
||||
log
|
||||
GLESv3
|
||||
EGL
|
||||
android
|
||||
jnigraphics
|
||||
PRIVATE filament
|
||||
PRIVATE backend
|
||||
PRIVATE filaflat
|
||||
PRIVATE filabridge
|
||||
PRIVATE geometry
|
||||
PRIVATE ibl
|
||||
PRIVATE log
|
||||
PRIVATE GLESv3
|
||||
PRIVATE EGL
|
||||
PRIVATE android
|
||||
PRIVATE jnigraphics
|
||||
PRIVATE utils
|
||||
)
|
||||
|
||||
target_include_directories(filament-jni PRIVATE
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
../../third_party/robin-map
|
||||
../../libs/utils/include)
|
||||
|
||||
# Force a relink when the version script is changed:
|
||||
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
|
||||
@@ -1,73 +1,22 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
group = "com.google.android.filament"
|
||||
version = "0.1"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def filament_path = file("../../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filament_path = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
// Our minSdkVersion is actually 21, we lie and say 14 here so apps don't have
|
||||
// to increase their minSdkVersion unnecessarily. It is however up to them to
|
||||
// ensure they do not initialize Filament on API levels < 21.
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
buildToolsVersion versions.buildTools
|
||||
compileSdkVersion versions.compileSdk
|
||||
ndkVersion versions.ndk
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DANDROID_PIE=ON")
|
||||
arguments.add("-DANDROID_PLATFORM=android-21")
|
||||
arguments.add("-DANDROID_STL=c++_static")
|
||||
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
|
||||
cppFlags.add("-std=c++14")
|
||||
if (project.hasProperty('extra_cmake_args')) {
|
||||
arguments.add(extra_cmake_args)
|
||||
}
|
||||
arguments.addAll(rootProject.ext.cmakeArgs)
|
||||
cppFlags.addAll(rootProject.ext.cppFlags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
@@ -93,6 +42,18 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.android.support:support-annotations:28.0.0'
|
||||
implementation deps.androidx.annotations
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3
android/filament-android/gradle.properties
Normal file
3
android/filament-android/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
POM_NAME=Filament
|
||||
POM_ARTIFACT_ID=filament-android
|
||||
POM_PACKAGING=aar
|
||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
172
android/filament-android/gradlew
vendored
172
android/filament-android/gradlew
vendored
@@ -1,172 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
android/filament-android/gradlew.bat
vendored
84
android/filament-android/gradlew.bat
vendored
@@ -1,84 +0,0 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,4 +1,4 @@
|
||||
LIBFILAMENT {
|
||||
global: Java_com_google_android_filament_*; JNI*;
|
||||
global: *filament*; JNI*;
|
||||
local: *;
|
||||
};
|
||||
22
android/filament-android/proguard-rules.pro
vendored
22
android/filament-android/proguard-rules.pro
vendored
@@ -1,22 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# JNI is an entry point that's hard to keep track of, so there's
|
||||
# an annotation to mark fields and methods used by native code.
|
||||
|
||||
# Keep the annotations that proguard needs to process.
|
||||
-keep class com.google.android.filament.proguard.UsedBy*
|
||||
|
||||
# Just because native code accesses members of a class, does not mean that the
|
||||
# class itself needs to be annotated - only annotate classes that are
|
||||
# referenced themselves in native code.
|
||||
-keep @com.google.android.filament.proguard.UsedBy* class * {
|
||||
<init>();
|
||||
}
|
||||
-keepclassmembers class * {
|
||||
@com.google.android.filament.proguard.UsedBy* *;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = 'filament-android'
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/Camera.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -38,9 +40,9 @@ Java_com_google_android_filament_Camera_nSetProjectionFov(JNIEnv*, jclass ,
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
|
||||
jlong nativeCamera, jdouble focalLength, jdouble near, jdouble far) {
|
||||
jlong nativeCamera, jdouble focalLength, jdouble aspect, jdouble near, jdouble far) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
camera->setLensProjection(focalLength, near, far);
|
||||
camera->setLensProjection(focalLength, aspect, near, far);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/EntityManager.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
@@ -59,6 +62,13 @@ Java_com_google_android_filament_Engine_nCreateSwapChain(JNIEnv* env,
|
||||
return (jlong) engine->createSwapChain(win, (uint64_t) flags);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv* env,
|
||||
jclass klass, jlong nativeEngine, jint width, jint height, jlong flags) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createSwapChain(width, height, (uint64_t) flags);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainFromRawPointer(JNIEnv*,
|
||||
jclass, jlong nativeEngine, jlong pointer, jlong flags) {
|
||||
@@ -154,9 +164,9 @@ Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass,
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateFence(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint fenceType) {
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createFence((Fence::Type) fenceType);
|
||||
return (jlong) engine->createFence();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -252,6 +262,13 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass,
|
||||
engine->destroy(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv *env, jclass clazz,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
engine->flushAndWait();
|
||||
}
|
||||
|
||||
// Managers...
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include <filament/IndexBuffer.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <filament/Texture.h>
|
||||
#include <common/NioUtils.h>
|
||||
#include <common/CallbackUtils.h>
|
||||
#include <math/mat4.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -135,10 +136,31 @@ Java_com_google_android_filament_IndirectLight_nGetDirectionEstimate(JNIEnv* env
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetColorEstimate(JNIEnv* env, jclass,
|
||||
jlong nativeIndirectLight, jfloatArray outColor_, float x, float y, float z) {
|
||||
jlong nativeIndirectLight, jfloatArray outColor_, jfloat x, jfloat y, jfloat z) {
|
||||
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
|
||||
jfloat *outColor = env->GetFloatArrayElements(outColor_, NULL);
|
||||
*reinterpret_cast<filament::math::float4*>(outColor) =
|
||||
indirectLight->getColorEstimate(math::float3{x, y, z});
|
||||
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetDirectionEstimateStatic(JNIEnv *env, jclass,
|
||||
jfloatArray sh_, jfloatArray outDirection_) {
|
||||
jfloat* sh = env->GetFloatArrayElements(sh_, NULL);
|
||||
jfloat *outDirection = env->GetFloatArrayElements(outDirection_, NULL);
|
||||
*reinterpret_cast<filament::math::float3*>(outDirection) = IndirectLight::getDirectionEstimate((filament::math::float3*)sh);
|
||||
env->ReleaseFloatArrayElements(outDirection_, outDirection, 0);
|
||||
env->ReleaseFloatArrayElements(sh_, sh, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_IndirectLight_nGetColorEstimateStatic(JNIEnv *env, jclass,
|
||||
jfloatArray outColor_, jfloatArray sh_, jfloat x, jfloat y, jfloat z) {
|
||||
jfloat* sh = env->GetFloatArrayElements(sh_, NULL);
|
||||
jfloat *outColor = env->GetFloatArrayElements(outColor_, NULL);
|
||||
*reinterpret_cast<filament::math::float4*>(outColor) =
|
||||
IndirectLight::getColorEstimate((filament::math::float3*)sh, math::float3{x, y, z});
|
||||
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
|
||||
env->ReleaseFloatArrayElements(sh_, sh, JNI_ABORT);
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/LightManager.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
@@ -64,7 +66,8 @@ Java_com_google_android_filament_LightManager_nBuilderCastShadows(JNIEnv*, jclas
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint mapSize, jfloat constantBias, jfloat normalBias, jfloat shadowFar,
|
||||
jfloat shadowNearHint, jfloat shadowFarHint, jboolean stable) {
|
||||
jfloat shadowNearHint, jfloat shadowFarHint, jboolean stable,
|
||||
jboolean screenSpaceContactShadows, jint stepCount, jfloat maxShadowDistance) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
builder->shadowOptions(
|
||||
LightManager::ShadowOptions{.mapSize = (uint32_t)mapSize,
|
||||
@@ -73,7 +76,10 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv*, jcl
|
||||
.shadowFar = shadowFar,
|
||||
.shadowNearHint = shadowNearHint,
|
||||
.shadowFarHint = shadowFarHint,
|
||||
.stable = (bool)stable});
|
||||
.stable = (bool)stable,
|
||||
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
|
||||
.stepCount = uint8_t(stepCount),
|
||||
.maxShadowDistance = maxShadowDistance});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -84,6 +84,23 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
|
||||
return (jint) material->getBlendingMode();
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetRefraction(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint)material->getRefractionMode();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetRefractionType(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint) material->getRefractionType();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetVertexDomain(JNIEnv*, jclass,
|
||||
|
||||
@@ -316,3 +316,35 @@ Java_com_google_android_filament_MaterialInstance_nSetDoubleSided(JNIEnv*,
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setDoubleSided(doubleSided);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetCullingMode(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jlong cullingMode) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setCullingMode((MaterialInstance::CullingMode) cullingMode);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetColorWrite(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jboolean enable) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setColorWrite(enable);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetDepthWrite(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jboolean enable) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setDepthWrite(enable);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jboolean enable) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setDepthCulling(enable);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ Java_com_google_android_filament_RenderTarget_nDestroyBuilder(JNIEnv *env, jclas
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nBuilderTexture(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jlong attachment, jlong nativeTexture) {
|
||||
jlong nativeBuilder, jint attachment, jlong nativeTexture) {
|
||||
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
builder->texture(RenderTarget::AttachmentPoint(attachment), texture);
|
||||
@@ -47,14 +47,14 @@ Java_com_google_android_filament_RenderTarget_nBuilderTexture(JNIEnv *env, jclas
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nBuilderMipLevel(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jlong attachment, jint level) {
|
||||
jlong nativeBuilder, jint attachment, jint level) {
|
||||
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
|
||||
builder->mipLevel(RenderTarget::AttachmentPoint(attachment), level);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nBuilderFace(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jlong attachment, jint face) {
|
||||
jlong nativeBuilder, jint attachment, jint face) {
|
||||
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
|
||||
RenderTarget::CubemapFace cubeface = (RenderTarget::CubemapFace) face;
|
||||
builder->face(RenderTarget::AttachmentPoint(attachment), cubeface);
|
||||
@@ -62,7 +62,7 @@ Java_com_google_android_filament_RenderTarget_nBuilderFace(JNIEnv *env, jclass t
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nBuilderLayer(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jlong attachment, jint layer) {
|
||||
jlong nativeBuilder, jint attachment, jint layer) {
|
||||
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
|
||||
builder->layer(RenderTarget::AttachmentPoint(attachment), layer);
|
||||
}
|
||||
@@ -77,7 +77,21 @@ Java_com_google_android_filament_RenderTarget_nBuilderBuild(JNIEnv *env, jclass
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nGetMipLevel(JNIEnv *env, jclass type,
|
||||
jlong nativeTarget, jlong attachment) {
|
||||
jlong nativeTarget, jint attachment) {
|
||||
RenderTarget* target = (RenderTarget*) nativeTarget;
|
||||
return (jint) target->getMipLevel(RenderTarget::AttachmentPoint(attachment));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nGetFace(JNIEnv *env, jclass type,
|
||||
long nativeTarget, int attachment) {
|
||||
RenderTarget* target = (RenderTarget*) nativeTarget;
|
||||
return (jint) target->getFace(RenderTarget::AttachmentPoint(attachment));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderTarget_nGetLayer(JNIEnv *env, jclass type,
|
||||
long nativeTarget, int attachment) {
|
||||
RenderTarget* target = (RenderTarget*) nativeTarget;
|
||||
return (jint) target->getLayer(RenderTarget::AttachmentPoint(attachment));
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/MaterialInstance.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
@@ -160,6 +164,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderReceiveShadows(JNIEnv
|
||||
builder->receiveShadows(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderScreenSpaceContactShadows(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->screenSpaceContactShadows(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint boneCount) {
|
||||
@@ -271,6 +282,13 @@ Java_com_google_android_filament_RenderableManager_nSetReceiveShadows(JNIEnv*, j
|
||||
rm->setReceiveShadows((RenderableManager::Instance) i, enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetScreenSpaceContactShadows(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setScreenSpaceContactShadows((RenderableManager::Instance) i, enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nIsShadowCaster(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i) {
|
||||
|
||||
@@ -97,6 +97,42 @@ Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Renderer_nReadPixelsEx(JNIEnv *env, jclass,
|
||||
jlong nativeRenderer, jlong nativeEngine, jlong nativeRenderTarget,
|
||||
jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint top, jint type, jint alignment, jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
RenderTarget *renderTarget = (RenderTarget *) nativeRenderTarget;
|
||||
|
||||
stride = stride ? stride : width;
|
||||
size_t sizeInBytes = PixelBufferDescriptor::computeDataSize(
|
||||
(PixelDataFormat) format, (PixelDataType) type,
|
||||
(size_t) stride, (size_t) (height + top), (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *buffer = nioBuffer.getData();
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
|
||||
renderer->readPixels(renderTarget,
|
||||
uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jdouble JNICALL
|
||||
Java_com_google_android_filament_Renderer_nGetUserTime(JNIEnv*, jclass, jlong nativeRenderer) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/Scene.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
|
||||
@@ -47,6 +47,13 @@ Java_com_google_android_filament_Skybox_nBuilderShowSun(JNIEnv *env, jclass type
|
||||
builder->showSun(show);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Skybox_nBuilderIntensity(JNIEnv *env, jclass clazz,
|
||||
jlong nativeSkyBoxBuilder, jfloat intensity) {
|
||||
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
|
||||
builder->intensity(intensity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
|
||||
jlong nativeSkyBoxBuilder, jlong nativeEngine) {
|
||||
@@ -68,3 +75,10 @@ Java_com_google_android_filament_Skybox_nGetLayerMask(JNIEnv *env, jclass type,
|
||||
Skybox *skybox = (Skybox *) nativeSkybox;
|
||||
return static_cast<jint>(skybox->getLayerMask());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_Skybox_nGetIntensity(JNIEnv *env, jclass clazz,
|
||||
jlong nativeSkybox) {
|
||||
Skybox *skybox = (Skybox *) nativeSkybox;
|
||||
return static_cast<jint>(skybox->getIntensity());
|
||||
}
|
||||
|
||||
@@ -24,6 +24,25 @@
|
||||
#include "common/NioUtils.h"
|
||||
#include "common/CallbackUtils.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#if __has_include(<android/hardware_buffer_jni.h>)
|
||||
#include <android/hardware_buffer_jni.h>
|
||||
#else
|
||||
struct AHardwareBuffer;
|
||||
typedef struct AHardwareBuffer AHardwareBuffer;
|
||||
#endif
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using PFN_FROMHARDWAREBUFFER = AHardwareBuffer* (*)(JNIEnv*, jobject);
|
||||
static PFN_FROMHARDWAREBUFFER AHardwareBuffer_fromHardwareBuffer_fn = nullptr;
|
||||
static bool sHardwareBufferSupported = true;
|
||||
|
||||
#endif
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
@@ -108,10 +127,10 @@ Java_com_google_android_filament_Stream_nBuilderBuild(JNIEnv*, jclass,
|
||||
return (jlong) builder->builder()->build(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Stream_nIsNative(JNIEnv*, jclass, jlong nativeStream) {
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetStreamType(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
return (jboolean) stream->isNativeStream();
|
||||
return (jint) stream->getStreamType();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -160,3 +179,44 @@ Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nat
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
return stream->getTimestamp();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, jlong nativeStream,
|
||||
jlong nativeEngine, jobject hwbuffer, jobject handler, jobject runnable) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
// This function is not available before NDK 15 or before Android 8.
|
||||
if (UTILS_UNLIKELY(!AHardwareBuffer_fromHardwareBuffer_fn)) {
|
||||
if (!sHardwareBufferSupported) {
|
||||
return;
|
||||
}
|
||||
AHardwareBuffer_fromHardwareBuffer_fn = (PFN_FROMHARDWAREBUFFER) dlsym(RTLD_DEFAULT, "AHardwareBuffer_fromHardwareBuffer");
|
||||
if (!AHardwareBuffer_fromHardwareBuffer_fn) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Filament", "AHardwareBuffer_fromHardwareBuffer is not available.");
|
||||
sHardwareBufferSupported = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AHardwareBuffer* nativeBuffer = AHardwareBuffer_fromHardwareBuffer_fn(env, hwbuffer);
|
||||
if (!nativeBuffer) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Filament", "Unable to obtain native HardwareBuffer.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* callback = JniImageCallback::make(engine, env, handler, runnable, (long) nativeBuffer);
|
||||
|
||||
#else
|
||||
|
||||
// TODO: for non-Android platforms, it is unclear how to go from "jobject" to "void*"
|
||||
// For now this code is reserved for future use.
|
||||
auto* callback = JniImageCallback::make(engine, env, handler, runnable, 0);
|
||||
void* nativeBuffer = nullptr;
|
||||
|
||||
#endif
|
||||
|
||||
stream->setAcquiredImage((void*) nativeBuffer, &JniImageCallback::invoke, callback);
|
||||
}
|
||||
|
||||
170
android/filament-android/src/main/cpp/SurfaceOrientation.cpp
Normal file
170
android/filament-android/src/main/cpp/SurfaceOrientation.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <geometry/SurfaceOrientation.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::geometry;
|
||||
using namespace filament::math;
|
||||
|
||||
namespace {
|
||||
struct JniWrapper {
|
||||
SurfaceOrientation::Builder* builder;
|
||||
AutoBuffer* normals;
|
||||
AutoBuffer* tangents;
|
||||
AutoBuffer* uvs;
|
||||
AutoBuffer* positions;
|
||||
AutoBuffer* triangles16;
|
||||
AutoBuffer* triangles32;
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nCreateBuilder(JNIEnv* env, jclass) {
|
||||
JniWrapper* wrapper = new JniWrapper();
|
||||
wrapper->builder = new SurfaceOrientation::Builder();
|
||||
return (jlong) wrapper;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nDestroyBuilder(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder) {
|
||||
auto wrapper = (JniWrapper*) nativeBuilder;
|
||||
delete wrapper->builder;
|
||||
delete wrapper->normals;
|
||||
delete wrapper->tangents;
|
||||
delete wrapper->uvs;
|
||||
delete wrapper->positions;
|
||||
delete wrapper->triangles16;
|
||||
delete wrapper->triangles32;
|
||||
delete wrapper;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nBuilderVertexCount(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, int vertexCount) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
wrapper->builder->vertexCount(vertexCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderTriangleCount(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, int triangleCount) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
wrapper->builder->triangleCount(triangleCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderNormals(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, jint remaining, int stride) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->normals = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->normals((const float3 *) buffer->getData(), stride);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderTangents(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, jint remaining, int stride) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->tangents = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->tangents((const float4 *) buffer->getData(), stride);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderUVs(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, int remaining, int stride) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->uvs = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->uvs((const float2 *) buffer->getData(), stride);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderPositions(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, int remaining, int stride) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->positions = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->positions((const float3 *) buffer->getData(), stride);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderTriangles16(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, int remaining) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->triangles16 = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->triangles((const ushort3 *) buffer->getData());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_mBuilderTriangles32(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jobject javaBuffer, int remaining) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
AutoBuffer* buffer = wrapper->triangles32 = new AutoBuffer(env, javaBuffer, remaining);
|
||||
wrapper->builder->triangles((const uint3 *) buffer->getData());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nBuilderBuild(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder) {
|
||||
auto wrapper = (JniWrapper *) nativeBuilder;
|
||||
return (jlong) wrapper->builder->build();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nGetVertexCount(JNIEnv* env, jclass,
|
||||
jlong nativeObject) {
|
||||
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
|
||||
return helper->getVertexCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsFloat(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jobject javaBuffer, int remaining) {
|
||||
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
size_t requestedCount = std::min(buffer.getSize() / sizeof(float4), helper->getVertexCount());
|
||||
helper->getQuats((quatf*) buffer.getData(), requestedCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsHalf(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jobject javaBuffer, int remaining) {
|
||||
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
size_t requestedCount = std::min(buffer.getSize() / sizeof(quath), helper->getVertexCount());
|
||||
helper->getQuats((quath*) buffer.getData(), requestedCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsShort(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jobject javaBuffer, int remaining) {
|
||||
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
size_t requestedCount = std::min(buffer.getSize() / sizeof(short4), helper->getVertexCount());
|
||||
helper->getQuats((short4*) buffer.getData(), requestedCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SurfaceOrientation_nDestroy(JNIEnv* env, jclass,
|
||||
jlong nativeSurfaceOrientation) {
|
||||
SurfaceOrientation* helper = (SurfaceOrientation*) nativeSurfaceOrientation;
|
||||
delete helper;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong na
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
@@ -199,8 +199,7 @@ extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
|
||||
jint width, jint height, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint compressedSizeInBytes, jint compressedFormat,
|
||||
jint, jint, jint, jint, jint compressedSizeInBytes, jint compressedFormat,
|
||||
jobject handler, jobject runnable) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
@@ -208,7 +207,7 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
|
||||
size_t sizeInBytes = (size_t) compressedSizeInBytes;
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
@@ -235,7 +234,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, NULL);
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
|
||||
Texture::FaceOffsets faceOffsets;
|
||||
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
|
||||
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
|
||||
@@ -244,7 +243,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
@@ -271,7 +270,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, NULL);
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
|
||||
Texture::FaceOffsets faceOffsets;
|
||||
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
|
||||
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
|
||||
@@ -279,7 +278,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
|
||||
size_t sizeInBytes = 6 * (size_t) compressedSizeInBytes;
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
@@ -340,28 +339,29 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, NULL);
|
||||
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
|
||||
Texture::FaceOffsets faceOffsets;
|
||||
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
|
||||
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
|
||||
|
||||
stride = stride ? stride : width;
|
||||
size_t sizeInBytes = 6 *
|
||||
Texture::computeTextureDataSize((Texture::Format) format, (Texture::Type) type,
|
||||
(size_t) stride, (size_t) height, (size_t) alignment);
|
||||
Texture::computeTextureDataSize((Texture::Format) format, (Texture::Type) type,
|
||||
(size_t) stride, (size_t) height, (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *buffer = nioBuffer.getData();
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
void* buffer = nioBuffer.getData();
|
||||
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t)0, (uint32_t)0,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(backend::PixelDataType) type, (uint8_t) alignment,
|
||||
(uint32_t) left, (uint32_t) top, (uint32_t) stride,
|
||||
&JniBufferCallback::invoke, callback);
|
||||
|
||||
Texture::PrefilterOptions options;
|
||||
options.sampleCount = sampleCount;
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <filament/TransformManager.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
using namespace utils;
|
||||
using namespace filament;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -161,17 +162,18 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*,
|
||||
jclass, jlong nativeView, jboolean enabled, jboolean homogeneousScaling,
|
||||
jfloat targetFrameTimeMilli, jfloat headRoomRatio, jfloat scaleRate,
|
||||
jfloat minScale, jfloat maxScale, jint history) {
|
||||
View* view = (View*) nativeView;
|
||||
jfloat minScale, jfloat maxScale, jint history, jint quality) {
|
||||
View* view = (View*)nativeView;
|
||||
View::DynamicResolutionOptions options;
|
||||
options.enabled = enabled;
|
||||
options.homogeneousScaling = homogeneousScaling;
|
||||
options.targetFrameTimeMilli = targetFrameTimeMilli;
|
||||
options.headRoomRatio = headRoomRatio;
|
||||
options.scaleRate = scaleRate;
|
||||
options.minScale = filament::math::float2{minScale};
|
||||
options.maxScale = filament::math::float2{maxScale};
|
||||
options.history = (uint8_t) history;
|
||||
options.minScale = filament::math::float2{ minScale };
|
||||
options.maxScale = filament::math::float2{ maxScale };
|
||||
options.history = (uint8_t)history;
|
||||
options.quality = (View::QualityLevel)quality;
|
||||
view->setDynamicResolutionOptions(options);
|
||||
}
|
||||
|
||||
@@ -192,13 +194,6 @@ Java_com_google_android_filament_View_nSetDynamicLightingOptions(JNIEnv*,
|
||||
view->setDynamicLightingOptions(zLightNear, zLightFar);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDepthPrepass(JNIEnv*,
|
||||
jclass, jlong nativeView, jint value) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setDepthPrepass(View::DepthPrepass(value));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetPostProcessingEnabled(JNIEnv*,
|
||||
jclass, jlong nativeView, jboolean enabled) {
|
||||
@@ -241,8 +236,58 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution) {
|
||||
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
|
||||
jint quality) {
|
||||
View* view = (View*) nativeView;
|
||||
View::AmbientOcclusionOptions options = { .radius = radius, .bias = bias, .power = power, .resolution = resolution};
|
||||
View::AmbientOcclusionOptions options = {
|
||||
.radius = radius,
|
||||
.power = power,
|
||||
.bias = bias,
|
||||
.resolution = resolution,
|
||||
.intensity = intensity,
|
||||
.quality = (View::QualityLevel)quality
|
||||
};
|
||||
view->setAmbientOcclusionOptions(options);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jlong nativeTexture,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jint blendMode, jboolean threshold, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
Texture* dirt = (Texture*) nativeTexture;
|
||||
View::BloomOptions options = {
|
||||
.dirt = dirt,
|
||||
.dirtStrength = dirtStrength,
|
||||
.strength = strength,
|
||||
.resolution = (uint32_t)resolution,
|
||||
.anamorphism = anamorphism,
|
||||
.levels = (uint8_t)levels,
|
||||
.blendMode = (View::BloomOptions::BlendMode)blendMode,
|
||||
.threshold = (bool)threshold,
|
||||
.enabled = (bool)enabled
|
||||
};
|
||||
view->setBloomOptions(options);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong nativeView,
|
||||
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat r,
|
||||
jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
|
||||
jfloat inScatteringSize, jboolean fogColorFromIbl, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
View::FogOptions options = {
|
||||
.distance = distance,
|
||||
.maximumOpacity = maximumOpacity,
|
||||
.height = height,
|
||||
.heightFalloff = heightFalloff,
|
||||
.color = math::float3{r, g, b},
|
||||
.density = density,
|
||||
.inScatteringStart = inScatteringStart,
|
||||
.inScatteringSize = inScatteringSize,
|
||||
.fogColorFromIbl = (bool)fogColorFromIbl,
|
||||
.enabled = (bool)enabled
|
||||
};
|
||||
view->setFogOptions(options);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<darwin/jawt_md.h>)
|
||||
#include <darwin/jawt_md.h>
|
||||
#else
|
||||
#include <jawt_md.h>
|
||||
#endif
|
||||
#else
|
||||
#include <darwin/jawt_md.h>
|
||||
#endif
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include "JAWTUtils.h"
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.google.android.filament;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.EGL14;
|
||||
import android.opengl.EGLContext;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
final class AndroidPlatform extends Platform {
|
||||
private static final String LOG_TAG = "Filament";
|
||||
@@ -59,6 +61,20 @@ final class AndroidPlatform extends Platform {
|
||||
|
||||
@Override
|
||||
long getSharedContextNativeHandle(Object sharedContext) {
|
||||
return ((EGLContext) sharedContext).getNativeHandle();
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
return AndroidPlatform21.getSharedContextNativeHandle(sharedContext);
|
||||
} else {
|
||||
try {
|
||||
//noinspection JavaReflectionMemberAccess
|
||||
Method method = EGLContext.class.getDeclaredMethod("getHandle");
|
||||
Integer handle = (Integer) method.invoke(sharedContext);
|
||||
//noinspection ConstantConditions
|
||||
return handle.longValue();
|
||||
} catch (Exception e) {
|
||||
Log.d(LOG_TAG, "Could not access shared context's native handle", e);
|
||||
}
|
||||
// Should not happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.opengl.EGLContext;
|
||||
|
||||
final class AndroidPlatform21 {
|
||||
static long getSharedContextNativeHandle(Object sharedContext) {
|
||||
return ((EGLContext) sharedContext).getNativeHandle();
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
final class Asserts {
|
||||
private Asserts() {
|
||||
|
||||
@@ -16,15 +16,28 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* An axis-aligned 3D box represented by its center and half-extent.
|
||||
*
|
||||
* The half-extent is a vector representing the distance from the center to the edge of the box in
|
||||
* each dimension. For example, a box of size 2 units in X, 4 units in Y, and 10 units in Z would
|
||||
* have a half-extent of (1, 2, 5).
|
||||
*/
|
||||
public class Box {
|
||||
private final float[] mCenter = new float[3];
|
||||
private final float[] mHalfExtent = new float[3];
|
||||
|
||||
/**
|
||||
* Default-initializes the 3D box to have a center and half-extent of (0,0,0).
|
||||
*/
|
||||
public Box() { }
|
||||
|
||||
/**
|
||||
* Initializes the 3D box from its center and half-extent.
|
||||
*/
|
||||
public Box(float centerX, float centerY, float centerZ,
|
||||
float halfExtentX, float halfExtentY, float halfExtentZ) {
|
||||
mCenter[0] = centerX;
|
||||
@@ -35,6 +48,13 @@ public class Box {
|
||||
mHalfExtent[2] = halfExtentZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the 3D box from its center and half-extent.
|
||||
*
|
||||
* @param center a float array with XYZ coordinates representing the center of the box
|
||||
* @param halfExtent a float array with XYZ coordinates representing half the size of the box in
|
||||
* each dimension
|
||||
*/
|
||||
public Box(@NonNull @Size(min = 3) float[] center, @NonNull @Size(min = 3) float[] halfExtent) {
|
||||
mCenter[0] = center[0];
|
||||
mCenter[1] = center[1];
|
||||
@@ -44,21 +64,37 @@ public class Box {
|
||||
mHalfExtent[2] = halfExtent[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the center of of the 3D box.
|
||||
*/
|
||||
public void setCenter(float centerX, float centerY, float centerZ) {
|
||||
mCenter[0] = centerX;
|
||||
mCenter[1] = centerY;
|
||||
mCenter[2] = centerZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the half-extent of the 3D box.
|
||||
*/
|
||||
public void setHalfExtent(float halfExtentX, float halfExtentY, float halfExtentZ) {
|
||||
mHalfExtent[0] = halfExtentX;
|
||||
mHalfExtent[1] = halfExtentY;
|
||||
mHalfExtent[2] = halfExtentZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the center of the 3D box.
|
||||
*
|
||||
* @return an XYZ float array of size 3
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getCenter() { return mCenter; }
|
||||
|
||||
/**
|
||||
* Returns the half-extent from the center of the 3D box.
|
||||
*
|
||||
* @return an XYZ float array of size 3
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getHalfExtent() { return mHalfExtent; }
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
/**
|
||||
* Camera represents the eye through which the scene is viewed.
|
||||
@@ -157,26 +157,30 @@ public class Camera {
|
||||
* @param projection type of projection to use
|
||||
*
|
||||
* @param left distance in world units from the camera to the left plane,
|
||||
* at the near plane. Precondition: left != right.
|
||||
* at the near plane. Precondition: <code>left</code> != <code>right</code>
|
||||
*
|
||||
* @param right distance in world units from the camera to the right plane,
|
||||
* at the near plane. Precondition: left != right.
|
||||
* at the near plane. Precondition: <code>left</code> != <code>right</code>
|
||||
*
|
||||
* @param bottom distance in world units from the camera to the bottom plane,
|
||||
* at the near plane. Precondition: bottom != top.
|
||||
* at the near plane. Precondition: <code>bottom</code> != <code>top</code>
|
||||
*
|
||||
* @param top distance in world units from the camera to the top plane,
|
||||
* at the near plane. Precondition: left != right.
|
||||
* at the near plane. Precondition: <code>bottom</code> != <code>top</code>
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -near.
|
||||
* Precondition: near > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* near != far for {@link Projection#ORTHO}.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
* Precondition:
|
||||
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param far distance in world units from the camera to the far plane.
|
||||
* The far plane's position in view space is z = -far.
|
||||
* Precondition: far > near for {@link Projection#PERSPECTIVE} or
|
||||
* far != near for {@link Projection#ORTHO}.
|
||||
* The far plane's position in view space is z = -<code>far</code>.
|
||||
* Precondition:
|
||||
* <code>far</code> > <code>near</code>
|
||||
* for {@link Projection#PERSPECTIVE} or
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*
|
||||
* <p>
|
||||
* These parameters are silently modified to meet the preconditions above.
|
||||
@@ -189,12 +193,32 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the projection matrix from the field-of-view.
|
||||
*
|
||||
* @param fovInDegrees
|
||||
* @param aspect
|
||||
* @param near
|
||||
* @param far
|
||||
* @param direction
|
||||
* @param fovInDegrees full field-of-view in degrees.
|
||||
* 0 < <code>fovInDegrees</code> < 180
|
||||
*
|
||||
* @param aspect aspect ratio width/height. <code>aspect</code> > 0
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
* Precondition:
|
||||
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param far distance in world units from the camera to the far plane.
|
||||
* The far plane's position in view space is z = -<code>far</code>.
|
||||
* Precondition:
|
||||
* <code>far</code> > <code>near</code>
|
||||
* for {@link Projection#PERSPECTIVE} or
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param direction direction of the field-of-view parameter.
|
||||
* <p>
|
||||
* These parameters are silently modified to meet the preconditions above.
|
||||
*
|
||||
* @see Fov
|
||||
*/
|
||||
public void setProjection(double fovInDegrees, double aspect, double near, double far,
|
||||
@NonNull Fov direction) {
|
||||
@@ -202,47 +226,88 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the projection matrix from the focal length.
|
||||
*
|
||||
* @param focalLength lens's focal length in millimeters. <code>focalLength</code> > 0
|
||||
*
|
||||
* @param aspect aspect ratio width/height. <code>aspect</code> > 0
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
* Precondition:
|
||||
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param far distance in world units from the camera to the far plane.
|
||||
* The far plane's position in view space is z = -<code>far</code>.
|
||||
* Precondition:
|
||||
* <code>far</code> > <code>near</code>
|
||||
* for {@link Projection#PERSPECTIVE} or
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param focalLength
|
||||
* @param near
|
||||
* @param far
|
||||
*/
|
||||
public void setLensProjection(double focalLength, double near, double far) {
|
||||
nSetLensProjection(getNativeObject(), focalLength, near, far);
|
||||
public void setLensProjection(double focalLength, double aspect, double near, double far) {
|
||||
nSetLensProjection(getNativeObject(), focalLength, aspect, near, far);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the projection matrix.
|
||||
*
|
||||
* @param inMatrix
|
||||
* @param near
|
||||
* @param far
|
||||
* @param inMatrix custom projection matrix.
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
* Precondition:
|
||||
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param far distance in world units from the camera to the far plane.
|
||||
* The far plane's position in view space is z = -<code>far</code>.
|
||||
* Precondition:
|
||||
* <code>far</code> > <code>near</code>
|
||||
* for {@link Projection#PERSPECTIVE} or
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*/
|
||||
public void setCustomProjection(@NonNull @Size(min = 16) double inMatrix[],
|
||||
public void setCustomProjection(@NonNull @Size(min = 16) double[] inMatrix,
|
||||
double near, double far) {
|
||||
Asserts.assertMat4dIn(inMatrix);
|
||||
nSetCustomProjection(getNativeObject(), inMatrix, near, far);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
* <p>
|
||||
* Helper method to set the camera's entity transform component.
|
||||
* Remember that the Camera "looks" towards its -z axis.
|
||||
* <p>
|
||||
* This has the same effect as calling:
|
||||
*
|
||||
* @param in
|
||||
* <pre>
|
||||
* engine.getTransformManager().setTransform(
|
||||
* engine.getTransformManager().getInstance(camera->getEntity()), viewMatrix);
|
||||
* </pre>
|
||||
*
|
||||
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
|
||||
*/
|
||||
public void setModelMatrix(@NonNull @Size(min = 16) float in[]) {
|
||||
Asserts.assertMat4fIn(in);
|
||||
nSetModelMatrix(getNativeObject(), in);
|
||||
public void setModelMatrix(@NonNull @Size(min = 16) float[] viewMatrix) {
|
||||
Asserts.assertMat4fIn(viewMatrix);
|
||||
nSetModelMatrix(getNativeObject(), viewMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
*
|
||||
* @param eyeX
|
||||
* @param eyeY
|
||||
* @param eyeZ
|
||||
* @param centerX
|
||||
* @param centerY
|
||||
* @param centerZ
|
||||
* @param upX
|
||||
* @param upY
|
||||
* @param upZ
|
||||
* @param eyeX x-axis position of the camera in world space
|
||||
* @param eyeY y-axis position of the camera in world space
|
||||
* @param eyeZ z-axis position of the camera in world space
|
||||
* @param centerX x-axis position of the point in world space the camera is looking at
|
||||
* @param centerY y-axis position of the point in world space the camera is looking at
|
||||
* @param centerZ z-axis position of the point in world space the camera is looking at
|
||||
* @param upX x-axis coordinate of a unit vector denoting the camera's "up" direction
|
||||
* @param upY y-axis coordinate of a unit vector denoting the camera's "up" direction
|
||||
* @param upZ z-axis coordinate of a unit vector denoting the camera's "up" direction
|
||||
*/
|
||||
public void lookAt(double eyeX, double eyeY, double eyeZ,
|
||||
double centerX, double centerY, double centerZ, double upX, double upY, double upZ) {
|
||||
@@ -250,16 +315,14 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Distance to the near plane.
|
||||
* @return Distance to the near plane
|
||||
*/
|
||||
public float getNear() {
|
||||
return nGetNear(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Distance to the far plane.
|
||||
* @return Distance to the far plane
|
||||
*/
|
||||
public float getCullingFar() {
|
||||
return nGetCullingFar(getNativeObject());
|
||||
@@ -267,12 +330,14 @@ public class Camera {
|
||||
|
||||
/**
|
||||
* Retrieves the camera's projection matrix.
|
||||
*
|
||||
* @param out A 16-float array where the projection matrix will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-float array containing the camera's projection as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public double[] getProjectionMatrix(@Nullable @Size(min = 16) double out[]) {
|
||||
public double[] getProjectionMatrix(@Nullable @Size(min = 16) double[] out) {
|
||||
out = Asserts.assertMat4d(out);
|
||||
nGetProjectionMatrix(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -281,12 +346,14 @@ public class Camera {
|
||||
/**
|
||||
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
|
||||
* orientation, or pose.
|
||||
*
|
||||
* @param out A 16-float array where the model matrix will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-float array containing the camera's pose as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public float[] getModelMatrix(@Nullable @Size(min = 16) float out[]) {
|
||||
public float[] getModelMatrix(@Nullable @Size(min = 16) float[] out) {
|
||||
out = Asserts.assertMat4f(out);
|
||||
nGetModelMatrix(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -297,10 +364,11 @@ public class Camera {
|
||||
*
|
||||
* @param out A 16-float array where the model view will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-float array containing the camera's view as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public float[] getViewMatrix(@Nullable @Size(min = 16) float out[]) {
|
||||
public float[] getViewMatrix(@Nullable @Size(min = 16) float[] out) {
|
||||
out = Asserts.assertMat4f(out);
|
||||
nGetViewMatrix(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -308,12 +376,14 @@ public class Camera {
|
||||
|
||||
/**
|
||||
* Retrieves the camera position in world space.
|
||||
*
|
||||
* @param out A 3-float array where the position will be stored, or null in which case a new
|
||||
* array is allocated.
|
||||
*
|
||||
* @return A 3-float array containing the camera's position in world units.
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getPosition(@Nullable @Size(min = 3) float out[]) {
|
||||
public float[] getPosition(@Nullable @Size(min = 3) float[] out) {
|
||||
out = Asserts.assertFloat3(out);
|
||||
nGetPosition(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -322,12 +392,14 @@ public class Camera {
|
||||
/**
|
||||
* Retrieves the camera left unit vector in world space, that is a unit vector that points to
|
||||
* the left of the camera.
|
||||
*
|
||||
* @param out A 3-float array where the left vector will be stored, or null in which case a new
|
||||
* array is allocated.
|
||||
*
|
||||
* @return A 3-float array containing the camera's left vector in world units.
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getLeftVector(@Nullable @Size(min = 3) float out[]) {
|
||||
public float[] getLeftVector(@Nullable @Size(min = 3) float[] out) {
|
||||
out = Asserts.assertFloat3(out);
|
||||
nGetLeftVector(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -336,12 +408,14 @@ public class Camera {
|
||||
/**
|
||||
* Retrieves the camera up unit vector in world space, that is a unit vector that points up with
|
||||
* respect to the camera.
|
||||
*
|
||||
* @param out A 3-float array where the up vector will be stored, or null in which case a new
|
||||
* array is allocated.
|
||||
*
|
||||
* @return A 3-float array containing the camera's up vector in world units.
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getUpVector(@Nullable @Size(min = 3) float out[]) {
|
||||
public float[] getUpVector(@Nullable @Size(min = 3) float[] out) {
|
||||
out = Asserts.assertFloat3(out);
|
||||
nGetUpVector(getNativeObject(), out);
|
||||
return out;
|
||||
@@ -350,46 +424,83 @@ public class Camera {
|
||||
/**
|
||||
* Retrieves the camera forward unit vector in world space, that is a unit vector that points
|
||||
* in the direction the camera is looking at.
|
||||
*
|
||||
* @param out A 3-float array where the forward vector will be stored, or null in which case a
|
||||
* new array is allocated.
|
||||
*
|
||||
* @return A 3-float array containing the camera's forward vector in world units.
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getForwardVector(@Nullable @Size(min = 3) float out[]) {
|
||||
public float[] getForwardVector(@Nullable @Size(min = 3) float[] out) {
|
||||
out = Asserts.assertFloat3(out);
|
||||
nGetForwardVector(getNativeObject(), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this camera's exposure (default is f/16, 1/125s, 100 ISO)
|
||||
*
|
||||
* @param aperture
|
||||
* @param shutterSpeed
|
||||
* @param sensitivity
|
||||
* The exposure ultimately controls the scene's brightness, just like with a real camera.
|
||||
* The default values provide adequate exposure for a camera placed outdoors on a sunny day
|
||||
* with the sun at the zenith.
|
||||
*
|
||||
* With the default parameters, the scene must contain at least one Light of intensity
|
||||
* similar to the sun (e.g.: a 100,000 lux directional light) and/or an indirect light
|
||||
* of appropriate intensity (30,000).
|
||||
*
|
||||
* @param aperture Aperture in f-stops, clamped between 0.5 and 64.
|
||||
* A lower aperture value increases the exposure, leading to
|
||||
* a brighter scene. Realistic values are between 0.95 and 32.
|
||||
*
|
||||
* @param shutterSpeed Shutter speed in seconds, clamped between 1/25,000 and 60.
|
||||
* A lower shutter speed increases the exposure. Realistic values are
|
||||
* between 1/8000 and 30.
|
||||
*
|
||||
* @param sensitivity Sensitivity in ISO, clamped between 10 and 204,800.
|
||||
* A higher sensitivity increases the exposure. Realistic values are
|
||||
* between 50 and 25600.
|
||||
*
|
||||
* @see LightManager
|
||||
* @see #setExposure(float)
|
||||
*/
|
||||
public void setExposure(float aperture, float shutterSpeed, float sensitivity) {
|
||||
nSetExposure(getNativeObject(), aperture, shutterSpeed, sensitivity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this camera's exposure directly. Calling this method will set the aperture
|
||||
* to 1.0, the shutter speed to 1.2 and the sensitivity will be computed to match
|
||||
* the requested exposure (for a desired exposure of 1.0, the sensitivity will be
|
||||
* set to 100 ISO).
|
||||
*
|
||||
* @return
|
||||
* This method is useful when trying to match the lighting of other engines or tools.
|
||||
* Many engines/tools use unit-less light intensities, which can be matched by setting
|
||||
* the exposure manually. This can be typically achieved by setting the exposure to
|
||||
* 1.0.
|
||||
*
|
||||
* @see LightManager
|
||||
* @see #setExposure(float, float, float)
|
||||
*/
|
||||
public void setExposure(float exposure) {
|
||||
setExposure(1.0f, 1.2f, 100.0f * (1.0f / exposure));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Aperture in f-stops
|
||||
*/
|
||||
public float getAperture() {
|
||||
return nGetAperture(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* @return Shutter speed in seconds
|
||||
*/
|
||||
public float getShutterSpeed() {
|
||||
return nGetShutterSpeed(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
* @return Sensitivity in ISO
|
||||
*/
|
||||
public float getSensitivity() {
|
||||
return nGetSensitivity(getNativeObject());
|
||||
@@ -408,7 +519,7 @@ public class Camera {
|
||||
|
||||
private static native void nSetProjection(long nativeCamera, int projection, double left, double right, double bottom, double top, double near, double far);
|
||||
private static native void nSetProjectionFov(long nativeCamera, double fovInDegrees, double aspect, double near, double far, int fov);
|
||||
private static native void nSetLensProjection(long nativeCamera, double focalLength, double near, double far);
|
||||
private static native void nSetLensProjection(long nativeCamera, double focalLength, double aspect, double near, double far);
|
||||
private static native void nSetCustomProjection(long nativeCamera, double[] inMatrix, double near, double far);
|
||||
private static native void nSetModelMatrix(long nativeCamera, float[] in);
|
||||
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
@@ -28,6 +28,9 @@ import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
/**
|
||||
* Utilities to manipulate and convert colors.
|
||||
*/
|
||||
public class Colors {
|
||||
private Colors() {
|
||||
}
|
||||
@@ -37,23 +40,67 @@ public class Colors {
|
||||
public @interface LinearColor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Types of RGB colors.
|
||||
*/
|
||||
public enum RgbType {
|
||||
/** The color is defined in sRGB space. */
|
||||
SRGB,
|
||||
|
||||
/** The color is defined in linear space. */
|
||||
LINEAR
|
||||
}
|
||||
|
||||
/**
|
||||
* Types of RGBA colors.
|
||||
*/
|
||||
public enum RgbaType {
|
||||
/**
|
||||
* The color is defined in sRGB space and the RGB values have not been premultiplied by the
|
||||
* alpha (for instance, a 50% transparent red is <1,0,0,0.5>).
|
||||
*/
|
||||
SRGB,
|
||||
|
||||
/**
|
||||
* The color is defined in linear space and the RGB values have not been premultiplied by
|
||||
* the alpha (for instance, a 50% transparent red is <1,0,0,0.5>).
|
||||
*/
|
||||
LINEAR,
|
||||
|
||||
/**
|
||||
* The color is defined in sRGB space and the RGB values have been premultiplied by the
|
||||
* alpha (for instance, a 50% transparent red is <0.5,0,0,0.5>).
|
||||
*/
|
||||
PREMULTIPLIED_SRGB,
|
||||
|
||||
/**
|
||||
* The color is defined in linear space and the RGB values have been premultiplied by the
|
||||
* alpha (for instance, a 50% transparent red is <0.5,0,0,0.5>).
|
||||
*/
|
||||
PREMULTIPLIED_LINEAR
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of color conversion to use when converting to/from sRGB and linear spaces.
|
||||
*/
|
||||
public enum Conversion {
|
||||
/** Accurate conversion using the sRGB standard. */
|
||||
ACCURATE,
|
||||
|
||||
/** Fast conversion using a simple gamma 2.2 curve. */
|
||||
FAST
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGB color to linear space, the conversion depends on the specified type.
|
||||
*
|
||||
* @param type the color space of the RGB color values provided
|
||||
* @param r the red component
|
||||
* @param g the green component
|
||||
* @param b the blue component
|
||||
*
|
||||
* @return an RGB float array of size 3 with the result of the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(3)
|
||||
@LinearColor
|
||||
@@ -61,6 +108,14 @@ public class Colors {
|
||||
return toLinear(type, new float[] { r, g, b });
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGB color to linear space, the conversion depends on the specified type.
|
||||
*
|
||||
* @param type the color space of the RGB color values provided
|
||||
* @param rgb an RGB float array of size 3, will be modified
|
||||
*
|
||||
* @return the passed-in <code>rgb</code> array, after applying the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 3)
|
||||
@LinearColor
|
||||
@@ -68,6 +123,17 @@ public class Colors {
|
||||
return (type == RgbType.LINEAR) ? rgb : toLinear(Conversion.ACCURATE, rgb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGBA color to linear space, with pre-multiplied alpha.
|
||||
*
|
||||
* @param type the color space and type of RGBA color values provided
|
||||
* @param r the red component
|
||||
* @param g the green component
|
||||
* @param b the blue component
|
||||
* @param a the alpha component
|
||||
*
|
||||
* @return an RGBA float array of size 4 with the result of the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(4)
|
||||
@LinearColor
|
||||
@@ -75,6 +141,14 @@ public class Colors {
|
||||
return toLinear(type, new float[] { r, g, b, a });
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGBA color to linear space, with pre-multiplied alpha.
|
||||
*
|
||||
* @param type the color space of the RGBA color values provided
|
||||
* @param rgba an RGBA float array of size 4, will be modified
|
||||
*
|
||||
* @return the passed-in <code>rgba</code> array, after applying the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 4)
|
||||
@LinearColor
|
||||
@@ -97,6 +171,15 @@ public class Colors {
|
||||
return rgba;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an RGB color in sRGB space to an RGB color in linear space.
|
||||
*
|
||||
* @param conversion the conversion algorithm to use
|
||||
* @param rgb an RGB float array of at least size 3, will be modified
|
||||
*
|
||||
* @return the passed-in <code>rgb</code> array, after applying the conversion. The alpha
|
||||
* channel, if present, is left unmodified.
|
||||
*/
|
||||
@NonNull
|
||||
@LinearColor
|
||||
public static float[] toLinear(@NonNull Conversion conversion, @NonNull @Size(min = 3) float[] rgb) {
|
||||
@@ -116,6 +199,14 @@ public class Colors {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a correlated color temperature to a linear RGB color in sRGB space. The temperature
|
||||
* must be expressed in Kelvin and must be in the range 1,000K to 15,000K.
|
||||
*
|
||||
* @param temperature the temperature, in Kelvin
|
||||
*
|
||||
* @return an RGB float array of size 3 with the result of the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(3)
|
||||
@LinearColor
|
||||
@@ -125,6 +216,14 @@ public class Colors {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a CIE standard illuminant series D to a linear RGB color in sRGB space. The
|
||||
* temperature must be expressed in Kelvin and must be in the range 4,000K to 25,000K.
|
||||
*
|
||||
* @param temperature the temperature, in Kelvin
|
||||
*
|
||||
* @return an RGB float array of size 3 with the result of the conversion
|
||||
*/
|
||||
@NonNull
|
||||
@Size(3)
|
||||
@LinearColor
|
||||
|
||||
@@ -16,21 +16,124 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Engine is filament's main entry-point.
|
||||
* <p>
|
||||
* An Engine instance main function is to keep track of all resources created by the user and
|
||||
* manage the rendering thread as well as the hardware renderer.
|
||||
* <p>
|
||||
* To use filament, an Engine instance must be created first:
|
||||
*
|
||||
* <pre>
|
||||
* import com.google.android.filament.*
|
||||
*
|
||||
* Engine engine = Engine.create();
|
||||
* </pre>
|
||||
* <p>
|
||||
* Engine essentially represents (or is associated to) a hardware context
|
||||
* (e.g. an OpenGL ES context).
|
||||
* <p>
|
||||
* Rendering typically happens in an operating system's window (which can be full screen), such
|
||||
* window is managed by a {@link Renderer}.
|
||||
* <p>
|
||||
* A typical filament render loop looks like this:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* import com.google.android.filament.*
|
||||
*
|
||||
* Engin engine = Engine.create();
|
||||
* SwapChain swapChain = engine.createSwapChain(nativeWindow);
|
||||
* Renderer renderer = engine.createRenderer();
|
||||
* Scene scene = engine.createScene();
|
||||
* View view = engine.createView();
|
||||
*
|
||||
* view.setScene(scene);
|
||||
*
|
||||
* do {
|
||||
* // typically we wait for VSYNC and user input events
|
||||
* if (renderer.beginFrame(swapChain)) {
|
||||
* renderer.render(view);
|
||||
* renderer.endFrame();
|
||||
* }
|
||||
* } while (!quit);
|
||||
*
|
||||
* engine.destroyView(view);
|
||||
* engine.destroyScene(scene);
|
||||
* engine.destroyRenderer(renderer);
|
||||
* engine.destroySwapChain(swapChain);
|
||||
* engine.destroy();
|
||||
* </pre>
|
||||
*
|
||||
* <h1><u>Resource Tracking</u></h1>
|
||||
* <p>
|
||||
* Each <code>Engine</code> instance keeps track of all objects created by the user, such as vertex
|
||||
* and index buffers, lights, cameras, etc...
|
||||
* The user is expected to free those resources, however, leaked resources are freed when the
|
||||
* engine instance is destroyed and a warning is emitted in the console.
|
||||
*
|
||||
* <h1><u>Thread safety</u></h1>
|
||||
* <p>
|
||||
* An <code>Engine</code> instance is not thread-safe. The implementation makes no attempt to
|
||||
* synchronize calls to an <code>Engine</code> instance methods.
|
||||
* If multi-threading is needed, synchronization must be external.
|
||||
*
|
||||
* <h1><u>Multi-threading</u></h1>
|
||||
* <p>
|
||||
* When created, the <code>Engine</code> instance starts a render thread as well as multiple worker
|
||||
* threads, these threads have an elevated priority appropriate for rendering, based on the
|
||||
* platform's best practices. The number of worker threads depends on the platform and is
|
||||
* automatically chosen for best performance.
|
||||
* <p>
|
||||
* On platforms with asymmetric cores (e.g. ARM's Big.Little), <code>Engine</code> makes some
|
||||
* educated guesses as to which cores to use for the render thread and worker threads. For example,
|
||||
* it'll try to keep an OpenGL ES thread on a Big core.
|
||||
*
|
||||
* <h1><u>Swap Chains</u></h1>
|
||||
* <p>
|
||||
* A swap chain represents an Operating System's <b>native</b> renderable surface.
|
||||
* Typically it's a window or a view. Because a {@link SwapChain} is initialized from a native
|
||||
* object, it is given to filament as an <code>Object</code>, which must be of the proper type for
|
||||
* each platform filament is running on.
|
||||
* <p>
|
||||
*
|
||||
* @see SwapChain
|
||||
* @see Renderer
|
||||
*/
|
||||
public class Engine {
|
||||
private long mNativeObject;
|
||||
@NonNull private final TransformManager mTransformManager;
|
||||
@NonNull private final LightManager mLightManager;
|
||||
@NonNull private final RenderableManager mRenderableManager;
|
||||
|
||||
/**
|
||||
* Denotes a backend
|
||||
*/
|
||||
public enum Backend {
|
||||
DEFAULT, // Automatically selects an appropriate driver for the platform.
|
||||
OPENGL, // Selects the OpenGL ES driver.
|
||||
VULKAN, // Selects the experimental Vulkan driver.
|
||||
NOOP, // Selects the no-op driver for testing purposes.
|
||||
/**
|
||||
* Automatically selects an appropriate driver for the platform.
|
||||
*/
|
||||
DEFAULT,
|
||||
/**
|
||||
* Selects the OpenGL driver (which supports OpenGL ES as well).
|
||||
*/
|
||||
OPENGL,
|
||||
/**
|
||||
* Selects the Vulkan driver if the platform supports it.
|
||||
*/
|
||||
VULKAN,
|
||||
/**
|
||||
* Selects the Metal driver if the platform supports it.
|
||||
*/
|
||||
METAL,
|
||||
/**
|
||||
* Selects the no-op driver for testing purposes.
|
||||
*/
|
||||
NOOP,
|
||||
}
|
||||
|
||||
private Engine(long nativeEngine) {
|
||||
@@ -40,6 +143,19 @@ public class Engine {
|
||||
mRenderableManager = new RenderableManager(nGetRenderableManager(nativeEngine));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Engine using the default {@link Backend}
|
||||
* <p>
|
||||
* This method is one of the few thread-safe methods.
|
||||
*
|
||||
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
|
||||
* be initialized, for instance if it doesn't support the right version of OpenGL or
|
||||
* OpenGL ES.
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if there isn't enough memory to
|
||||
* allocate the command buffer.
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create() {
|
||||
long nativeEngine = nCreateEngine(0, 0);
|
||||
@@ -47,6 +163,21 @@ public class Engine {
|
||||
return new Engine(nativeEngine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Engine using the specified {@link Backend}
|
||||
* <p>
|
||||
* This method is one of the few thread-safe methods.
|
||||
*
|
||||
* @param backend driver backend to use
|
||||
*
|
||||
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
|
||||
* be initialized, for instance if it doesn't support the right version of OpenGL or
|
||||
* OpenGL ES.
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if there isn't enough memory to
|
||||
* allocate the command buffer.
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Backend backend) {
|
||||
long nativeEngine = nCreateEngine(backend.ordinal(), 0);
|
||||
@@ -55,9 +186,21 @@ public class Engine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid shared context:
|
||||
* - Android: EGLContext
|
||||
* - Other: none
|
||||
* Creates an instance of Engine using the {@link Backend#OPENGL} and a shared OpenGL context.
|
||||
* <p>
|
||||
* This method is one of the few thread-safe methods.
|
||||
*
|
||||
* @param sharedContext A platform-dependant OpenGL context used as a shared context
|
||||
* when creating filament's internal context. On Android this parameter
|
||||
* <b>must be</b> an instance of {@link android.opengl.EGLContext}.
|
||||
*
|
||||
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
|
||||
* be initialized, for instance if it doesn't support the right version of OpenGL or
|
||||
* OpenGL ES.
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if there isn't enough memory to
|
||||
* allocate the command buffer.
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Object sharedContext) {
|
||||
@@ -70,15 +213,41 @@ public class Engine {
|
||||
throw new IllegalArgumentException("Invalid shared context " + sharedContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this <code>Engine</code> is initialized properly.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return mNativeObject != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the <code>Engine</code> instance and all associated resources.
|
||||
* <p>
|
||||
* This method is one of the few thread-safe methods.
|
||||
* <p>
|
||||
* {@link Engine#destroy()} should be called last and after all other resources have been
|
||||
* destroyed, it ensures all filament resources are freed.
|
||||
* <p>
|
||||
* <code>Destroy</code> performs the following tasks:
|
||||
* <li>Destroy all internal software and hardware resources.</li>
|
||||
* <li>Free all user allocated resources that are not already destroyed and logs a warning.
|
||||
* <p>This indicates a "leak" in the user's code.</li>
|
||||
* <li>Terminate the rendering engine's thread.</li>
|
||||
*
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
* engine.destroy();
|
||||
* </pre>
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyEngine(getNativeObject());
|
||||
clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the backend used by this <code>Engine</code>
|
||||
*/
|
||||
@NonNull
|
||||
public Backend getBackend() {
|
||||
return Backend.values()[(int) nGetBackend(getNativeObject())];
|
||||
}
|
||||
@@ -86,25 +255,36 @@ public class Engine {
|
||||
// SwapChain
|
||||
|
||||
/**
|
||||
* Valid surface types:
|
||||
* - Android: Surface
|
||||
* - Other: none
|
||||
* Creates an opaque {@link SwapChain} from the given OS native window handle.
|
||||
*
|
||||
* @param surface on Android, <b>must be</b> an instance of {@link android.view.Surface}
|
||||
*
|
||||
* @return a newly created {@link SwapChain} object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public SwapChain createSwapChain(@NonNull Object surface) {
|
||||
return createSwapChain(surface, SwapChain.CONFIG_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid surface types:
|
||||
* - Android: Surface
|
||||
* - Other: none
|
||||
* Creates a {@link SwapChain} from the given OS native window handle.
|
||||
*
|
||||
* Flags: see CONFIG flags in SwapChain.
|
||||
* @param surface on Android, <b>must be</b> an instance of {@link android.view.Surface}
|
||||
*
|
||||
* @param flags configuration flags, see {@link SwapChain}
|
||||
*
|
||||
* @return a newly created {@link SwapChain} object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
|
||||
*
|
||||
* @see SwapChain#CONFIG_DEFAULT
|
||||
* @see SwapChain#CONFIG_TRANSPARENT
|
||||
* @see SwapChain#CONFIG_READABLE
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public SwapChain createSwapChain(@NonNull Object surface, long flags) {
|
||||
if (Platform.get().validateSurface(surface)) {
|
||||
long nativeSwapChain = nCreateSwapChain(getNativeObject(), surface, flags);
|
||||
@@ -114,6 +294,44 @@ public class Engine {
|
||||
throw new IllegalArgumentException("Invalid surface " + surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a headless {@link SwapChain}
|
||||
*
|
||||
* @param width width of the rendering buffer
|
||||
* @param height height of the rendering buffer
|
||||
* @param flags configuration flags, see {@link SwapChain}
|
||||
*
|
||||
* @return a newly created {@link SwapChain} object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
|
||||
*
|
||||
* @see SwapChain#CONFIG_DEFAULT
|
||||
* @see SwapChain#CONFIG_TRANSPARENT
|
||||
* @see SwapChain#CONFIG_READABLE
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public SwapChain createSwapChain(int width, int height, long flags) {
|
||||
if (width >= 0 && height >= 0) {
|
||||
long nativeSwapChain = nCreateSwapChainHeadless(getNativeObject(), width, height, flags);
|
||||
if (nativeSwapChain == 0) throw new IllegalStateException("Couldn't create SwapChain");
|
||||
return new SwapChain(nativeSwapChain, null);
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid parameters");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SwapChain} from a {@link NativeSurface}.
|
||||
*
|
||||
* @param surface a properly initialized {@link NativeSurface}
|
||||
*
|
||||
* @param flags configuration flags, see {@link SwapChain}
|
||||
*
|
||||
* @return a newly created {@link SwapChain} object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the {@link SwapChain} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public SwapChain createSwapChainFromNativeSurface(@NonNull NativeSurface surface, long flags) {
|
||||
long nativeSwapChain =
|
||||
nCreateSwapChainFromRawPointer(getNativeObject(), surface.getNativeObject(), flags);
|
||||
@@ -121,6 +339,10 @@ public class Engine {
|
||||
return new SwapChain(nativeSwapChain, surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link SwapChain} and frees all its associated resources.
|
||||
* @param swapChain the {@link SwapChain} to destroy
|
||||
*/
|
||||
public void destroySwapChain(@NonNull SwapChain swapChain) {
|
||||
nDestroySwapChain(getNativeObject(), swapChain.getNativeObject());
|
||||
swapChain.clearNativeObject();
|
||||
@@ -128,6 +350,11 @@ public class Engine {
|
||||
|
||||
// View
|
||||
|
||||
/**
|
||||
* Creates a {@link View}.
|
||||
* @return a newly created {@link View}
|
||||
* @exception IllegalStateException can be thrown if the {@link View} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public View createView() {
|
||||
long nativeView = nCreateView(getNativeObject());
|
||||
@@ -135,6 +362,10 @@ public class Engine {
|
||||
return new View(nativeView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link View} and frees all its associated resources.
|
||||
* @param view the {@link View} to destroy
|
||||
*/
|
||||
public void destroyView(@NonNull View view) {
|
||||
nDestroyView(getNativeObject(), view.getNativeObject());
|
||||
view.clearNativeObject();
|
||||
@@ -142,6 +373,11 @@ public class Engine {
|
||||
|
||||
// Renderer
|
||||
|
||||
/**
|
||||
* Creates a {@link Renderer}.
|
||||
* @return a newly created {@link Renderer}
|
||||
* @exception IllegalStateException can be thrown if the {@link Renderer} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Renderer createRenderer() {
|
||||
long nativeRenderer = nCreateRenderer(getNativeObject());
|
||||
@@ -149,6 +385,10 @@ public class Engine {
|
||||
return new Renderer(this, nativeRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Renderer} and frees all its associated resources.
|
||||
* @param renderer the {@link Renderer} to destroy
|
||||
*/
|
||||
public void destroyRenderer(@NonNull Renderer renderer) {
|
||||
nDestroyRenderer(getNativeObject(), renderer.getNativeObject());
|
||||
renderer.clearNativeObject();
|
||||
@@ -156,6 +396,12 @@ public class Engine {
|
||||
|
||||
// Camera
|
||||
|
||||
/**
|
||||
* Creates a new <code>entity</code> and adds a {@link Camera} component to it.
|
||||
*
|
||||
* @return A newly created {@link Camera}
|
||||
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera() {
|
||||
long nativeCamera = nCreateCamera(getNativeObject());
|
||||
@@ -163,6 +409,13 @@ public class Engine {
|
||||
return new Camera(nativeCamera);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a {@link Camera} component to a given <code>entity</code>.
|
||||
*
|
||||
* @param entity <code>entity</code> to add the camera component to
|
||||
* @return A newly created {@link Camera}
|
||||
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera(@Entity int entity) {
|
||||
long nativeCamera = nCreateCameraWithEntity(getNativeObject(), entity);
|
||||
@@ -170,6 +423,10 @@ public class Engine {
|
||||
return new Camera(nativeCamera);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Camera} component and frees all its associated resources.
|
||||
* @param camera the {@link Camera} to destroy
|
||||
*/
|
||||
public void destroyCamera(@NonNull Camera camera) {
|
||||
nDestroyCamera(getNativeObject(), camera.getNativeObject());
|
||||
camera.clearNativeObject();
|
||||
@@ -177,6 +434,11 @@ public class Engine {
|
||||
|
||||
// Scene
|
||||
|
||||
/**
|
||||
* Creates a {@link Scene}.
|
||||
* @return a newly created {@link Scene}
|
||||
* @exception IllegalStateException can be thrown if the {@link Scene} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Scene createScene() {
|
||||
long nativeScene = nCreateScene(getNativeObject());
|
||||
@@ -184,6 +446,10 @@ public class Engine {
|
||||
return new Scene(nativeScene);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Scene} and frees all its associated resources.
|
||||
* @param scene the {@link Scene} to destroy
|
||||
*/
|
||||
public void destroyScene(@NonNull Scene scene) {
|
||||
nDestroyScene(getNativeObject(), scene.getNativeObject());
|
||||
scene.clearNativeObject();
|
||||
@@ -191,6 +457,10 @@ public class Engine {
|
||||
|
||||
// Stream
|
||||
|
||||
/**
|
||||
* Destroys a {@link Stream} and frees all its associated resources.
|
||||
* @param stream the {@link Stream} to destroy
|
||||
*/
|
||||
public void destroyStream(@NonNull Stream stream) {
|
||||
nDestroyStream(getNativeObject(), stream.getNativeObject());
|
||||
stream.clearNativeObject();
|
||||
@@ -198,13 +468,22 @@ public class Engine {
|
||||
|
||||
// Fence
|
||||
|
||||
/**
|
||||
* Creates a {@link Fence}.
|
||||
* @return a newly created {@link Fence}
|
||||
* @exception IllegalStateException can be thrown if the {@link Fence} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Fence createFence(@NonNull Fence.Type type) {
|
||||
long nativeFence = nCreateFence(getNativeObject(), type.ordinal());
|
||||
public Fence createFence() {
|
||||
long nativeFence = nCreateFence(getNativeObject());
|
||||
if (nativeFence == 0) throw new IllegalStateException("Couldn't create Fence");
|
||||
return new Fence(nativeFence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Fence} and frees all its associated resources.
|
||||
* @param fence the {@link Fence} to destroy
|
||||
*/
|
||||
public void destroyFence(@NonNull Fence fence) {
|
||||
nDestroyFence(getNativeObject(), fence.getNativeObject());
|
||||
fence.clearNativeObject();
|
||||
@@ -212,69 +491,135 @@ public class Engine {
|
||||
|
||||
// others...
|
||||
|
||||
/**
|
||||
* Destroys a {@link IndexBuffer} and frees all its associated resources.
|
||||
* @param indexBuffer the {@link IndexBuffer} to destroy
|
||||
*/
|
||||
public void destroyIndexBuffer(@NonNull IndexBuffer indexBuffer) {
|
||||
nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject());
|
||||
indexBuffer.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link VertexBuffer} and frees all its associated resources.
|
||||
* @param vertexBuffer the {@link VertexBuffer} to destroy
|
||||
*/
|
||||
public void destroyVertexBuffer(@NonNull VertexBuffer vertexBuffer) {
|
||||
nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject());
|
||||
vertexBuffer.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link IndirectLight} and frees all its associated resources.
|
||||
* @param ibl the {@link IndirectLight} to destroy
|
||||
*/
|
||||
public void destroyIndirectLight(@NonNull IndirectLight ibl) {
|
||||
nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject());
|
||||
ibl.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Material} and frees all its associated resources.
|
||||
* <p>
|
||||
* All {@link MaterialInstance} of the specified {@link Material} must be destroyed before
|
||||
* destroying it; if some {@link MaterialInstance} remain, this method fails silently.
|
||||
*
|
||||
* @param material the {@link Material} to destroy
|
||||
*/
|
||||
public void destroyMaterial(@NonNull Material material) {
|
||||
nDestroyMaterial(getNativeObject(), material.getNativeObject());
|
||||
material.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link MaterialInstance} and frees all its associated resources.
|
||||
* @param materialInstance the {@link MaterialInstance} to destroy
|
||||
*/
|
||||
public void destroyMaterialInstance(@NonNull MaterialInstance materialInstance) {
|
||||
nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject());
|
||||
materialInstance.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Skybox} and frees all its associated resources.
|
||||
* @param skybox the {@link Skybox} to destroy
|
||||
*/
|
||||
public void destroySkybox(@NonNull Skybox skybox) {
|
||||
nDestroySkybox(getNativeObject(), skybox.getNativeObject());
|
||||
skybox.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Texture} and frees all its associated resources.
|
||||
* @param texture the {@link Texture} to destroy
|
||||
*/
|
||||
public void destroyTexture(@NonNull Texture texture) {
|
||||
nDestroyTexture(getNativeObject(), texture.getNativeObject());
|
||||
texture.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link RenderTarget} and frees all its associated resources.
|
||||
* @param target the {@link RenderTarget} to destroy
|
||||
*/
|
||||
public void destroyRenderTarget(@NonNull RenderTarget target) {
|
||||
nDestroyRenderTarget(getNativeObject(), target.getNativeObject());
|
||||
target.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys an <code>entity</code> and all its components.
|
||||
* <p>
|
||||
* It is recommended to destroy components individually before destroying their
|
||||
* <code>entity</code>, this gives more control as to when the destruction really happens.
|
||||
* Otherwise, orphaned components are garbage collected, which can happen at a later time.
|
||||
* Even when component are garbage collected, the destruction of their <code>entity</code>
|
||||
* terminates their participation immediately.
|
||||
*
|
||||
* @param entity the <code>entity</code> to destroy
|
||||
*/
|
||||
public void destroyEntity(@Entity int entity) {
|
||||
nDestroyEntity(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
// Managers
|
||||
|
||||
/**
|
||||
* @return the {@link TransformManager} used by this {@link Engine}
|
||||
*/
|
||||
@NonNull
|
||||
public TransformManager getTransformManager() {
|
||||
return mTransformManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link LightManager} used by this {@link Engine}
|
||||
*/
|
||||
@NonNull
|
||||
public LightManager getLightManager() {
|
||||
return mLightManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link RenderableManager} used by this {@link Engine}
|
||||
*/
|
||||
@NonNull
|
||||
public RenderableManager getRenderableManager() {
|
||||
return mRenderableManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g.: the OpenGL, Vulkan or Metal thread) and blocks until
|
||||
* all commands to this point are executed. Note that this doesn't guarantee that the
|
||||
* hardware is actually finished.
|
||||
*
|
||||
* <p>This is typically used right after destroying the <code>SwapChain</code>,
|
||||
* in cases where a guarantee about the SwapChain destruction is needed in a timely fashion,
|
||||
* such as when responding to Android's
|
||||
* {@link android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed}.</p>
|
||||
*/
|
||||
public void flushAndWait() {
|
||||
Fence.waitAndDestroy(createFence(Fence.Type.HARD), Fence.Mode.FLUSH);
|
||||
nFlushAndWait(getNativeObject());
|
||||
}
|
||||
|
||||
@UsedByReflection("TextureHelper.java")
|
||||
@@ -293,6 +638,7 @@ public class Engine {
|
||||
private static native void nDestroyEngine(long nativeEngine);
|
||||
private static native long nGetBackend(long nativeEngine);
|
||||
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
|
||||
private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags);
|
||||
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
|
||||
private static native void nDestroySwapChain(long nativeEngine, long nativeSwapChain);
|
||||
private static native long nCreateView(long nativeEngine);
|
||||
@@ -304,7 +650,7 @@ public class Engine {
|
||||
private static native void nDestroyCamera(long nativeEngine, long nativeCamera);
|
||||
private static native long nCreateScene(long nativeEngine);
|
||||
private static native void nDestroyScene(long nativeEngine, long nativeScene);
|
||||
private static native long nCreateFence(long nativeEngine, int fenceType);
|
||||
private static native long nCreateFence(long nativeEngine);
|
||||
private static native void nDestroyFence(long nativeEngine, long nativeFence);
|
||||
private static native void nDestroyStream(long nativeEngine, long nativeStream);
|
||||
private static native void nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||
@@ -316,6 +662,7 @@ public class Engine {
|
||||
private static native void nDestroyTexture(long nativeEngine, long nativeTexture);
|
||||
private static native void nDestroyRenderTarget(long nativeEngine, long nativeTarget);
|
||||
private static native void nDestroyEntity(long nativeEngine, int entity);
|
||||
private static native void nFlushAndWait(long nativeEngine);
|
||||
private static native long nGetTransformManager(long nativeEngine);
|
||||
private static native long nGetLightManager(long nativeEngine);
|
||||
private static native long nGetRenderableManager(long nativeEngine);
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
public class EntityManager {
|
||||
private long mNativeObject = nGetEntityManager();
|
||||
|
||||
@@ -15,7 +15,7 @@ package com.google.android.filament;
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class Fence {
|
||||
private long mNativeObject;
|
||||
@@ -26,11 +26,6 @@ public class Fence {
|
||||
|
||||
public static final long WAIT_FOR_EVER = -1;
|
||||
|
||||
public enum Type {
|
||||
SOFT,
|
||||
HARD
|
||||
}
|
||||
|
||||
public enum Mode {
|
||||
FLUSH,
|
||||
DONT_FLUSH
|
||||
@@ -42,6 +37,9 @@ public class Fence {
|
||||
TIMEOUT_EXPIRED
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks the current thread until the Fence signals.
|
||||
*/
|
||||
public FenceStatus wait(@NonNull Mode mode, long timeoutNanoSeconds) {
|
||||
int nativeResult = nWait(getNativeObject(), mode.ordinal(), timeoutNanoSeconds);
|
||||
switch (nativeResult) {
|
||||
|
||||
@@ -16,13 +16,24 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
/**
|
||||
* A buffer containing vertex indices into a <code>VertexBuffer</code>. Indices can be 16 or 32 bit.
|
||||
* The buffer itself is a GPU resource, therefore mutating the data can be relatively slow.
|
||||
* Typically these buffers are constant.
|
||||
*
|
||||
* It is possible, and even encouraged, to use a single index buffer for several
|
||||
* <code>Renderables</code>.
|
||||
*
|
||||
* @see VertexBuffer
|
||||
* @see RenderableManager
|
||||
*/
|
||||
public class IndexBuffer {
|
||||
private long mNativeObject;
|
||||
|
||||
@@ -36,8 +47,14 @@ public class IndexBuffer {
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
/**
|
||||
* Type of the index buffer.
|
||||
*/
|
||||
public enum IndexType {
|
||||
/** 16-bit indices */
|
||||
USHORT,
|
||||
|
||||
/** 32-bit indices */
|
||||
UINT,
|
||||
}
|
||||
|
||||
@@ -46,18 +63,45 @@ public class IndexBuffer {
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the index buffer in elements.
|
||||
*
|
||||
* @param indexCount number of indices the <code>IndexBuffer</code> can hold
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder indexCount(@IntRange(from = 1) int indexCount) {
|
||||
nBuilderIndexCount(mNativeBuilder, indexCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of the index buffer, 16-bit or 32-bit.
|
||||
*
|
||||
* @param indexType type of indices stored in the <code>IndexBuffer</code>
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder bufferType(@NonNull IndexType indexType) {
|
||||
nBuilderBufferType(mNativeBuilder, indexType.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>IndexBuffer</code> object. After creation, the index buffer
|
||||
* is uninitialized. Use {@link #setBuffer} to initialized the <code>IndexBuffer</code>.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>IndexBuffer</code>
|
||||
* with
|
||||
*
|
||||
* @return the newly created <code>IndexBuffer</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the IndexBuffer could not be created
|
||||
*
|
||||
* @see #setBuffer
|
||||
*/
|
||||
@NonNull
|
||||
public IndexBuffer build(@NonNull Engine engine) {
|
||||
long nativeIndexBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -85,24 +129,69 @@ public class IndexBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this <code>IndexBuffer</code> in elements.
|
||||
*
|
||||
* @return the number of indices the <code>IndexBuffer</code> holds
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getIndexCount() {
|
||||
return nGetIndexCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes this <code>IndexBuffer</code> from the data provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>IndexBuffer</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>IndexBuffer</code>. <code>buffer</code> should contain raw,
|
||||
* untyped data that will be interpreted as either 16-bit or 32-bits
|
||||
* indices based on the <code>IndexType</code> of this
|
||||
* <code>IndexBuffer</code>.
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer) {
|
||||
setBuffer(engine, buffer, 0, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes a region of this <code>IndexBuffer</code> from the data
|
||||
* provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>IndexBuffer</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>IndexBuffer</code>. <code>buffer</code> should contain raw,
|
||||
* untyped data that will be interpreted as either 16-bit or 32-bits
|
||||
* indices based on the <code>IndexType</code> of this
|
||||
* <code>IndexBuffer</code>.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>IndexBuffer</code>
|
||||
* @param count number of buffer elements to consume, defaults to
|
||||
* <code>buffer.remaining()</code>
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count) {
|
||||
setBuffer(engine, buffer, destOffsetInBytes, count, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid handler types:
|
||||
* - Android: Handler, Executor
|
||||
* - Other: Executor
|
||||
* Asynchronously copy-initializes a region of this <code>IndexBuffer</code> from the data
|
||||
* provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>IndexBuffer</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>IndexBuffer</code>. <code>buffer</code> should contain raw,
|
||||
* untyped data that will be interpreted as either 16-bit or 32-bits
|
||||
* indices based on the <code>IndexType</code> of this
|
||||
* <code>IndexBuffer</code>.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>IndexBuffer</code>
|
||||
* @param count number of buffer elements to consume, defaults to
|
||||
* <code>buffer.remaining()</code>
|
||||
* @param handler an {@link java.util.concurrent.Executor Executor}. On Android this
|
||||
* can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback a callback executed by <code>handler</code> when <code>buffer</code>
|
||||
* is no longer needed.
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count,
|
||||
|
||||
@@ -16,37 +16,171 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
|
||||
/**
|
||||
* <code>IndirectLight</code> is used to simulate environment lighting, a form of global illumination.
|
||||
*
|
||||
* <p>Environment lighting has a two components:</p>
|
||||
* <ol>
|
||||
* <li>irradiance</li>
|
||||
* <li>reflections (specular component)</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>Environments are usually captured as high-resolution HDR equirectangular images and processed
|
||||
* by the <b>cmgen</b> tool to generate the data needed by {@link IndirectLight}.</p>
|
||||
*
|
||||
* <p>Currently {@link IndirectLight} is intended to be used for "distant probes", that is, to represent
|
||||
* global illumination from a distant (i.e. at infinity) environment, such as the sky or distant
|
||||
* mountains. Only a single {@link IndirectLight} can be used in a {@link Scene}.
|
||||
* This limitation will be lifted in the future.</p>
|
||||
*
|
||||
*
|
||||
* <h1>Creation and destruction</h1>
|
||||
*
|
||||
* <p>An {@link IndirectLight} object is created using the {@link IndirectLight.Builder} and
|
||||
* destroyed by calling {@link Engine#destroyIndirectLight}.</p>
|
||||
*
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
*
|
||||
* Scene scene = engine.createScene();
|
||||
*
|
||||
* IndirectLight environment = new IndirectLight.Builder()
|
||||
* .reflections(cubemap)
|
||||
* .irradiance(numBands, sphericalHarmonicsCoefficients)
|
||||
* .build(engine);
|
||||
*
|
||||
* scene.setIndirectLight(environment);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <h1>Irradiance</h1>
|
||||
*
|
||||
* <p>The irradiance represents the light that comes from the environment and shines an
|
||||
* object's surface.
|
||||
* The irradiance is calculated automatically from the Reflections (see below), and generally
|
||||
* doesn't need to be provided explicitly. However, it can be provided separately from the
|
||||
* Reflections as
|
||||
* <a href="https://en.wikipedia.org/wiki/Spherical_harmonics">Spherical Harmonics</a> (SH) of 1, 2 or
|
||||
* 3 bands, respectively 1, 4 or 9 coefficients.</p>
|
||||
*
|
||||
* <p>Use the <b>cmgen</b> tool to generate the Spherical Harmonics for a given environment.</p>
|
||||
*
|
||||
*
|
||||
* <h1>Reflections</h1>
|
||||
*
|
||||
* <p>The reflections on object surfaces (specular component) is calculated from a specially
|
||||
* filtered cubemap pyramid generated by the <b>cmgen</b> tool.</p>
|
||||
*
|
||||
* @see Scene
|
||||
* @see LightManager
|
||||
* @see Texture
|
||||
* @see Skybox
|
||||
*/
|
||||
public class IndirectLight {
|
||||
long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
IndirectLight(long indirectLight) {
|
||||
public IndirectLight(long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct an <code>IndirectLight</code> object instance.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct an <code>IndirectLight</code> object instance.
|
||||
*/
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the reflections cubemap mipmap chain.
|
||||
*
|
||||
* @param cubemap A mip-mapped cubemap generated by <b>cmgen</b>. Each cubemap level
|
||||
* encodes the irradiance for a roughness level.
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
*/
|
||||
@NonNull
|
||||
public Builder reflections(@NonNull Texture cubemap) {
|
||||
nBuilderReflections(mNativeBuilder, cubemap.getNativeObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the irradiance as Spherical Harmonics.
|
||||
*
|
||||
* <p>The irradiance coefficients must be pre-convolved by <code>< n &sdot l ></code> and
|
||||
* pre-multiplied by the Lambertian diffuse BRDF <code>1/&pi</code> and
|
||||
* specified as Spherical Harmonics coefficients.</p>
|
||||
*
|
||||
* <p>Additionally, these Spherical Harmonics coefficients must be pre-scaled by the
|
||||
* reconstruction factors A<sup>l,m</sup>.</p>
|
||||
*
|
||||
* <p>The final coefficients can be generated using the <code>cmgen</code> tool.</p>
|
||||
*
|
||||
* <p>The index in the <code>sh</code> array is given by:
|
||||
* <br><code>index(l, m) = 3 × (l * (l + 1) + m)</code>
|
||||
* <br><code>sh[index(l,m) + 0] = L<sub>R</sub><sup>l,m</sup>
|
||||
* × 1/&pi
|
||||
* × A<sup>l,m</sup>
|
||||
* × C<sup>l</sup> </code>
|
||||
* <br><code>sh[index(l,m) + 1] = L<sub>G</sub><sup>l,m</sup>
|
||||
* × 1/&pi
|
||||
* × A<sup>l,m</sup>
|
||||
* × C<sup>l</sup> </code>
|
||||
* <br><code>sh[index(l,m) + 2] = L<sub>B</sub><sup>l,m</sup>
|
||||
* × 1/&pi
|
||||
* × A<sup>l,m</sup>
|
||||
* × C<sup>l</sup> </code>
|
||||
* </p>
|
||||
*
|
||||
* <center>
|
||||
* <table border="1" cellpadding="3">
|
||||
* <tr><th> index </th><th> l </th><th> m </th><th> A<sup>l,m</sup> </th><th> C<sup>l</sup> </th>
|
||||
* <th> 1/&pi × A<sup>l,m</sup> × C<sup>l</sup></th></tr>
|
||||
* <tr align="right"><td>0</td><td>0</td><td> 0</td><td> 0.282095</td><td>3.1415926</td><td> 0.282095</td></tr>
|
||||
* <tr align="right"><td>1</td><td>1</td><td>-1</td><td>-0.488602</td><td>2.0943951</td><td>-0.325735</td></tr>
|
||||
* <tr align="right"><td>2</td><td>1</td><td> 0</td><td> 0.488602</td><td>2.0943951</td><td> 0.325735</td></tr>
|
||||
* <tr align="right"><td>3</td><td>1</td><td> 1</td><td>-0.488602</td><td>2.0943951</td><td>-0.325735</td></tr>
|
||||
* <tr align="right"><td>4</td><td>2</td><td>-2</td><td> 1.092548</td><td>0.785398 </td><td> 0.273137</td></tr>
|
||||
* <tr align="right"><td>5</td><td>2</td><td>-1</td><td>-1.092548</td><td>0.785398 </td><td>-0.273137</td></tr>
|
||||
* <tr align="right"><td>6</td><td>2</td><td> 0</td><td> 0.315392</td><td>0.785398 </td><td> 0.078848</td></tr>
|
||||
* <tr align="right"><td>7</td><td>2</td><td> 1</td><td>-1.092548</td><td>0.785398 </td><td>-0.273137</td></tr>
|
||||
* <tr align="right"><td>8</td><td>2</td><td> 2</td><td> 0.546274</td><td>0.785398 </td><td> 0.136569</td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
*
|
||||
*
|
||||
* <p>Only 1, 2 or 3 bands are allowed.</p>
|
||||
*
|
||||
* <p>Because the coefficients are pre-scaled, <code>sh[0]</code> is the environment's
|
||||
* average irradiance.</p>
|
||||
*
|
||||
* @param bands Number of spherical harmonics bands. Must be 1, 2 or 3.
|
||||
* @param sh Array containing the spherical harmonics coefficients.
|
||||
* The size of the array must be <code>3 × bands<sup>2</sup></code>
|
||||
* (i.e. 1, 4 or 9 <code>float3</code> coefficients respectively).
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
* @exception ArrayIndexOutOfBoundsException if the <code>sh</code> array length is smaller
|
||||
* than 3 × bands<sup>2</sup>
|
||||
*/
|
||||
@NonNull
|
||||
public Builder irradiance(@IntRange(from=1, to=3) int bands, @NonNull float[] sh) {
|
||||
switch (bands) {
|
||||
@@ -65,6 +199,44 @@ public class IndirectLight {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the irradiance from the radiance expressed as Spherical Harmonics.
|
||||
*
|
||||
* <p>The radiance must be specified as Spherical Harmonics coefficients L<sup>l,m</sup>, where
|
||||
* each coefficient is comprised of three floats for red, green and blue components, respectively</p>
|
||||
*
|
||||
* <p>The index in the <code>sh</code> array is given by:
|
||||
* <br><code>index(l, m) = 3 × (l * (l + 1) + m)</code>
|
||||
* <br><code>sh[index(l,m) + 0] = L<sub>R</sub><sup>l,m</sup></code>
|
||||
* <br><code>sh[index(l,m) + 1] = L<sub>G</sub><sup>l,m</sup></code>
|
||||
* <br><code>sh[index(l,m) + 2] = L<sub>B</sub><sup>l,m</sup></code>
|
||||
* </p>
|
||||
*
|
||||
* <center>
|
||||
* <table border="1" cellpadding="3">
|
||||
* <tr><th> index </th><th> l </th><th> m </th>
|
||||
* <tr align="right"><td>0</td><td>0</td><td> 0</td>
|
||||
* <tr align="right"><td>1</td><td>1</td><td>-1</td>
|
||||
* <tr align="right"><td>2</td><td>1</td><td> 0</td>
|
||||
* <tr align="right"><td>3</td><td>1</td><td> 1</td>
|
||||
* <tr align="right"><td>4</td><td>2</td><td>-2</td>
|
||||
* <tr align="right"><td>5</td><td>2</td><td>-1</td>
|
||||
* <tr align="right"><td>6</td><td>2</td><td> 0</td>
|
||||
* <tr align="right"><td>7</td><td>2</td><td> 1</td>
|
||||
* <tr align="right"><td>8</td><td>2</td><td> 2</td>
|
||||
* </table>
|
||||
* </center>
|
||||
*
|
||||
* @param bands Number of spherical harmonics bands. Must be 1, 2 or 3.
|
||||
* @param sh Array containing the spherical harmonics coefficients.
|
||||
* The size of the array must be 3 × <code>bands<sup>2</sup></code>
|
||||
* (i.e. 1, 4 or 9 <code>float3</code> coefficients respectively).
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
* @exception ArrayIndexOutOfBoundsException if the <code>sh</code> array length is smaller
|
||||
* than 3 × bands<sup>2</sup>
|
||||
*/
|
||||
@NonNull
|
||||
public Builder radiance(@IntRange(from=1, to=3) int bands, @NonNull float[] sh) {
|
||||
switch (bands) {
|
||||
@@ -83,18 +255,52 @@ public class IndirectLight {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the irradiance as a cubemap.
|
||||
* <p></p>
|
||||
* The irradiance can alternatively be specified as a cubemap instead of Spherical
|
||||
* Harmonics coefficients. It may or may not be more efficient, depending on your
|
||||
* hardware (essentially, it's trading ALU for bandwidth).
|
||||
* <p></p>
|
||||
* This irradiance cubemap can be generated with the <code>cmgen</code> tool.
|
||||
*
|
||||
* @param cubemap Cubemap representing the Irradiance pre-convolved by
|
||||
* <code>< n &sdot l ></code>.
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
* @see #irradiance(int bands, float[] sh)
|
||||
*/
|
||||
@NonNull
|
||||
public Builder irradiance(@NonNull Texture cubemap) {
|
||||
nIrradianceAsTexture(mNativeBuilder, cubemap.getNativeObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment intensity (optional).
|
||||
*
|
||||
* <p>Because the environment is encoded usually relative to some reference, the
|
||||
* range can be adjusted with this method.</p>
|
||||
*
|
||||
* @param envIntensity Scale factor applied to the environment and irradiance such that
|
||||
* the result is in cd/m^2 (lux) units (default = 30000)
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder intensity(float envIntensity) {
|
||||
nIntensity(mNativeBuilder, envIntensity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the rigid-body transformation to apply to the IBL.
|
||||
*
|
||||
* @param rotation 3x3 rotation matrix. Must be a rigid-body transform.
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder rotation(@NonNull @Size(min = 9) float[] rotation) {
|
||||
nRotation(mNativeBuilder,
|
||||
@@ -104,6 +310,15 @@ public class IndirectLight {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the IndirectLight object and returns a pointer to it.
|
||||
*
|
||||
* @param engine The {@link Engine} to associate this <code>IndirectLight</code> with.
|
||||
*
|
||||
* @return A newly created <code>IndirectLight</code>
|
||||
*
|
||||
* @exception IllegalStateException if a parameter to a builder function was invalid.
|
||||
*/
|
||||
@NonNull
|
||||
public IndirectLight build(@NonNull Engine engine) {
|
||||
long nativeIndirectLight = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -128,14 +343,31 @@ public class IndirectLight {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the environment's intensity.
|
||||
*
|
||||
* <p>Because the environment is encoded usually relative to some reference, the
|
||||
* range can be adjusted with this method.</p>
|
||||
*
|
||||
* @param intensity Scale factor applied to the environment and irradiance such that
|
||||
* the result is in cd/m^2 units (default = 30000)
|
||||
*/
|
||||
public void setIntensity(float intensity) {
|
||||
nSetIntensity(getNativeObject(), intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment's intensity in cd/m<sup>2</sup>.
|
||||
*/
|
||||
public float getIntensity() {
|
||||
return nGetIntensity(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rigid-body transformation to apply to the IBL.
|
||||
*
|
||||
* @param rotation 3x3 rotation matrix. Must be a rigid-body transform.
|
||||
*/
|
||||
public void setRotation(@NonNull @Size(min = 9) float[] rotation) {
|
||||
Asserts.assertMat3fIn(rotation);
|
||||
nSetRotation(getNativeObject(),
|
||||
@@ -144,6 +376,14 @@ public class IndirectLight {
|
||||
rotation[6], rotation[7], rotation[8]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rigid-body transformation applied to the IBL.
|
||||
*
|
||||
* @param rotation an array of 9 floats to receive the rigid-body transformation applied to
|
||||
* the IBL or <code>null</code>
|
||||
* @return the <code>rotation</code> paramter if it was provided, or a newly allocated float
|
||||
* array containing the rigid-body transformation applied to the IBL
|
||||
*/
|
||||
@NonNull @Size(min = 9)
|
||||
public float[] getRotation(@Nullable @Size(min = 9) float[] rotation) {
|
||||
rotation = Asserts.assertMat3f(rotation);
|
||||
@@ -151,6 +391,41 @@ public class IndirectLight {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to estimate the direction of the dominant light in the environment.
|
||||
*
|
||||
* <p>This assumes that there is only a single dominant light (such as the sun in outdoors
|
||||
* environments), if it's not the case the direction returned will be an average of the
|
||||
* various lights based on their intensity.</p>
|
||||
*
|
||||
* <p>If there are no clear dominant light, as is often the case with low dynamic range (LDR)
|
||||
* environments, this method may return a wrong or unexpected direction.</p>
|
||||
*
|
||||
* <p>The dominant light direction can be used to set a directional light's direction,
|
||||
* for instance to produce shadows that match the environment.</p>
|
||||
*
|
||||
* @param sh pre-scaled 3-bands spherical harmonics
|
||||
* @param direction an array of 3 floats to receive a unit vector representing the direction of
|
||||
* the dominant light or <code>null</code>
|
||||
* @return the <code>direction</code> paramter if it was provided, or a newly allocated float
|
||||
* array containing a unit vector representing the direction of the dominant light
|
||||
*
|
||||
* @see LightManager.Builder#direction
|
||||
* @see #getColorEstimate
|
||||
*/
|
||||
|
||||
@NonNull @Size(min = 3)
|
||||
public static float[] getDirectionEstimate(@NonNull float[] sh, @Nullable @Size(min = 3) float[] direction) {
|
||||
if (sh.length < 9 * 3) {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
"3 bands SH required, array must be at least 9 x float3");
|
||||
}
|
||||
direction = Asserts.assertFloat3(direction);
|
||||
nGetDirectionEstimateStatic(sh, direction);
|
||||
return direction;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getDirectionEstimate(@Nullable @Size(min = 3) float[] direction) {
|
||||
direction = Asserts.assertFloat3(direction);
|
||||
@@ -158,6 +433,41 @@ public class IndirectLight {
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to estimate the color and relative intensity of the environment in a given direction.
|
||||
*
|
||||
* <p>This can be used to set the color and intensity of a directional light. In this case
|
||||
* make sure to multiply this relative intensity by the the intensity of this indirect light.</p>
|
||||
*
|
||||
* @param colorIntensity an array of 4 floats to receive the result or <code>null</code>
|
||||
* @param sh pre-scaled 3-bands spherical harmonics
|
||||
* @param x the x coordinate of a unit vector representing the direction of the light
|
||||
* @param y the x coordinate of a unit vector representing the direction of the light
|
||||
* @param z the x coordinate of a unit vector representing the direction of the light
|
||||
*
|
||||
* @return A vector of 4 floats where the first 3 components represent the linear color and
|
||||
* the 4th component represents the intensity of the dominant light
|
||||
*
|
||||
* @see LightManager.Builder#color
|
||||
* @see LightManager.Builder#intensity
|
||||
* @see #getDirectionEstimate
|
||||
* @see #getIntensity
|
||||
* @see #setIntensity
|
||||
*/
|
||||
@NonNull @Size(min = 4)
|
||||
public static float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, @NonNull float[] sh, float x, float y, float z) {
|
||||
if (sh.length < 9 * 3) {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
"3 bands SH required, array must be at least 9 x float3");
|
||||
}
|
||||
colorIntensity = Asserts.assertFloat4(colorIntensity);
|
||||
nGetColorEstimateStatic(colorIntensity, sh, x, y, z);
|
||||
return colorIntensity;
|
||||
}
|
||||
|
||||
|
||||
/** @deprecated */
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, float x, float y, float z) {
|
||||
colorIntensity = Asserts.assertFloat4(colorIntensity);
|
||||
@@ -193,4 +503,7 @@ public class IndirectLight {
|
||||
private static native void nGetRotation(long nativeIndirectLight, float[] outRotation);
|
||||
private static native void nGetDirectionEstimate(long nativeIndirectLight, float[] outDirection);
|
||||
private static native void nGetColorEstimate(long nativeIndirectLight, float[] outColor, float x, float y, float z);
|
||||
|
||||
private static native void nGetDirectionEstimateStatic(float[] sh, float[] direction);
|
||||
private static native void nGetColorEstimateStatic(float[] colorIntensity, float[] sh, float x, float y, float z);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public class LightManager {
|
||||
private long mNativeObject;
|
||||
@@ -56,6 +56,9 @@ public class LightManager {
|
||||
public float shadowNearHint = 1.0f;
|
||||
public float shadowFarHint = 100.0f;
|
||||
public boolean stable = true;
|
||||
public boolean screenSpaceContactShadows = false;
|
||||
public int stepCount = 8;
|
||||
public float maxShadowDistance = 0.3f;
|
||||
}
|
||||
|
||||
public static final float EFFICIENCY_INCANDESCENT = 0.0220f;
|
||||
@@ -83,7 +86,8 @@ public class LightManager {
|
||||
public Builder shadowOptions(@NonNull ShadowOptions options) {
|
||||
nBuilderShadowOptions(mNativeBuilder,
|
||||
options.mapSize, options.constantBias, options.normalBias, options.shadowFar,
|
||||
options.shadowNearHint, options.shadowFarHint, options.stable);
|
||||
options.shadowNearHint, options.shadowFarHint, options.stable,
|
||||
options.screenSpaceContactShadows, options.stepCount, options.maxShadowDistance);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -282,7 +286,7 @@ public class LightManager {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
|
||||
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance);
|
||||
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
import java.nio.Buffer;
|
||||
@@ -28,45 +29,182 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A Filament Material defines the visual appearance of an object. Materials function as a
|
||||
* templates from which {@link MaterialInstance}s can be spawned. Use {@link Builder} to construct
|
||||
* a Material object.
|
||||
*
|
||||
* @see <a href="https://google.github.io/filament/Materials.html">Filament Materials Guide</a>
|
||||
*/
|
||||
public class Material {
|
||||
private long mNativeObject;
|
||||
private final MaterialInstance mDefaultInstance;
|
||||
|
||||
private Set<VertexBuffer.VertexAttribute> mRequiredAttributes;
|
||||
|
||||
/** Supported shading models */
|
||||
public enum Shading {
|
||||
/**
|
||||
* No lighting applied, emissive possible
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels/unlitmodel">
|
||||
* Unlit model</a>
|
||||
*/
|
||||
UNLIT,
|
||||
|
||||
/**
|
||||
* Default, standard lighting
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels/litmodel">
|
||||
* Lit model</a>
|
||||
*/
|
||||
LIT,
|
||||
|
||||
/**
|
||||
* Subsurface lighting model
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels/subsurfacemodel">
|
||||
* Subsurface model</a>
|
||||
*/
|
||||
SUBSURFACE,
|
||||
|
||||
/**
|
||||
* Cloth lighting model
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels/clothmodel">
|
||||
* Cloth model</a>
|
||||
*/
|
||||
CLOTH,
|
||||
|
||||
/**
|
||||
* Legacy lighting model
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels/specularglossiness">
|
||||
* Specular glossiness</a>
|
||||
*/
|
||||
SPECULAR_GLOSSINESS
|
||||
}
|
||||
|
||||
/**
|
||||
* Attribute interpolation types in the fragment shader
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:interpolation">
|
||||
* Vertex and attributes: interpolation</a>
|
||||
*/
|
||||
public enum Interpolation {
|
||||
/** Default, smooth interpolation */
|
||||
SMOOTH,
|
||||
|
||||
/** Flat interpolation */
|
||||
FLAT
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported blending modes
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:blending">
|
||||
* Blending and transparency: blending</a>
|
||||
*/
|
||||
public enum BlendingMode {
|
||||
/** Material is opaque. */
|
||||
OPAQUE,
|
||||
|
||||
/**
|
||||
* Material is transparent and color is alpha-pre-multiplied.
|
||||
* Affects diffuse lighting only.
|
||||
*/
|
||||
TRANSPARENT,
|
||||
|
||||
/** Material is additive (e.g.: hologram). */
|
||||
ADD,
|
||||
MODULATE,
|
||||
|
||||
/** Material is masked (i.e. alpha tested). */
|
||||
MASKED,
|
||||
FADE
|
||||
|
||||
/**
|
||||
* Material is transparent and color is alpha-pre-multiplied.
|
||||
* Affects specular lighting.
|
||||
*/
|
||||
FADE,
|
||||
|
||||
/** Material darkens what's behind it. */
|
||||
MULTIPLY,
|
||||
|
||||
/** Material brightens what's behind it. */
|
||||
SCREEN,
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported refraction modes
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refraction">
|
||||
* Blending and transparency: refractionMode</a>
|
||||
*/
|
||||
public enum RefractionMode {
|
||||
NONE,
|
||||
CUBEMAP,
|
||||
SCREEN_SPACE
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported refraction types
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refractiontype">
|
||||
* Blending and transparency: refractionType</a>
|
||||
*/
|
||||
public enum RefractionType {
|
||||
SOLID,
|
||||
THIN
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported types of vertex domains
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:vertexdomain">
|
||||
* Vertex and attributes: vertexDomain</a>
|
||||
*/
|
||||
public enum VertexDomain {
|
||||
/** Vertices are in object space, default. */
|
||||
OBJECT,
|
||||
|
||||
/** Vertices are in world space. */
|
||||
WORLD,
|
||||
|
||||
/** Vertices are in view space. */
|
||||
VIEW,
|
||||
|
||||
/** Vertices are in normalized device space. */
|
||||
DEVICE
|
||||
}
|
||||
|
||||
/**
|
||||
* Face culling Mode
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
|
||||
* Rasterization: culling</a>
|
||||
*/
|
||||
public enum CullingMode {
|
||||
/** No culling. Front and back faces are visible. */
|
||||
NONE,
|
||||
|
||||
/** Front face culling. Only back faces are visible. */
|
||||
FRONT,
|
||||
|
||||
/** Back face culling. Only front faces are visible. */
|
||||
BACK,
|
||||
|
||||
/** Front and back culling. Geometry is not visible. */
|
||||
FRONT_AND_BACK
|
||||
}
|
||||
|
||||
@@ -144,6 +282,13 @@ public class Material {
|
||||
private Buffer mBuffer;
|
||||
private int mSize;
|
||||
|
||||
/**
|
||||
* Specifies the material data. The material data is a binary blob produced by
|
||||
* libfilamat or by matc.
|
||||
*
|
||||
* @param buffer buffer containing material data
|
||||
* @param size size of the material data in bytes
|
||||
*/
|
||||
@NonNull
|
||||
public Builder payload(@NonNull Buffer buffer, @IntRange(from = 0) int size) {
|
||||
mBuffer = buffer;
|
||||
@@ -151,6 +296,15 @@ public class Material {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the Material object.
|
||||
*
|
||||
* @param engine reference to the Engine instance to associate this Material with
|
||||
*
|
||||
* @return the newly created object
|
||||
*
|
||||
* @exception IllegalStateException if the material could not be created
|
||||
*/
|
||||
@NonNull
|
||||
public Material build(@NonNull Engine engine) {
|
||||
long nativeMaterial = nBuilderBuild(engine.getNativeObject(), mBuffer, mSize);
|
||||
@@ -159,6 +313,12 @@ public class Material {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of this material. Material instances should be freed using
|
||||
* {@link Engine#destroyMaterialInstance(MaterialInstance)}.
|
||||
*
|
||||
* @return the new instance
|
||||
*/
|
||||
@NonNull
|
||||
public MaterialInstance createInstance() {
|
||||
long nativeInstance = nCreateInstance(getNativeObject());
|
||||
@@ -166,63 +326,185 @@ public class Material {
|
||||
return new MaterialInstance(this, nativeInstance);
|
||||
}
|
||||
|
||||
/** Returns the material's default instance. */
|
||||
@NonNull
|
||||
public MaterialInstance getDefaultInstance() {
|
||||
return mDefaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this material. The material name is used for debugging purposes.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:name">
|
||||
* General: name</a>
|
||||
*/
|
||||
public String getName() {
|
||||
return nGetName(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shading model of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialmodels">
|
||||
* Material Models</a>
|
||||
*/
|
||||
public Shading getShading() {
|
||||
return Shading.values()[nGetShading(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interpolation mode of this material. This affects how variables are interpolated.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:interpolation">
|
||||
* Vertex and attributes: interpolation</a>
|
||||
*/
|
||||
public Interpolation getInterpolation() {
|
||||
return Interpolation.values()[nGetInterpolation(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the blending mode of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:blending">
|
||||
* Blending and transparency: blending</a>
|
||||
*/
|
||||
public BlendingMode getBlendingMode() {
|
||||
return BlendingMode.values()[nGetBlendingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the refraction mode of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refraction">
|
||||
* Blending and transparency: refraction</a>
|
||||
*/
|
||||
public RefractionMode getRefractionMode() {
|
||||
return RefractionMode.values()[nGetRefractionMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the refraction type of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:refractiontype">
|
||||
* Blending and transparency: refractionType</a>
|
||||
*/
|
||||
public RefractionType getRefractionType() {
|
||||
return RefractionType.values()[nGetRefractionType(getNativeObject())];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the vertex domain of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:vertexdomain">
|
||||
* Vertex and attributes: vertexDomain</a>
|
||||
*/
|
||||
public VertexDomain getVertexDomain() {
|
||||
return VertexDomain.values()[nGetVertexDomain(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default culling mode of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
|
||||
* Rasterization: culling</a>
|
||||
*/
|
||||
public CullingMode getCullingMode() {
|
||||
return CullingMode.values()[nGetCullingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether instances of this material will, by default, write to the color buffer.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorwrite">
|
||||
* Rasterization: colorWrite</a>
|
||||
*/
|
||||
public boolean isColorWriteEnabled() {
|
||||
return nIsColorWriteEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether instances of this material will, by default, write to the depth buffer.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthwrite">
|
||||
* Rasterization: depthWrite</a>
|
||||
*/
|
||||
public boolean isDepthWriteEnabled() {
|
||||
return nIsDepthWriteEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether instances of this material will, by default, use depth testing.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthculling">
|
||||
* Rasterization: depthCulling</a>
|
||||
*/
|
||||
public boolean isDepthCullingEnabled() {
|
||||
return nIsDepthCullingEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this material is double-sided.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:doublesided">
|
||||
* Rasterization: doubleSided</a>
|
||||
*/
|
||||
public boolean isDoubleSided() {
|
||||
return nIsDoubleSided(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alpha mask threshold used when the blending mode is set to masked.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:maskthreshold">
|
||||
* Blending and transparency: maskThreshold</a>
|
||||
*/
|
||||
public float getMaskThreshold() {
|
||||
return nGetMaskThreshold(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the screen-space variance for specular-antialiasing. This value is between 0 and 1.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance">
|
||||
* Anti-aliasing: specularAntiAliasingVariance</a>
|
||||
*/
|
||||
public float getSpecularAntiAliasingVariance() {
|
||||
return nGetSpecularAntiAliasingVariance(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clamping threshold for specular-antialiasing. This value is between 0 and 1.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold">
|
||||
* Anti-aliasing: specularAntiAliasingThreshold</a>
|
||||
*/
|
||||
public float getSpecularAntiAliasingThreshold() {
|
||||
return nGetSpecularAntiAliasingThreshold(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of {@link VertexBuffer.VertexAttribute}s that are required by this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:requires">
|
||||
* Vertex and attributes: requires</a>
|
||||
*/
|
||||
public Set<VertexBuffer.VertexAttribute> getRequiredAttributes() {
|
||||
if (mRequiredAttributes == null) {
|
||||
int bitSet = nGetRequiredAttributes(getNativeObject());
|
||||
@@ -238,14 +520,38 @@ public class Material {
|
||||
return mRequiredAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bit set representing the set of {@link VertexBuffer.VertexAttribute}s that are
|
||||
* required by this material. Use {@link #getRequiredAttributes()} to get these as a Set object.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/vertexandattributes:requires">
|
||||
* Vertex and attributes: requires</a>
|
||||
*/
|
||||
int getRequiredAttributesAsInt() {
|
||||
return nGetRequiredAttributes(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of parameters declared by this material.
|
||||
* The returned value can be 0.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:parameters">
|
||||
* General: parameters</a>
|
||||
*/
|
||||
public int getParameterCount() {
|
||||
return nGetParameterCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of Parameter objects representing this material's parameters.
|
||||
* The list may be empty if the material has no declared parameters.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:parameters">
|
||||
* General: parameters</a>
|
||||
*/
|
||||
public List<Parameter> getParameters() {
|
||||
int count = getParameterCount();
|
||||
List<Parameter> parameters = new ArrayList<>(count);
|
||||
@@ -253,86 +559,308 @@ public class Material {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a parameter of the given name exists on this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:parameters">
|
||||
* General: parameters</a>
|
||||
*/
|
||||
public boolean hasParameter(@NonNull String name) {
|
||||
return nHasParameter(getNativeObject(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, boolean x) {
|
||||
mDefaultInstance.setParameter(name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, float x) {
|
||||
mDefaultInstance.setParameter(name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of an int parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, int x) {
|
||||
mDefaultInstance.setParameter(name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool2 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, boolean x, boolean y) {
|
||||
mDefaultInstance.setParameter(name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float2 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, float x, float y) {
|
||||
mDefaultInstance.setParameter(name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of an int2 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, int x, int y) {
|
||||
mDefaultInstance.setParameter(name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool3 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, boolean x, boolean y, boolean z) {
|
||||
mDefaultInstance.setParameter(name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float3 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, float x, float y, float z) {
|
||||
mDefaultInstance.setParameter(name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a int3 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, int x, int y, int z) {
|
||||
mDefaultInstance.setParameter(name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool4 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, boolean x, boolean y, boolean z, boolean w) {
|
||||
mDefaultInstance.setParameter(name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float4 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, float x, float y, float z, float w) {
|
||||
mDefaultInstance.setParameter(name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a int4 parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, int x, int y, int z, int w) {
|
||||
mDefaultInstance.setParameter(name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a bool parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 bool4s:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name,
|
||||
@NonNull MaterialInstance.BooleanElement type, @NonNull @Size(min = 1) boolean[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
mDefaultInstance.setParameter(name, type, v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an int parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 int4s:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name,
|
||||
@NonNull MaterialInstance.IntElement type, @NonNull @Size(min = 1) int[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
mDefaultInstance.setParameter(name, type, v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a float parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 float4s:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name,
|
||||
@NonNull MaterialInstance.FloatElement type, @NonNull @Size(min = 1) float[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
mDefaultInstance.setParameter(name, type, v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the given parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material color parameter
|
||||
* @param type whether the color is specified in the linear or sRGB space
|
||||
* @param r red component
|
||||
* @param g green component
|
||||
* @param b blue component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, @NonNull Colors.RgbType type,
|
||||
float r, float g, float b) {
|
||||
mDefaultInstance.setParameter(name, type, r, g, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the given parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material color parameter
|
||||
* @param type whether the color is specified in the linear or sRGB space
|
||||
* @param r red component
|
||||
* @param g green component
|
||||
* @param b blue component
|
||||
* @param a alpha component
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name, @NonNull Colors.RgbaType type,
|
||||
float r, float g, float b, float a) {
|
||||
mDefaultInstance.setParameter(name, type, r, g, b, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a texture and sampler parameter on this material's default instance.
|
||||
*
|
||||
* @param name The name of the material texture parameter
|
||||
* @param texture The texture to set as parameter
|
||||
* @param sampler The sampler to be used with this texture
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
*/
|
||||
public void setDefaultParameter(@NonNull String name,
|
||||
@NonNull Texture texture, @NonNull TextureSampler sampler) {
|
||||
mDefaultInstance.setParameter(name, texture, sampler);
|
||||
@@ -366,6 +894,9 @@ public class Material {
|
||||
private static native float nGetMaskThreshold(long nativeMaterial);
|
||||
private static native float nGetSpecularAntiAliasingVariance(long nativeMaterial);
|
||||
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterial);
|
||||
private static native int nGetRefractionMode(long nativeMaterial);
|
||||
private static native int nGetRefractionType(long nativeMaterial);
|
||||
|
||||
|
||||
private static native int nGetParameterCount(long nativeMaterial);
|
||||
private static native void nGetParameters(long nativeMaterial,
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public class MaterialInstance {
|
||||
private Material mMaterial;
|
||||
@@ -58,6 +58,7 @@ public class MaterialInstance {
|
||||
mNativeObject = nativeMaterialInstance;
|
||||
}
|
||||
|
||||
/** @return the {@link Material} associated with this instance */
|
||||
@NonNull
|
||||
public Material getMaterial() {
|
||||
if (mMaterial == null) {
|
||||
@@ -66,118 +67,402 @@ public class MaterialInstance {
|
||||
return mMaterial;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*/
|
||||
public void setParameter(@NonNull String name, boolean x) {
|
||||
nSetParameterBool(getNativeObject(), name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*/
|
||||
public void setParameter(@NonNull String name, float x) {
|
||||
nSetParameterFloat(getNativeObject(), name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of an int parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the material parameter
|
||||
*/
|
||||
public void setParameter(@NonNull String name, int x) {
|
||||
nSetParameterInt(getNativeObject(), name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool2 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, boolean x, boolean y) {
|
||||
nSetParameterBool2(getNativeObject(), name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float2 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, float x, float y) {
|
||||
nSetParameterFloat2(getNativeObject(), name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of an int2 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, int x, int y) {
|
||||
nSetParameterInt2(getNativeObject(), name, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool3 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, boolean x, boolean y, boolean z) {
|
||||
nSetParameterBool3(getNativeObject(), name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float3 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, float x, float y, float z) {
|
||||
nSetParameterFloat3(getNativeObject(), name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a int3 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, int x, int y, int z) {
|
||||
nSetParameterInt3(getNativeObject(), name, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool4 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, boolean x, boolean y, boolean z, boolean w) {
|
||||
nSetParameterBool4(getNativeObject(), name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a float4 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, float x, float y, float z, float w) {
|
||||
nSetParameterFloat4(getNativeObject(), name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a int4 parameter.
|
||||
*
|
||||
* @param name the name of the material parameter
|
||||
* @param x the value of the first component
|
||||
* @param y the value of the second component
|
||||
* @param z the value of the third component
|
||||
* @param w the value of the fourth component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, int x, int y, int z, int w) {
|
||||
nSetParameterInt4(getNativeObject(), name, x, y, z, w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a texture and sampler parameter on this material's default instance.
|
||||
*
|
||||
* @param name The name of the material texture parameter
|
||||
* @param texture The texture to set as parameter
|
||||
* @param sampler The sampler to be used with this texture
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@NonNull Texture texture, @NonNull TextureSampler sampler) {
|
||||
nSetParameterTexture(getNativeObject(), name, texture.getNativeObject(), sampler.mSampler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a bool parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 bool4s:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 4];
|
||||
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 3];
|
||||
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@NonNull BooleanElement type, @NonNull boolean[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
nSetBooleanParameterArray(getNativeObject(), name, type.ordinal(), v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an int parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 int4s:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 4];
|
||||
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 3];
|
||||
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@NonNull IntElement type, @NonNull int[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
nSetIntParameterArray(getNativeObject(), name, type.ordinal(), v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a float parameter array by name.
|
||||
*
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 float4s:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@NonNull FloatElement type, @NonNull float[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count) {
|
||||
nSetFloatParameterArray(getNativeObject(), name, type.ordinal(), v, offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the given parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material color parameter
|
||||
* @param type whether the color is specified in the linear or sRGB space
|
||||
* @param r red component
|
||||
* @param g green component
|
||||
* @param b blue component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, @NonNull Colors.RgbType type,
|
||||
float r, float g, float b) {
|
||||
float[] color = Colors.toLinear(type, r, g, b);
|
||||
nSetParameterFloat3(getNativeObject(), name, color[0], color[1], color[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the given parameter on this material's default instance.
|
||||
*
|
||||
* @param name the name of the material color parameter
|
||||
* @param type whether the color is specified in the linear or sRGB space
|
||||
* @param r red component
|
||||
* @param g green component
|
||||
* @param b blue component
|
||||
* @param a alpha component
|
||||
*/
|
||||
public void setParameter(@NonNull String name, @NonNull Colors.RgbaType type,
|
||||
float r, float g, float b, float a) {
|
||||
float[] color = Colors.toLinear(type, r, g, b, a);
|
||||
nSetParameterFloat4(getNativeObject(), name, color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a custom scissor rectangle; by default this encompasses the View.
|
||||
*
|
||||
* @param left left coordinate of the scissor box
|
||||
* @param bottom bottom coordinate of the scissor box
|
||||
* @param width width of the scissor box
|
||||
* @param height height of the scissor box
|
||||
*/
|
||||
public void setScissor(@IntRange(from = 0) int left, @IntRange(from = 0) int bottom,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
|
||||
nSetScissor(getNativeObject(), left, bottom, width, height);
|
||||
}
|
||||
|
||||
/** Returns the scissor rectangle to its default setting, which encompasses the View. */
|
||||
public void unsetScissor() {
|
||||
nUnsetScissor(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a polygon offset that will be applied to all renderables drawn with this material
|
||||
* instance.
|
||||
*
|
||||
* The value of the offset is scale * dz + r * constant, where dz is the change in depth
|
||||
* relative to the screen area of the triangle, and r is the smallest value that is guaranteed
|
||||
* to produce a resolvable offset for a given implementation. This offset is added before the
|
||||
* depth test.
|
||||
*
|
||||
* Warning: using a polygon offset other than zero has a significant negative performance
|
||||
* impact, as most implementations have to disable early depth culling. DO NOT USE unless
|
||||
* absolutely necessary.
|
||||
*
|
||||
* @param scale scale factor used to create a variable depth offset for each triangle
|
||||
* @param constant scale factor used to create a constant depth offset for each triangle
|
||||
*/
|
||||
public void setPolygonOffset(float scale, float constant) {
|
||||
nSetPolygonOffset(getNativeObject(), scale, constant);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the minimum alpha value a fragment must have to not be discarded when the blend
|
||||
* mode is MASKED. Defaults to 0.4 if it has not been set in the parent Material. The specified
|
||||
* value should be between 0 and 1 and will be clamped if necessary.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:maskthreshold">
|
||||
* Blending and transparency: maskThreshold</a>
|
||||
*/
|
||||
public void setMaskThreshold(float threshold) {
|
||||
nSetMaskThreshold(getNativeObject(), threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the screen space variance of the filter kernel used when applying specular
|
||||
* anti-aliasing. The default value is set to 0.15. The specified value should be between
|
||||
* 0 and 1 and will be clamped if necessary.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance">
|
||||
* Anti-aliasing: specularAntiAliasingVariance</a>
|
||||
*/
|
||||
public void setSpecularAntiAliasingVariance(float variance) {
|
||||
nSetSpecularAntiAliasingVariance(getNativeObject(), variance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clamping threshold used to suppress estimation errors when applying specular
|
||||
* anti-aliasing. The default value is set to 0.2. The specified value should be between 0
|
||||
* and 1 and will be clamped if necessary.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold">
|
||||
* Anti-aliasing: specularAntiAliasingThreshold</a>
|
||||
*/
|
||||
public void setSpecularAntiAliasingThreshold(float threshold) {
|
||||
nSetSpecularAntiAliasingThreshold(getNativeObject(), threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables double-sided lighting if the parent Material has double-sided capability,
|
||||
* otherwise prints a warning. If double-sided lighting is enabled, backface culling is
|
||||
* automatically disabled.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:doublesided">
|
||||
* Rasterization: doubleSided</a>
|
||||
*/
|
||||
public void setDoubleSided(boolean doubleSided) {
|
||||
nSetDoubleSided(getNativeObject(), doubleSided);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default triangle culling state that was set on the material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
|
||||
* Rasterization: culling</a>
|
||||
*/
|
||||
public void setCullingMode(Material.CullingMode mode) {
|
||||
nSetCullingMode(getNativeObject(), mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default color-buffer write state that was set on the material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorWrite">
|
||||
* Rasterization: colorWrite</a>
|
||||
*/
|
||||
void setColorWrite(boolean enable) {
|
||||
nSetColorWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default depth-buffer write state that was set on the material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthWrite">
|
||||
* Rasterization: depthWrite</a>
|
||||
*/
|
||||
void setDepthWrite(boolean enable) {
|
||||
nSetDepthWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default depth testing state that was set on the material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthCulling">
|
||||
* Rasterization: depthCulling</a>
|
||||
*/
|
||||
void setDepthCulling(boolean enable) {
|
||||
nSetDepthCulling(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
|
||||
@@ -247,4 +532,8 @@ public class MaterialInstance {
|
||||
float threshold);
|
||||
|
||||
private static native void nSetDoubleSided(long nativeMaterialInstance, boolean doubleSided);
|
||||
private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
|
||||
private static native void nSetColorWrite(long nativeMaterialInstance, boolean enable);
|
||||
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
|
||||
private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,36 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public final class MathUtils {
|
||||
private MathUtils() { }
|
||||
|
||||
/**
|
||||
* Packs the tangent frame represented by the specified tangent, bitangent, and normal into a
|
||||
* quaternion.
|
||||
*
|
||||
* <p>
|
||||
* Reflection is preserved by encoding it as the sign of the w component in the resulting
|
||||
* quaternion. Since -0 cannot always be represented on the GPU, this function computes a bias
|
||||
* to ensure values are always either positive or negative, never 0. The bias is computed based
|
||||
* on a per-element storage size of 2 bytes, making the resulting quaternion suitable for
|
||||
* storage into an SNORM16 vector.
|
||||
* </p>
|
||||
*
|
||||
* @param tangentX the X component of the tangent
|
||||
* @param tangentY the Y component of the tangent
|
||||
* @param tangentZ the Z component of the tangent
|
||||
* @param bitangentX the X component of the bitangent
|
||||
* @param bitangentY the Y component of the bitangent
|
||||
* @param bitangentZ the Z component of the bitangent
|
||||
* @param normalX the X component of the normal
|
||||
* @param normalY the Y component of the normal
|
||||
* @param normalZ the Z component of the normal
|
||||
* @param quaternion a float array of at least size 4 for the quaternion result to be stored
|
||||
*/
|
||||
public static void packTangentFrame(
|
||||
float tangentX, float tangentY, float tangentZ,
|
||||
float bitangentX, float bitangentY, float bitangentZ,
|
||||
@@ -34,6 +57,30 @@ public final class MathUtils {
|
||||
normalX, normalY, normalZ, quaternion, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs the tangent frame represented by the specified tangent, bitangent, and normal into a
|
||||
* quaternion.
|
||||
*
|
||||
* <p>
|
||||
* Reflection is preserved by encoding it as the sign of the w component in the resulting
|
||||
* quaternion. Since -0 cannot always be represented on the GPU, this function computes a bias
|
||||
* to ensure values are always either positive or negative, never 0. The bias is computed based
|
||||
* on a per-element storage size of 2 bytes, making the resulting quaternion suitable for
|
||||
* storage into an SNORM16 vector.
|
||||
* </p>
|
||||
*
|
||||
* @param tangentX the X component of the tangent
|
||||
* @param tangentY the Y component of the tangent
|
||||
* @param tangentZ the Z component of the tangent
|
||||
* @param bitangentX the X component of the bitangent
|
||||
* @param bitangentY the Y component of the bitangent
|
||||
* @param bitangentZ the Z component of the bitangent
|
||||
* @param normalX the X component of the normal
|
||||
* @param normalY the Y component of the normal
|
||||
* @param normalZ the Z component of the normal
|
||||
* @param quaternion a float array of at least size 4 for the quaternion result to be stored
|
||||
* @param offset offset, in elements, into the quaternion array to store the results
|
||||
*/
|
||||
public static void packTangentFrame(
|
||||
float tangentX, float tangentY, float tangentZ,
|
||||
float bitangentX, float bitangentY, float bitangentZ,
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
import java.nio.Buffer;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
abstract class Platform {
|
||||
private static Platform mCurrentPlatform = null;
|
||||
|
||||
@@ -16,13 +16,20 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An offscreen render target that can be associated with a {@link View} and contains
|
||||
* weak references to a set of attached {@link Texture} objects.
|
||||
*
|
||||
* <p>
|
||||
* Clients are responsible for the lifetime of all associated <code>Texture</code> attachments.
|
||||
* </p>
|
||||
*
|
||||
* @see View
|
||||
*/
|
||||
public class RenderTarget {
|
||||
private long mNativeObject;
|
||||
private final Texture[] mTextures = new Texture[2];
|
||||
@@ -40,11 +47,17 @@ public class RenderTarget {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* An attachment point is a slot that can be assigned to a {@link Texture}.
|
||||
*/
|
||||
public enum AttachmentPoint {
|
||||
COLOR,
|
||||
DEPTH,
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs <code>RenderTarget</code> objects using a builder pattern.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
@@ -56,6 +69,15 @@ public class RenderTarget {
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a texture to a given attachment point.
|
||||
*
|
||||
* <p>All RenderTargets must have a non-null <code>COLOR</code> attachment.</p>
|
||||
*
|
||||
* @param attachment The attachment point of the texture.
|
||||
* @param texture The associated texture object.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder texture(@NonNull AttachmentPoint attachment, @Nullable Texture texture) {
|
||||
mTextures[attachment.ordinal()] = texture;
|
||||
@@ -63,24 +85,51 @@ public class RenderTarget {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mipmap level for a given attachment point.
|
||||
*
|
||||
* @param attachment The attachment point of the texture.
|
||||
* @param level The associated mipmap level, 0 by default.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder mipLevel(@NonNull AttachmentPoint attachment, @IntRange(from = 0) int level) {
|
||||
nBuilderMipLevel(mNativeBuilder, attachment.ordinal(), level);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cubemap face for a given attachment point.
|
||||
*
|
||||
* @param attachment The attachment point.
|
||||
* @param face The associated cubemap face.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder face(@NonNull AttachmentPoint attachment, Texture.CubemapFace face) {
|
||||
nBuilderFace(mNativeBuilder, attachment.ordinal(), face.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the layer for a given attachment point (for 3D textures).
|
||||
*
|
||||
* @param attachment The attachment point.
|
||||
* @param layer The associated cubemap layer.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder layer(@NonNull AttachmentPoint attachment, @IntRange(from = 0) int layer) {
|
||||
nBuilderLayer(mNativeBuilder, attachment.ordinal(), layer);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the RenderTarget object and returns a pointer to it.
|
||||
*
|
||||
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
||||
* an error occurred.
|
||||
*/
|
||||
@NonNull
|
||||
public RenderTarget build(@NonNull Engine engine) {
|
||||
long nativeRenderTarget = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -108,20 +157,45 @@ public class RenderTarget {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the texture set on the given attachment point.
|
||||
*
|
||||
* @param attachment Attachment point
|
||||
* @return A Texture object or nullptr if no texture is set for this attachment point
|
||||
*/
|
||||
@Nullable
|
||||
public Texture getTexture(@NonNull AttachmentPoint attachment) {
|
||||
return mTextures[attachment.ordinal()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mipmap level set on the given attachment point.
|
||||
*
|
||||
* @param attachment Attachment point
|
||||
* @return the mipmap level set on the given attachment point
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getMipLevel(@NonNull AttachmentPoint attachment) {
|
||||
return nGetMipLevel(getNativeObject(), attachment.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the face of a cubemap set on the given attachment point.
|
||||
*
|
||||
* @param attachment Attachment point
|
||||
* @return A cubemap face identifier. This is only relevant if the attachment's texture is
|
||||
* a cubemap.
|
||||
*/
|
||||
public Texture.CubemapFace getFace(AttachmentPoint attachment) {
|
||||
return Texture.CubemapFace.values()[nGetFace(getNativeObject(), attachment.ordinal())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture-layer set on the given attachment point.
|
||||
*
|
||||
* @param attachment Attachment point
|
||||
* @return A texture layer. This is only relevant if the attachment's texture is a 3D texture.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getLayer(@NonNull AttachmentPoint attachment) {
|
||||
return nGetLayer(getNativeObject(), attachment.ordinal());
|
||||
@@ -132,11 +206,11 @@ public class RenderTarget {
|
||||
}
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native long nDestroyBuilder(long nativeBuilder);
|
||||
private static native long nBuilderTexture(long nativeBuilder, int attachment, long nativeTexture);
|
||||
private static native long nBuilderMipLevel(long nativeBuilder, int attachment, int level);
|
||||
private static native long nBuilderFace(long nativeBuilder, int attachment, int face);
|
||||
private static native long nBuilderLayer(long nativeBuilder, int attachment, int layer);
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nBuilderTexture(long nativeBuilder, int attachment, long nativeTexture);
|
||||
private static native void nBuilderMipLevel(long nativeBuilder, int attachment, int level);
|
||||
private static native void nBuilderFace(long nativeBuilder, int attachment, int face);
|
||||
private static native void nBuilderLayer(long nativeBuilder, int attachment, int layer);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetMipLevel(long nativeRenderTarget, int attachment);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,19 +16,58 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
|
||||
/**
|
||||
* A <code>Renderer</code> instance represents an operating system's window.
|
||||
*
|
||||
* <p>
|
||||
* Typically, applications create a <code>Renderer</code> per window. The <code>Renderer</code> generates
|
||||
* drawing commands for the render thread and manages frame latency.
|
||||
* <br>
|
||||
* A Renderer generates drawing commands from a View, itself containing a Scene description.
|
||||
* </p>
|
||||
*
|
||||
* <h1>Creation and Destruction</h1>
|
||||
*
|
||||
* <p>A <code>Renderer</code> is created using {@link Engine#createRenderer} and destroyed
|
||||
* using {@link Engine#destroyRenderer}.</p>
|
||||
*
|
||||
* @see Engine
|
||||
* @see View
|
||||
*/
|
||||
public class Renderer {
|
||||
private final Engine mEngine;
|
||||
private long mNativeObject;
|
||||
|
||||
/**
|
||||
* Indicates that the <code>dstSwapChain</code> passed into {@link #copyFrame} should be
|
||||
* committed after the frame has been copied.
|
||||
*
|
||||
* @see #copyFrame
|
||||
*/
|
||||
public static final int MIRROR_FRAME_FLAG_COMMIT = 0x1;
|
||||
|
||||
/**
|
||||
* Indicates that the presentation time should be set on the <code>dstSwapChain</code>
|
||||
* passed into {@link #copyFrame} to the monotonic clock time when the frame is
|
||||
* copied.
|
||||
*
|
||||
* @see #copyFrame
|
||||
*/
|
||||
public static final int MIRROR_FRAME_FLAG_SET_PRESENTATION_TIME = 0x2;
|
||||
|
||||
/**
|
||||
* Indicates that the <code>dstSwapChain</code> passed into {@link #copyFrame} should be
|
||||
* cleared to black before the frame is copied into the specified viewport.
|
||||
*
|
||||
* @see #copyFrame
|
||||
*/
|
||||
public static final int MIRROR_FRAME_FLAG_CLEAR = 0x4;
|
||||
|
||||
Renderer(@NonNull Engine engine, long nativeRenderer) {
|
||||
@@ -36,25 +75,128 @@ public class Renderer {
|
||||
mNativeObject = nativeRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Engine} that created this <code>Renderer</code>.
|
||||
*
|
||||
* @return {@link Engine} instance this <code>Renderer</code> is associated to.
|
||||
*/
|
||||
@NonNull
|
||||
public Engine getEngine() {
|
||||
return mEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a frame for this <code>Renderer</code>.
|
||||
* <p><code>beginFrame</code> manages frame pacing, and returns whether or not a frame should be
|
||||
* drawn. The goal of this is to skip frames when the GPU falls behind in order to keep the frame
|
||||
* latency low.</p>
|
||||
*
|
||||
* <p>If a given frame takes too much time in the GPU, the CPU will get ahead of the GPU. The
|
||||
* display will draw the same frame twice producing a stutter. At this point, the CPU is
|
||||
* ahead of the GPU and depending on how many frames are buffered, latency increases.
|
||||
* beginFrame() attempts to detect this situation and returns <code>false</code> in that case,
|
||||
* indicating to the caller to skip the current frame.</p>
|
||||
*
|
||||
* <p>All calls to render() must happen <b>after</b> beginFrame().</p>
|
||||
*
|
||||
* @param swapChain the {@link SwapChain} instance to use
|
||||
*
|
||||
* @return <code>false</code> if the current frame must be skipped<br>
|
||||
* When skipping a frame, the whole frame is canceled, and {@link #endFrame} must not
|
||||
* be called.
|
||||
*
|
||||
* @see #endFrame
|
||||
* @see #render
|
||||
*/
|
||||
public boolean beginFrame(@NonNull SwapChain swapChain) {
|
||||
return nBeginFrame(getNativeObject(), swapChain.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the current frame and schedules it for display.
|
||||
* <p>
|
||||
* <code>endFrame()</code> schedules the current frame to be displayed on the
|
||||
* <code>Renderer</code>'s window.
|
||||
* </p>
|
||||
*
|
||||
* <br><p>All calls to render() must happen <b>before</b> endFrame().</p>
|
||||
*
|
||||
* @see #beginFrame
|
||||
* @see #render
|
||||
*/
|
||||
public void endFrame() {
|
||||
nEndFrame(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a {@link View} into this <code>Renderer</code>'s window.
|
||||
*
|
||||
* <p>
|
||||
* This is filament's main rendering method, most of the CPU-side heavy lifting is performed
|
||||
* here. The purpose of the <code>render()</code> function is to generate render commands which
|
||||
* are asynchronously executed by the {@link Engine}'s render thread.
|
||||
* </p>
|
||||
*
|
||||
* <p><code>render()</code> generates commands for each of the following stages:</p>
|
||||
* <ul>
|
||||
* <li>Shadow map pass, if needed (currently only a single shadow map is supported)</li>
|
||||
* <li>Depth pre-pass</li>
|
||||
* <li>SSAO pass, if enabled</li>
|
||||
* <li>Color pass</li>
|
||||
* <li>Post-processing pass</li>
|
||||
* </ul>
|
||||
*
|
||||
* A typical render loop looks like this:
|
||||
*
|
||||
* <pre>
|
||||
* void renderLoop(Renderer renderer, SwapChain swapChain) {
|
||||
* do {
|
||||
* // typically we wait for VSYNC and user input events
|
||||
* if (renderer.beginFrame(swapChain)) {
|
||||
* renderer.render(mView);
|
||||
* renderer.endFrame();
|
||||
* }
|
||||
* } while (!quit());
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
*<li><code>render()</code> must be called <b>after</b> {@link #beginFrame} and <b>before</b>
|
||||
*{@link #endFrame}.</li>
|
||||
*
|
||||
*<li><code>render()</code> must be called from the {@link Engine}'s main thread
|
||||
*(or external synchronization must be provided). In particular, calls to <code>render()</code>
|
||||
*on different <code>Renderer</code> instances <b>must</b> be synchronized.</li>
|
||||
*
|
||||
*<li><code>render()</code> performs potentially heavy computations and cannot be multi-threaded.
|
||||
*However, internally, it is highly multi-threaded to both improve performance and mitigate
|
||||
*the call's latency.</li>
|
||||
*
|
||||
*<li><code>render()</code> is typically called once per frame (but not necessarily).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param view the {@link View} to render
|
||||
*
|
||||
* @see #beginFrame
|
||||
* @see #endFrame
|
||||
* @see View
|
||||
*
|
||||
*/
|
||||
public void render(@NonNull View view) {
|
||||
nRender(getNativeObject(), view.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method MUST be called before endFrame.
|
||||
* Copies the currently rendered {@link View} to the indicated {@link SwapChain}, using the
|
||||
* indicated source and destination rectangle.
|
||||
*
|
||||
* <p><code>copyFrame()</code> should be called after a frame is rendered using {@link #render}
|
||||
* but before {@link #endFrame} is called.</p>
|
||||
*
|
||||
* @param dstSwapChain the {@link SwapChain} into which the frame should be copied
|
||||
* @param dstViewport the destination rectangle in which to draw the view
|
||||
* @param srcViewport the source rectangle to be copied
|
||||
* @param flags one or more <code>CopyFrameFlag</code> behavior configuration flags
|
||||
*/
|
||||
public void copyFrame(
|
||||
@NonNull SwapChain dstSwapChain, @NonNull Viewport dstViewport,
|
||||
@@ -73,7 +215,68 @@ public class Renderer {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method MUST be called before endFrame.
|
||||
* Reads back the content of the {@link SwapChain} associated with this <code>Renderer</code>.
|
||||
*
|
||||
*<pre>
|
||||
*
|
||||
* Framebuffer as seen on User buffer (PixelBufferDescriptor)
|
||||
* screen
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
*
|
||||
* <p>Typically <code>readPixels</code> will be called after {@link #render} and before
|
||||
* {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@@ -96,11 +299,155 @@ public class Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
double getUserTime() {
|
||||
/**
|
||||
* Reads back the content of a specified {@link RenderTarget}.
|
||||
*
|
||||
*<pre>
|
||||
*
|
||||
* Framebuffer as seen on User buffer (PixelBufferDescriptor)
|
||||
* screen
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
*
|
||||
* <p>Typically <code>readPixels</code> will be called after {@link #render} and before
|
||||
* {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param renderTarget {@link RenderTarget} to read back from
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@NonNull RenderTarget renderTarget,
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@NonNull Texture.PixelBufferDescriptor buffer) {
|
||||
|
||||
if (buffer.storage.isReadOnly()) {
|
||||
throw new ReadOnlyBufferException();
|
||||
}
|
||||
|
||||
int result = nReadPixelsEx(getNativeObject(), mEngine.getNativeObject(),
|
||||
renderTarget.getNativeObject(),
|
||||
xoffset, yoffset, width, height,
|
||||
buffer.storage, buffer.storage.remaining(),
|
||||
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
|
||||
buffer.stride, buffer.format.ordinal(),
|
||||
buffer.handler, buffer.callback);
|
||||
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a timestamp (in seconds) for the last call to {@link #beginFrame}. This value is
|
||||
* constant for all {@link View views} rendered during a frame. The epoch is set with
|
||||
* {@link #resetUserTime}.
|
||||
* <br>
|
||||
* <p>In materials, this value can be queried using <code>vec4 getUserTime()</code>. The value
|
||||
* returned is a <code>highp vec4</code> encoded as follows:</p>
|
||||
* <pre>
|
||||
* time.x = (float)Renderer.getUserTime();
|
||||
* time.y = Renderer.getUserTime() - time.x;
|
||||
* </pre>
|
||||
*
|
||||
* It follows that the following invariants are true:
|
||||
* <pre>
|
||||
* (double)time.x + (double)time.y == Renderer.getUserTime()
|
||||
* time.x == (float)Renderer.getUserTime()
|
||||
* </pre>
|
||||
*
|
||||
* This encoding allows the shader code to perform high precision (i.e. double) time
|
||||
* calculations when needed despite the lack of double precision in the shader, e.g.:
|
||||
* <br>
|
||||
* To compute <code>(double)time * vertex</code> in the material, use the following construct:
|
||||
* <pre>
|
||||
* vec3 result = time.x * vertex + time.y * vertex;
|
||||
* </pre>
|
||||
*
|
||||
* Most of the time, high precision computations are not required, but be aware that the
|
||||
* precision of <code>time.x</code> rapidly diminishes as time passes:
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr align="center"><th> time </th><th> precision </th></tr>
|
||||
* <tr align="center"><td> 16.7s </td><td> us </td></tr>
|
||||
* <tr align="center"><td> 4h39.7s </td><td> ms </td></tr>
|
||||
* <tr align="center"><td> 77h </td><td> 1/60s </td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
* <p>
|
||||
*
|
||||
* In other words, it is only possible to get microsecond accuracy for about 16s or millisecond
|
||||
* accuracy for just under 5h. This problem can be mitigated by calling {@link #resetUserTime},
|
||||
* or using high precision time as described above.
|
||||
*
|
||||
* @return the time in seconds since {@link #resetUserTime} was last called
|
||||
*
|
||||
* @see #resetUserTime
|
||||
*/
|
||||
public double getUserTime() {
|
||||
return nGetUserTime(getNativeObject());
|
||||
}
|
||||
|
||||
void resetUserTime() {
|
||||
/**
|
||||
* Sets the user time epoch to now, i.e. resets the user time to zero.
|
||||
* <br>
|
||||
* <p>Use this method used to keep the precision of time high in materials, in practice it should
|
||||
* be called at least when the application is paused, e.g.
|
||||
* <code>Activity.onPause</code> in Android.</p>
|
||||
*
|
||||
* @see #getUserTime
|
||||
*/
|
||||
public void resetUserTime() {
|
||||
nResetUserTime(getNativeObject());
|
||||
}
|
||||
|
||||
@@ -127,6 +474,12 @@ public class Renderer {
|
||||
Buffer storage, int remaining,
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native int nReadPixelsEx(long nativeRenderer, long nativeEngine,
|
||||
long nativeRenderTarget,
|
||||
int xoffset, int yoffset, int width, int height,
|
||||
Buffer storage, int remaining,
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native double nGetUserTime(long nativeRenderer);
|
||||
private static native void nResetUserTime(long nativeRenderer);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,30 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A <code>Scene</code> is a flat container of {@link RenderableManager} and {@link LightManager}
|
||||
* components.
|
||||
* <br>
|
||||
* <p>A <code>Scene</code> doesn't provide a hierarchy of objects, i.e.: it's not a scene-graph.
|
||||
* However, it manages the list of objects to render and the list of lights. These can
|
||||
* be added or removed from a <code>Scene</code> at any time.
|
||||
* Moreover clients can use {@link TransformManager} to create a graph of transforms.</p>
|
||||
* <br>
|
||||
* <p>A {@link RenderableManager} component <b>must</b> be added to a <code>Scene</code> in order
|
||||
* to be rendered, and the <code>Scene</code> must be provided to a {@link View}.</p>
|
||||
*
|
||||
* <h1>Creation and Destruction</h1>
|
||||
*
|
||||
* A <code>Scene</code> is created using {@link Engine#createScene} and destroyed using
|
||||
* {@link Engine#destroyScene(Scene)}.
|
||||
*
|
||||
* @see View
|
||||
* @see LightManager
|
||||
* @see RenderableManager
|
||||
* @see TransformManager
|
||||
*/
|
||||
public class Scene {
|
||||
private long mNativeObject;
|
||||
private @Nullable Skybox mSkybox;
|
||||
@@ -27,35 +49,78 @@ public class Scene {
|
||||
mNativeObject = nativeScene;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link Skybox} or <code>null</code> if none is set
|
||||
* @see #setSkybox(Skybox)
|
||||
*/
|
||||
@Nullable
|
||||
public Skybox getSkybox() {
|
||||
return mSkybox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Skybox}.
|
||||
*
|
||||
* The {@link Skybox} is drawn last and covers all pixels not touched by geometry.
|
||||
*
|
||||
* @param skybox the {@link Skybox} to use to fill untouched pixels,
|
||||
* or <code>null</code> to unset the {@link Skybox}.
|
||||
*/
|
||||
public void setSkybox(@Nullable Skybox skybox) {
|
||||
mSkybox = skybox;
|
||||
nSetSkybox(getNativeObject(), mSkybox != null ? mSkybox.getNativeObject() : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link IndirectLight} or <code>null</code> if none is set
|
||||
* @see #setIndirectLight(IndirectLight)
|
||||
*/
|
||||
@Nullable
|
||||
public IndirectLight getIndirectLight() {
|
||||
return mIndirectLight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link IndirectLight} to use when rendering the <code>Scene</code>.
|
||||
*
|
||||
* Currently, a <code>Scene</code> may only have a single {@link IndirectLight}.
|
||||
* This call replaces the current {@link IndirectLight}.
|
||||
*
|
||||
* @param ibl the {@link IndirectLight} to use when rendering the <code>Scene</code>
|
||||
* or <code>null</code> to unset.
|
||||
*/
|
||||
public void setIndirectLight(@Nullable IndirectLight ibl) {
|
||||
mIndirectLight = ibl;
|
||||
nSetIndirectLight(getNativeObject(),
|
||||
mIndirectLight != null ? mIndirectLight.getNativeObject() : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an {@link Entity} to the <code>Scene</code>.
|
||||
*
|
||||
* @param entity the entity is ignored if it doesn't have a {@link RenderableManager} component
|
||||
* or {@link LightManager} component.<br>
|
||||
* A given {@link Entity} object can only be added once to a <code>Scene</code>.
|
||||
*/
|
||||
public void addEntity(@Entity int entity) {
|
||||
nAddEntity(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a list of entities to the <code>Scene</code>.
|
||||
*
|
||||
* @param entities array containing entities to add to the <code>Scene</code>.
|
||||
*/
|
||||
public void addEntities(@Entity int[] entities) {
|
||||
nAddEntities(getNativeObject(), entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an {@link Entity} from the <code>Scene</code>.
|
||||
*
|
||||
* @param entity the {@link Entity} to remove from the <code>Scene</code>. If the specified
|
||||
* <code>entity</code> doesn't exist, this call is ignored.
|
||||
*/
|
||||
public void removeEntity(@Entity int entity) {
|
||||
nRemove(getNativeObject(), entity);
|
||||
}
|
||||
@@ -67,10 +132,20 @@ public class Scene {
|
||||
removeEntity(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of {@link RenderableManager} components in the <code>Scene</code>.
|
||||
*
|
||||
* @return number of {@link RenderableManager} components in the <code>Scene</code>..
|
||||
*/
|
||||
public int getRenderableCount() {
|
||||
return nGetRenderableCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of {@link LightManager} components in the <code>Scene</code>.
|
||||
*
|
||||
* @return number of {@link LightManager} components in the <code>Scene</code>..
|
||||
*/
|
||||
public int getLightCount() {
|
||||
return nGetLightCount(getNativeObject());
|
||||
}
|
||||
|
||||
@@ -16,41 +16,125 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Skybox
|
||||
* <p>When added to a {@link Scene}, the <code>Skybox</code> fills all untouched pixels.</p>
|
||||
*
|
||||
* <h1>Creation and destruction</h1>
|
||||
*
|
||||
* A <code>Skybox</code> object is created using the {@link Skybox.Builder} and destroyed by calling
|
||||
* {@link Engine#destroySkybox}.<br>
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
*
|
||||
* Scene scene = engine.createScene();
|
||||
*
|
||||
* Skybox skybox = new Skybox.Builder()
|
||||
* .environment(cubemap)
|
||||
* .build(engine);
|
||||
*
|
||||
* scene.setSkybox(skybox);
|
||||
* </pre>
|
||||
*
|
||||
* Currently only {@link Texture} based sky boxes are supported.
|
||||
*
|
||||
* @see Scene
|
||||
* @see IndirectLight
|
||||
*/
|
||||
public class Skybox {
|
||||
private long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
Skybox(long nativeSkybox) {
|
||||
public Skybox(long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct a <code>Skybox</code> object instance.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct a <code>Skybox</code> object instance.
|
||||
*/
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the environment map (i.e. the skybox content).
|
||||
*
|
||||
* <p>The <code>Skybox</code> is rendered as though it were an infinitely large cube with the
|
||||
* camera inside it. This means that the cubemap which is mapped onto the cube's exterior
|
||||
* will appear mirrored. This follows the OpenGL conventions.</p>
|
||||
*
|
||||
* <p>The <code>cmgen</code> tool generates reflection maps by default which are therefore
|
||||
* ideal to use as skyboxes.</p>
|
||||
*
|
||||
* @param cubemap A cubemap {@link Texture}
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
* @see Texture
|
||||
*/
|
||||
@NonNull
|
||||
public Builder environment(@NonNull Texture texture) {
|
||||
nBuilderEnvironment(mNativeBuilder, texture.getNativeObject());
|
||||
public Builder environment(@NonNull Texture cubemap) {
|
||||
nBuilderEnvironment(mNativeBuilder, cubemap.getNativeObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the sun should be rendered. The sun can only be
|
||||
* rendered if there is at least one light of type {@link LightManager.Type#SUN} in
|
||||
* the {@link Scene}. The default value is <code>false</code>.
|
||||
*
|
||||
* @param show <code>true</code> if the sun should be rendered, <code>false</code> otherwise
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder showSun(boolean show) {
|
||||
nBuilderShowSun(mNativeBuilder, show);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Skybox</code> intensity when no {@link IndirectLight} is set
|
||||
*
|
||||
* <p>This call is ignored when an {@link IndirectLight} is set, otherwise it is used in
|
||||
* its place.</p>
|
||||
*
|
||||
* @param envIntensity Scale factor applied to the skybox texel values such that
|
||||
* the result is in cd/m<sup>2</sup> (lux) units (default = 30000)
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
* @see IndirectLight.Builder#intensity
|
||||
*/
|
||||
@NonNull
|
||||
public Builder intensity(float envIntensity) {
|
||||
nBuilderIntensity(mNativeBuilder, envIntensity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>Skybox</code> object
|
||||
*
|
||||
* @param engine the {@link Engine} to associate this <code>Skybox</code> with.
|
||||
*
|
||||
* @return A newly created <code>Skybox</code>object
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if the <code>Skybox</code> couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Skybox build(@NonNull Engine engine) {
|
||||
long nativeSkybox = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -75,14 +159,35 @@ public class Skybox {
|
||||
}
|
||||
}
|
||||
|
||||
public void setLayerMask(@IntRange(from = 0, to = 255) int select, @IntRange(from = 0, to = 255) int value) {
|
||||
nSetLayerMask(getNativeObject(), select & 0xff, value & 0xff);
|
||||
/**
|
||||
* Sets bits in a visibility mask. By default, this is <code>0x1</code>.
|
||||
* <p>This provides a simple mechanism for hiding or showing this <code>Skybox</code> in a
|
||||
* {@link Scene}.</p>
|
||||
*
|
||||
* <p>For example, to set bit 1 and reset bits 0 and 2 while leaving all other bits unaffected,
|
||||
* call: <code>setLayerMask(7, 2)</code>.</p>
|
||||
*
|
||||
* @param select the set of bits to affect
|
||||
* @param values the replacement values for the affected bits
|
||||
*
|
||||
* @see View#setVisibleLayers
|
||||
*/
|
||||
public void setLayerMask(@IntRange(from = 0, to = 255) int select, @IntRange(from = 0, to = 255) int values) {
|
||||
nSetLayerMask(getNativeObject(), select & 0xff, values & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the visibility mask bits
|
||||
*/
|
||||
public int getLayerMask() {
|
||||
return nGetLayerMask(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Skybox</code>'s intensity in cd/m<sup>2</sup>.
|
||||
*/
|
||||
public float getIntensity() { return nGetIntensity(getNativeObject()); }
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed Skybox");
|
||||
@@ -98,7 +203,9 @@ public class Skybox {
|
||||
private static native void nDestroyBuilder(long nativeSkyboxBuilder);
|
||||
private static native void nBuilderEnvironment(long nativeSkyboxBuilder, long nativeTexture);
|
||||
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
|
||||
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
|
||||
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
|
||||
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
|
||||
private static native int nGetLayerMask(long nativeSkybox);
|
||||
private static native float nGetIntensity(long nativeSkybox);
|
||||
}
|
||||
|
||||
@@ -16,36 +16,73 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
|
||||
/**
|
||||
* <code>Stream</code> is used to attach a native video stream to a filament {@link Texture}.
|
||||
*
|
||||
* @see Texture#setExternalStream
|
||||
* @see Engine#destroyStream
|
||||
*/
|
||||
public class Stream {
|
||||
private long mNativeObject;
|
||||
private long mNativeEngine;
|
||||
|
||||
/**
|
||||
* Represents the immutable stream type.
|
||||
*/
|
||||
public enum StreamType {
|
||||
/** Not synchronized but copy-free. Good for video. */
|
||||
NATIVE,
|
||||
|
||||
/** Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26. */
|
||||
TEXTURE_ID,
|
||||
|
||||
/** Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+. */
|
||||
ACQUIRED,
|
||||
};
|
||||
|
||||
Stream(long nativeStream, Engine engine) {
|
||||
mNativeObject = nativeStream;
|
||||
mNativeEngine = engine.getNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct an Stream object instance.
|
||||
*
|
||||
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
|
||||
* {@link #setAcquiredImage}.
|
||||
*
|
||||
* To create a {@link StreamType#NATIVE NATIVE} or {@link StreamType#TEXTURE_ID TEXTURE_ID} stream, call one of the <pre>stream</pre> methods
|
||||
* on the builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct an Stream object instance.
|
||||
*/
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepted types for the stream source:
|
||||
* - Android: SurfaceView
|
||||
* - Other: none
|
||||
* Creates a {@link StreamType#NATIVE NATIVE} stream. Native streams can sample data
|
||||
* directly from an opaque platform object such as a {@link android.graphics.SurfaceTexture SurfaceTexture}
|
||||
* on Android.
|
||||
*
|
||||
* @param streamSource an opaque native stream handle, e.g.: on Android this must be a
|
||||
* {@link android.graphics.SurfaceTexture SurfaceTexture} object
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
*/
|
||||
@NonNull
|
||||
public Builder stream(@NonNull Object streamSource) {
|
||||
@@ -56,24 +93,57 @@ public class Stream {
|
||||
throw new IllegalArgumentException("Invalid stream source: " + streamSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link StreamType#TEXTURE_ID TEXTURE_ID} stream. A copy stream will sample data from the supplied
|
||||
* external texture and copy it into an internal private texture.
|
||||
*
|
||||
* <p>Currently only OpenGL external texture ids are supported.</p>
|
||||
*
|
||||
* @param externalTextureId An opaque texture id (typically a GLuint created with
|
||||
* <code>glGenTextures()</code>) in a context shared with
|
||||
* filament -- in that case this texture's target must be
|
||||
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
*/
|
||||
@NonNull
|
||||
public Builder stream(long externalTextureId) {
|
||||
nBuilderStream(mNativeBuilder, externalTextureId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param width initial width of the incoming stream. Whether this value is used is
|
||||
* stream dependent. On Android, it must be set when using
|
||||
* {@link #stream(long)}
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder width(int width) {
|
||||
nBuilderWidth(mNativeBuilder, width);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param height initial height of the incoming stream. Whether this value is used is
|
||||
* stream dependent. On Android, it must be set when using
|
||||
* {@link #stream(long)}
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder height(int height) {
|
||||
nBuilderHeight(mNativeBuilder, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Stream</code> object instance.
|
||||
*
|
||||
* @param engine {@link Engine} instance to associate this <code>Stream</code> with.
|
||||
*
|
||||
* @return newly created <code>Stream</code> object
|
||||
* @exception IllegalStateException if the <code>Stream</code> couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Stream build(@NonNull Engine engine) {
|
||||
long nativeStream = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -99,14 +169,104 @@ public class Stream {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNative() {
|
||||
return nIsNative(getNativeObject());
|
||||
/**
|
||||
* Indicates whether this <code>Stream</code> is NATIVE, TEXTURE_ID, or ACQUIRED.
|
||||
*/
|
||||
public StreamType getStreamType() {
|
||||
return StreamType.values()[nGetStreamType(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an <pre>ACQUIRED</pre> stream with an image that is guaranteed to be used in the next frame.
|
||||
*
|
||||
* This method should be called on the same thread that calls {#link Renderer#beginFrame}, which is
|
||||
* also where the callback is invoked.
|
||||
*
|
||||
* @param hwbuffer {@link android.hardware.HardwareBuffer HardwareBuffer} (requires API level 26)
|
||||
* @param handler {@link java.util.concurrent.Executor Executor} or {@link android.os.Handler Handler}.
|
||||
* @param callback a callback invoked by <code>handler</code> when the <code>hwbuffer</code> can be released.
|
||||
*/
|
||||
public void setAcquiredImage(Object hwbuffer, Object handler, Runnable callback) {
|
||||
nSetAcquiredImage(getNativeObject(), mNativeEngine, hwbuffer, handler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the size of the incoming stream. Whether this value is used is
|
||||
* stream dependent. On Android, it must be set when using
|
||||
* {@link Builder#stream(long)}
|
||||
*
|
||||
* @param width new width of the incoming stream
|
||||
* @param height new height of the incoming stream
|
||||
*/
|
||||
public void setDimensions(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
|
||||
nSetDimensions(getNativeObject(), width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads back the content of the last frame of a <code>Stream</code> since the last call to
|
||||
* {@link Renderer#beginFrame}.
|
||||
*
|
||||
* <p>The Stream must be a copy stream, which can be checked with {@link #getStreamType()}.
|
||||
* This function is a no-op otherwise.</p>
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* Stream buffer User buffer (PixelBufferDescriptor)
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* <p>Typically readPixels() will be called after {@link Renderer#beginFrame}.</p>
|
||||
*
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link Renderer#beginFrame},
|
||||
* {@link Renderer#render}, {@link Renderer#endFrame}.</p>
|
||||
*
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@@ -128,6 +288,13 @@ public class Stream {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presentation time of the currently displayed frame in nanosecond.
|
||||
*
|
||||
* This value can change at any time.
|
||||
*
|
||||
* @return timestamp in nanosecond.
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return nGetTimestamp(getNativeObject());
|
||||
}
|
||||
@@ -151,6 +318,7 @@ public class Stream {
|
||||
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
|
||||
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetStreamType(long nativeStream);
|
||||
private static native void nSetDimensions(long nativeStream, int width, int height);
|
||||
private static native int nReadPixels(long nativeStream, long nativeEngine,
|
||||
int xoffset, int yoffset, int width, int height,
|
||||
@@ -158,6 +326,6 @@ public class Stream {
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native long nGetTimestamp(long nativeStream);
|
||||
|
||||
private static native boolean nIsNative(long nativeStream);
|
||||
private static native void nSetAcquiredImage(long nativeStream, long nativeEngine,
|
||||
Object hwbuffer, Object handler, Runnable callback);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.nio.Buffer;
|
||||
|
||||
/**
|
||||
* Helper used to populate <code>TANGENTS</code> buffers.
|
||||
*/
|
||||
public class SurfaceOrientation {
|
||||
private long mNativeObject;
|
||||
|
||||
private SurfaceOrientation(long nativeSurfaceOrientation) {
|
||||
mNativeObject = nativeSurfaceOrientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an immutable surface orientation helper.
|
||||
*
|
||||
* At a minimum, clients must supply a vertex count.
|
||||
* They can supply data in any of the following combinations:
|
||||
*
|
||||
* <ol>
|
||||
* <li>normals only (not recommended)</li>
|
||||
* <li>normals + tangents (sign of W determines bitangent orientation)</li>
|
||||
* <li>normals + uvs + positions + indices</li>
|
||||
* <li>positions + indices</li>
|
||||
* </ol>
|
||||
*
|
||||
* Additionally, the client-side data has the following type constraints:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Normals must be float3</li>
|
||||
* <li>Tangents must be float4</li>
|
||||
* <li>UVs must be float2</li>
|
||||
* <li>Positions must be float3</li>
|
||||
* <li>Triangles must be uint3 or ushort3</li>
|
||||
* </ol>
|
||||
*/
|
||||
public static class Builder {
|
||||
private int mVertexCount;
|
||||
private int mTriangleCount;
|
||||
|
||||
private Buffer mNormals;
|
||||
private int mNormalsStride;
|
||||
|
||||
private Buffer mTangents;
|
||||
private int mTangentsStride;
|
||||
|
||||
private Buffer mTexCoords;
|
||||
private int mTexCoordsStride;
|
||||
|
||||
private Buffer mPositions;
|
||||
private int mPositionsStride;
|
||||
|
||||
private Buffer mTrianglesUint16;
|
||||
private Buffer mTrianglesUint32;
|
||||
|
||||
@NonNull
|
||||
public Builder vertexCount(@IntRange(from = 1) int vertexCount) {
|
||||
mVertexCount = vertexCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder normals(@NonNull Buffer buffer) {
|
||||
mNormals = buffer;
|
||||
mNormalsStride = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder tangents(@NonNull Buffer buffer) {
|
||||
mTangents = buffer;
|
||||
mTangentsStride = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder uvs(@NonNull Buffer buffer) {
|
||||
mTexCoords = buffer;
|
||||
mTexCoordsStride = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder positions(@NonNull Buffer buffer) {
|
||||
mPositions = buffer;
|
||||
mPositionsStride = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder triangleCount(int triangleCount) {
|
||||
mTriangleCount = triangleCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder triangles_uint16(@NonNull Buffer buffer) {
|
||||
mTrianglesUint16 = buffer;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder triangles_uint32(@NonNull Buffer buffer) {
|
||||
mTrianglesUint32 = buffer;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the input data, produces quaternions, and destroys the native builder.
|
||||
*/
|
||||
@NonNull
|
||||
public SurfaceOrientation build() {
|
||||
|
||||
// The C++ Builder API specifies that the pointers are consumed during build(), not
|
||||
// during the individual daisy-chain methods. Therefore we need to retain the Java
|
||||
// buffers until this point in the code.
|
||||
|
||||
long builder = nCreateBuilder();
|
||||
nBuilderVertexCount(builder, mVertexCount);
|
||||
nBuilderTriangleCount(builder, mTriangleCount);
|
||||
|
||||
if (mNormals != null) {
|
||||
nBuilderNormals(builder, mNormals, mNormals.remaining(), mNormalsStride);
|
||||
}
|
||||
|
||||
if (mTangents != null) {
|
||||
nBuilderTangents(builder, mTangents, mTangents.remaining(), mTangentsStride);
|
||||
}
|
||||
|
||||
if (mTexCoords != null) {
|
||||
nBuilderUVs(builder, mTexCoords, mTexCoords.remaining(), mTexCoordsStride);
|
||||
}
|
||||
|
||||
if (mPositions != null) {
|
||||
nBuilderPositions(builder, mPositions, mPositions.remaining(), mPositionsStride);
|
||||
}
|
||||
|
||||
if (mTrianglesUint16 != null) {
|
||||
nBuilderTriangles16(builder, mTrianglesUint16, mTrianglesUint16.remaining());
|
||||
}
|
||||
|
||||
if (mTrianglesUint32 != null) {
|
||||
nBuilderTriangles32(builder, mTrianglesUint32, mTrianglesUint32.remaining());
|
||||
}
|
||||
|
||||
long nativeSurfaceOrientation = nBuilderBuild(builder);
|
||||
nDestroyBuilder(builder);
|
||||
if (nativeSurfaceOrientation == 0) {
|
||||
throw new IllegalStateException("Could not create SurfaceOrientation");
|
||||
}
|
||||
return new SurfaceOrientation(nativeSurfaceOrientation);
|
||||
}
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed SurfaceOrientation");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
@IntRange(from = 0)
|
||||
public int getVertexCount() {
|
||||
return nGetVertexCount(mNativeObject);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public void getQuatsAsFloat(@NonNull Buffer buffer) {
|
||||
nGetQuatsAsFloat(mNativeObject, buffer, buffer.remaining());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public void getQuatsAsHalf(@NonNull Buffer buffer) {
|
||||
nGetQuatsAsHalf(mNativeObject, buffer, buffer.remaining());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public void getQuatsAsShort(@NonNull Buffer buffer) {
|
||||
nGetQuatsAsShort(mNativeObject, buffer, buffer.remaining());
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
nDestroy(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
|
||||
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
|
||||
private static native void nBuilderNormals(long nativeBuilder, Buffer buffer, int remaining, int stride);
|
||||
private static native void nBuilderTangents(long nativeBuilder, Buffer buffer, int remaining, int stride);
|
||||
private static native void nBuilderUVs(long nativeBuilder, Buffer buffer, int remaining, int stride);
|
||||
private static native void nBuilderPositions(long nativeBuilder, Buffer buffer, int remaining, int stride);
|
||||
private static native void nBuilderTriangleCount(long nativeBuilder, int triangleCount);
|
||||
private static native void nBuilderTriangles16(long nativeBuilder, Buffer buffer, int remaining);
|
||||
private static native void nBuilderTriangles32(long nativeBuilder, Buffer buffer, int remaining);
|
||||
private static native long nBuilderBuild(long nativeBuilder);
|
||||
|
||||
private static native int nGetVertexCount(long nativeSurfaceOrientation);
|
||||
private static native void nGetQuatsAsFloat(long nativeSurfaceOrientation, Buffer buffer, int remaining);
|
||||
private static native void nGetQuatsAsHalf(long nativeSurfaceOrientation, Buffer buffer, int remaining);
|
||||
private static native void nGetQuatsAsShort(long nativeSurfaceOrientation, Buffer buffer, int remaining);
|
||||
private static native void nDestroy(long nativeSurfaceOrientation);
|
||||
}
|
||||
@@ -16,22 +16,84 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* A <code>SwapChain</code> represents an Operating System's <b>native</b> renderable surface.
|
||||
*
|
||||
* <p>Typically it's a native window or a view. Because a <code>SwapChain</code> is initialized
|
||||
* from a native object, it is given to filament as an <code>Object</code>, which must be of the
|
||||
* proper type for each platform filament is running on.</p>
|
||||
*
|
||||
* <code>
|
||||
* SwapChain swapChain = engine.createSwapChain(nativeWindow);
|
||||
* </code>
|
||||
*
|
||||
* <p>The <code>nativeWindow</code> parameter above must be of type:</p>
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr><th> Platform </th><th> nativeWindow type </th></tr>
|
||||
* <tr><td> Android </td><td>{@link android.view.Surface Surface}</td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
* <p>
|
||||
*
|
||||
* <h1>Examples</h1>
|
||||
*
|
||||
* <h2>Android</h2>
|
||||
*
|
||||
*
|
||||
* <p>A {@link android.view.Surface Surface} can be retrieved from a
|
||||
* {@link android.view.SurfaceView SurfaceView} or {@link android.view.SurfaceHolder SurfaceHolder}
|
||||
* easily using {@link android.view.SurfaceHolder#getSurface SurfaceHolder.getSurface()} and/or
|
||||
* {@link android.view.SurfaceView#getHolder SurfaceView.getHolder()}.</p>
|
||||
*
|
||||
* <p>To use a {@link android.view.TextureView Textureview} as a <code>SwapChain</code>, it is
|
||||
* necessary to first get its {@link android.graphics.SurfaceTexture SurfaceTexture},
|
||||
* for instance using {@link android.view.TextureView.SurfaceTextureListener SurfaceTextureListener}
|
||||
* and then create a {@link android.view.Surface Surface}:</p>
|
||||
*
|
||||
* <pre>
|
||||
* // using a TextureView.SurfaceTextureListener:
|
||||
* public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
|
||||
* mSurface = new Surface(surfaceTexture);
|
||||
* // mSurface can now be used with Engine.createSwapChain()
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see Engine
|
||||
*/
|
||||
public class SwapChain {
|
||||
private final Object mSurface;
|
||||
private long mNativeObject;
|
||||
|
||||
public static final long CONFIG_DEFAULT = 0x0;
|
||||
|
||||
/**
|
||||
* This flag indicates that the <code>SwapChain</code> must be allocated with an
|
||||
* alpha-channel.
|
||||
*/
|
||||
public static final long CONFIG_TRANSPARENT = 0x1;
|
||||
|
||||
/**
|
||||
* This flag indicates that the <code>SwapChain</code> may be used as a source surface
|
||||
* for reading back render results. This config must be set when creating
|
||||
* any <code>SwapChain</code> that will be used as the source for a blit operation.
|
||||
*
|
||||
* @see Renderer#copyFrame
|
||||
*/
|
||||
public static final long CONFIG_READABLE = 0x2;
|
||||
|
||||
SwapChain(long nativeSwapChain, @NonNull Object surface) {
|
||||
SwapChain(long nativeSwapChain, Object surface) {
|
||||
mNativeObject = nativeSwapChain;
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
/**
|
||||
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
|
||||
* for a headless SwapChain.
|
||||
*/
|
||||
public Object getNativeWindow() {
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
@@ -29,20 +29,145 @@ import java.nio.ByteBuffer;
|
||||
|
||||
import static com.google.android.filament.Texture.Type.COMPRESSED;
|
||||
|
||||
/**
|
||||
* Texture
|
||||
* <p>The <code>Texture</code> class supports:</p>
|
||||
* <ul>
|
||||
* <li>2D textures</li>
|
||||
* <li>3D textures</li>
|
||||
* <li>Cube maps</li>
|
||||
* <li>mip mapping</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* <h1>Usage example</h1>
|
||||
*
|
||||
* A <code>Texture</code> object is created using the {@link Texture.Builder} and destroyed by
|
||||
* calling {@link Engine#destroyTexture}. They're bound using {@link MaterialInstance#setParameter}.
|
||||
*
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
*
|
||||
* Material material = new Material.Builder()
|
||||
* .payload( ... )
|
||||
* .build(ending);
|
||||
*
|
||||
* MaterialInstance mi = material.getDefaultInstance();
|
||||
*
|
||||
* Texture texture = new Texture.Builder()
|
||||
* .width(64)
|
||||
* .height(64)
|
||||
* .build(engine);
|
||||
*
|
||||
*
|
||||
* texture.setImage(engine, 0,
|
||||
* new Texture.PixelBufferDescriptor( ... ));
|
||||
*
|
||||
* mi.setParameter("parameterName", texture, new TextureSampler());
|
||||
* </pre>
|
||||
*
|
||||
* @see #setImage
|
||||
* @see PixelBufferDescriptor
|
||||
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
|
||||
*/
|
||||
public class Texture {
|
||||
private long mNativeObject;
|
||||
|
||||
@UsedByReflection("KtxLoader.java")
|
||||
Texture(long nativeTexture) {
|
||||
public Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of sampler
|
||||
*/
|
||||
public enum Sampler {
|
||||
/** 2D sampler */
|
||||
SAMPLER_2D,
|
||||
/** 2D array sampler */
|
||||
SAMPLER_2D_ARRAY,
|
||||
/** Cubemap sampler */
|
||||
SAMPLER_CUBEMAP,
|
||||
/** External texture sampler */
|
||||
SAMPLER_EXTERNAL
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal texel formats
|
||||
*
|
||||
* <p>These formats are used to specify a texture's internal storage format.</p>
|
||||
*
|
||||
* <h1>Enumerants syntax format</h1>
|
||||
*
|
||||
* <code>[components][size][type]</code>
|
||||
* <br><code>components</code> : List of stored components by this format
|
||||
* <br><code>size</code> : Size in bit of each component
|
||||
* <br><code>type</code> : Type this format is stored as
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr><th> Name </th><th> Component </th></tr>
|
||||
* <tr><td> R </td><td> Linear Red </td></tr>
|
||||
* <tr><td> RG </td><td> Linear Red, Green </td></tr>
|
||||
* <tr><td> RGB </td><td> Linear Red, Green, Blue </td></tr>
|
||||
* <tr><td> RGBA </td><td> Linear Red, Green Blue, Alpha </td></tr>
|
||||
* <tr><td> SRGB </td><td> sRGB encoded Red, Green, Blue </td></tr>
|
||||
* <tr><td> DEPTH </td><td> Depth </td></tr>
|
||||
* <tr><td> STENCIL </td><td> Stencil </td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
* <br>
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr><th> Name </th><th> Type </th></tr>
|
||||
* <tr><td> (none) </td><td> Unsigned Normalized Integer [0, 1] </th></tr>
|
||||
* <tr><td> _SNORM </td><td> Signed Normalized Integer [-1, 1] </td></tr>
|
||||
* <tr><td> UI </td><td> Unsigned Integer [0, 2<sup>size</sup>] </td></tr>
|
||||
* <tr><td> I </td><td> Signed Integer [-2<sup>size-1</sup>, 2<sup>size-1</sup>-1] </td></tr>
|
||||
* <tr><td> F </td><td> Floating-point </td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
* <br>
|
||||
*
|
||||
* <h1>Special color formats</h1>
|
||||
*
|
||||
* There are a few special color formats that don't follow the convention above:
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr><th> Name </th><th> Format </th></tr>
|
||||
* <tr><td> RGB565 </td><td> 5-bits for R and B, 6-bits for G. </td></tr>
|
||||
* <tr><td> RGB5_A1 </td><td> 5-bits for R, G and B, 1-bit for A. </td></tr>
|
||||
* <tr><td> RGB10_A2 </td><td> 10-bits for R, G and B, 2-bits for A. </td></tr>
|
||||
* <tr><td> RGB9_E5 </td><td> <b>Unsigned</b> floating point. 9-bits mantissa for RGB, 5-bits shared exponent </td></tr>
|
||||
* <tr><td> R11F_G11F_B10F </td><td> <b>Unsigned</b> floating point. 6-bits mantissa, for R and G, 5-bits for B. 5-bits exponent. </td></tr>
|
||||
* <tr><td> SRGB8_A8 </td><td> sRGB 8-bits with linear 8-bits alpha. </td></tr>
|
||||
* <tr><td> DEPTH24_STENCIL8 </td><td> 24-bits unsigned normalized integer depth, 8-bits stencil. </td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
* <br>
|
||||
*
|
||||
* <h1>Compressed texture formats</h1>
|
||||
*
|
||||
* Many compressed texture formats are supported as well, which include (but are not limited to)
|
||||
* the following list:
|
||||
*
|
||||
* <center>
|
||||
* <table border="1">
|
||||
* <tr><th> Name </th><th> Format </th></tr>
|
||||
* <tr><td> EAC_R11 </td><td> Compresses R11UI </td></tr>
|
||||
* <tr><td> EAC_R11_SIGNED </td><td> Compresses R11I </td></tr>
|
||||
* <tr><td> EAC_RG11 </td><td> Compresses RG11UI </td></tr>
|
||||
* <tr><td> EAC_RG11_SIGNED </td><td> Compresses RG11I </td></tr>
|
||||
* <tr><td> ETC2_RGB8 </td><td> Compresses RGB8 </td></tr>
|
||||
* <tr><td> ETC2_SRGB8 </td><td> compresses SRGB8 </td></tr>
|
||||
* <tr><td> ETC2_EAC_RGBA8 </td><td> Compresses RGBA8 </td></tr>
|
||||
* <tr><td> ETC2_EAC_SRGBA8 </td><td> Compresses SRGB8_A8 </td></tr>
|
||||
* <tr><td> ETC2_RGB8_A1 </td><td> Compresses RGB8 with 1-bit alpha </td></tr>
|
||||
* <tr><td> ETC2_SRGB8_A1 </td><td> Compresses sRGB8 with 1-bit alpha </td></tr>
|
||||
* </table>
|
||||
* </center>
|
||||
*/
|
||||
public enum InternalFormat {
|
||||
// 8-bits per element
|
||||
R8, R8_SNORM, R8UI, R8I, STENCIL8,
|
||||
@@ -92,6 +217,10 @@ public class Texture {
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
|
||||
}
|
||||
|
||||
/**
|
||||
* Compressed data types for use with {@link PixelBufferDescriptor}
|
||||
* @see InternalFormat
|
||||
*/
|
||||
public enum CompressedFormat {
|
||||
// Mandatory in GLES 3.0 and GL 4.3
|
||||
EAC_R11, EAC_R11_SIGNED, EAC_RG11, EAC_RG11_SIGNED,
|
||||
@@ -103,15 +232,27 @@ public class Texture {
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
|
||||
}
|
||||
|
||||
/**
|
||||
* Cubemap faces
|
||||
*/
|
||||
public enum CubemapFace {
|
||||
/** +x face */
|
||||
POSITIVE_X,
|
||||
/** -x face */
|
||||
NEGATIVE_X,
|
||||
/** +y face */
|
||||
POSITIVE_Y,
|
||||
/** -y face */
|
||||
NEGATIVE_Y,
|
||||
/** +z face */
|
||||
POSITIVE_Z,
|
||||
/** -z face */
|
||||
NEGATIVE_Z
|
||||
}
|
||||
|
||||
/**
|
||||
* Pixel color format
|
||||
*/
|
||||
public enum Format {
|
||||
R,
|
||||
R_INTEGER,
|
||||
@@ -128,19 +269,43 @@ public class Texture {
|
||||
ALPHA
|
||||
}
|
||||
|
||||
/**
|
||||
* Pixel data type
|
||||
*/
|
||||
public enum Type {
|
||||
/** unsigned byte, 8-bits */
|
||||
UBYTE,
|
||||
/** signed byte, 8-bits */
|
||||
BYTE,
|
||||
/** unsigned short, 16-bits */
|
||||
USHORT,
|
||||
/** signed short, 16-bits */
|
||||
SHORT,
|
||||
/** unsigned int, 32-bits */
|
||||
UINT,
|
||||
/** signed int, 32-bits */
|
||||
INT,
|
||||
/** half-float, 16-bits float with 10 bits mantissa */
|
||||
HALF,
|
||||
/** float, 32-bits float, with 24 bits mantissa */
|
||||
FLOAT,
|
||||
/** a compessed type */
|
||||
COMPRESSED,
|
||||
/** unsigned 5.6 (5.5 for blue) float packed in 32-bits */
|
||||
UINT_10F_11F_11F_REV
|
||||
}
|
||||
|
||||
/**
|
||||
* A descriptor to an image in main memory, typically used to transfer image data from the CPU
|
||||
* to the GPU.
|
||||
* <p>A <code>PixelBufferDescriptor</code> owns the memory buffer it references,
|
||||
* therefore <code>PixelBufferDescriptor</code> cannot be copied, but can be moved.</p>
|
||||
*
|
||||
* <code>PixelBufferDescriptor</code> releases ownership of the memory-buffer when it's
|
||||
* destroyed.
|
||||
*
|
||||
* @see #setImage
|
||||
*/
|
||||
public static class PixelBufferDescriptor {
|
||||
public Buffer storage;
|
||||
|
||||
@@ -158,12 +323,39 @@ public class Texture {
|
||||
public CompressedFormat compressedFormat;
|
||||
|
||||
@Nullable public Object handler;
|
||||
@Nullable public Runnable callback;
|
||||
|
||||
/**
|
||||
* Valid handler types:
|
||||
* - Android: Handler, Executor
|
||||
* - Other: Executor
|
||||
* Callback used to destroy the buffer data.
|
||||
* <p>
|
||||
* Guarantees:
|
||||
* <ul>
|
||||
* <li>Called on the main filament thread.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Limitations:
|
||||
* <ul>
|
||||
* <li>Must be lightweight.</li>
|
||||
* <li>Must not call filament APIs.</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
@Nullable public Runnable callback;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a <code>PixelBufferDescriptor</code>
|
||||
*
|
||||
* @param storage CPU-side buffer containing the image data to upload into the texture
|
||||
* @param format Pixel {@link Format format} of the CPU-side image
|
||||
* @param type Pixel data {@link Type type} of the CPU-side image
|
||||
* @param alignment Row-alignment in bytes of the CPU-side image (1 to 8 bytes)
|
||||
* @param left Left coordinate in pixels of the CPU-side image
|
||||
* @param top Top coordinate in pixels of the CPU-side image
|
||||
* @param stride Stride in pixels of the CPU-side image (i.e. distance in pixels to the next row)
|
||||
* @param handler An {@link java.util.concurrent.Executor Executor}. On Android this can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback A callback executed by <code>handler</code> when <code>storage</code> is no longer needed.
|
||||
*/
|
||||
public PixelBufferDescriptor(@NonNull Buffer storage,
|
||||
@NonNull Format format, @NonNull Type type,
|
||||
@@ -182,17 +374,48 @@ public class Texture {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>PixelBufferDescriptor</code> with some default values and no callback.
|
||||
*
|
||||
* @param storage CPU-side buffer containing the image data to upload into the texture
|
||||
* @param format Pixel {@link Format format} of the CPU-side image
|
||||
* @param type Pixel data {@link Type type} of the CPU-side image
|
||||
*
|
||||
* @see #setCallback
|
||||
*/
|
||||
public PixelBufferDescriptor(@NonNull Buffer storage,
|
||||
@NonNull Format format, @NonNull Type type) {
|
||||
this(storage, format, type, 1, 0, 0, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>PixelBufferDescriptor</code> with some default values and no callback.
|
||||
*
|
||||
* @param storage CPU-side buffer containing the image data to upload into the texture
|
||||
* @param format Pixel {@link Format format} of the CPU-side image
|
||||
* @param type Pixel data {@link Type type} of the CPU-side image
|
||||
* @param alignment Row-alignment in bytes of the CPU-side image (1 to 8 bytes)
|
||||
*
|
||||
* @see #setCallback
|
||||
*/
|
||||
public PixelBufferDescriptor(@NonNull Buffer storage,
|
||||
@NonNull Format format, @NonNull Type type,
|
||||
@IntRange(from = 1, to = 8) int alignment) {
|
||||
this(storage, format, type, alignment, 0, 0, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>PixelBufferDescriptor</code> with some default values and no callback.
|
||||
*
|
||||
* @param storage CPU-side buffer containing the image data to upload into the texture
|
||||
* @param format Pixel {@link Format format} of the CPU-side image
|
||||
* @param type Pixel data {@link Type type} of the CPU-side image
|
||||
* @param alignment Row-alignment in bytes of the CPU-side image (1 to 8 bytes)
|
||||
* @param left Left coordinate in pixels of the CPU-side image
|
||||
* @param top Top coordinate in pixels of the CPU-side image
|
||||
*
|
||||
* @see #setCallback
|
||||
*/
|
||||
public PixelBufferDescriptor(@NonNull Buffer storage,
|
||||
@NonNull Format format, @NonNull Type type,
|
||||
@IntRange(from = 1, to = 8) int alignment,
|
||||
@@ -200,6 +423,14 @@ public class Texture {
|
||||
this(storage, format, type, alignment, left, top, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param storage CPU-side buffer containing the image data to upload into the texture
|
||||
* @param format Compressed pixel {@link CompressedFormat format} of the CPU-side image
|
||||
* @param compressedSizeInBytes Size of the compressed data in bytes
|
||||
*
|
||||
* @see #setCallback
|
||||
*/
|
||||
public PixelBufferDescriptor(@NonNull ByteBuffer storage,
|
||||
@NonNull CompressedFormat format,
|
||||
@IntRange(from = 0) int compressedSizeInBytes) {
|
||||
@@ -211,9 +442,10 @@ public class Texture {
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid handler types:
|
||||
* - Android: Handler, Executor
|
||||
* - Other: Executor
|
||||
* Set or replace the callback called when the CPU-side data is no longer needed.
|
||||
*
|
||||
* @param handler An {@link java.util.concurrent.Executor Executor}. On Android this can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback A callback executed by <code>handler</code> when <code>storage</code> is no longer needed.
|
||||
*/
|
||||
public void setCallback(@Nullable Object handler, @Nullable Runnable callback) {
|
||||
this.handler = handler;
|
||||
@@ -288,57 +520,113 @@ public class Texture {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options of {@link #generatePrefilterMipmap}
|
||||
*/
|
||||
public static class PrefilterOptions {
|
||||
/** number of samples for roughness pre-filtering */
|
||||
public int sampleCount = 8;
|
||||
/** whether to generate a reflection map (mirror) */
|
||||
public boolean mirror = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given format is supported for texturing in this {@link Engine}.
|
||||
* This depends on the selected backend.
|
||||
*
|
||||
* @param engine {@link Engine} to test the {@link InternalFormat InternalFormat} against
|
||||
* @param format format to check
|
||||
* @return <code>true</code> if this format is supported for texturing.
|
||||
*/
|
||||
public static boolean isTextureFormatSupported(@NonNull Engine engine,
|
||||
@NonNull InternalFormat format) {
|
||||
return nIsTextureFormatSupported(engine.getNativeObject(), format.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct a <code>Texture</code> object instance.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct a <code>Texture</code> object instance.
|
||||
*/
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the width of the texture in texels.
|
||||
* @param width texture width in texels, must be at least 1. Default is 1.
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder width(@IntRange(from = 1) int width) {
|
||||
nBuilderWidth(mNativeBuilder, width);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the height of the texture in texels.
|
||||
* @param height texture height in texels, must be at least 1. Default is 1.
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder height(@IntRange(from = 1) int height) {
|
||||
nBuilderHeight(mNativeBuilder, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the texture's number of layers. Values greater than 1 create a 3D texture.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use
|
||||
* {@link Sampler#SAMPLER_2D_ARRAY SAMPLER_2D_ARRAY} or it has no effect.</p>
|
||||
*
|
||||
* @param depth texture number of layers. Default is 1.
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder depth(@IntRange(from = 1) int depth) {
|
||||
nBuilderDepth(mNativeBuilder, depth);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the number of mipmap levels
|
||||
* @param levels must be at least 1 and less or equal to <code>floor(log<sub>2</sub>(max(width, height))) + 1</code>. Default is 1.
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder levels(@IntRange(from = 1) int levels) {
|
||||
nBuilderLevels(mNativeBuilder, levels);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the type of sampler to use.
|
||||
* @param target {@link Sampler Sampler} type
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder sampler(@NonNull Sampler target) {
|
||||
nBuilderSampler(mNativeBuilder, target.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the texture's internal format.
|
||||
* <p>The internal format specifies how texels are stored (which may be different from how
|
||||
* they're specified in {@link #setImage}). {@link InternalFormat InternalFormat} specifies
|
||||
* both the color components and the data type used.</p>
|
||||
* @param format texture's {@link InternalFormat internal format}.
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder format(@NonNull InternalFormat format) {
|
||||
nBuilderFormat(mNativeBuilder, format.ordinal());
|
||||
@@ -356,6 +644,13 @@ public class Texture {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Texture</code> instance.
|
||||
* @param engine The {@link Engine} to associate this <code>Texture</code> with.
|
||||
* @return A newly created <code>Texture</code>
|
||||
* @exception IllegalStateException if a parameter to a builder function was invalid.
|
||||
* A mode detailed message about the error is output in the system log.
|
||||
*/
|
||||
@NonNull
|
||||
public Texture build(@NonNull Engine engine) {
|
||||
long nativeTexture = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -382,38 +677,71 @@ public class Texture {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitmask to specify how the texture will be used.
|
||||
*/
|
||||
public static class Usage {
|
||||
/** The texture will be used as a color attachment */
|
||||
public static final int COLOR_ATTACHMENT = 0x1;
|
||||
/** The texture will be used as a depth attachment */
|
||||
public static final int DEPTH_ATTACHMENT = 0x2;
|
||||
/** The texture will be used as a stencil attachment */
|
||||
public static final int STENCIL_ATTACHMENT = 0x4;
|
||||
/** The texture content can be set with {@link #setImage} */
|
||||
public static final int UPLOADABLE = 0x8;
|
||||
/** The texture can be read from a shader or blitted from */
|
||||
public static final int SAMPLEABLE = 0x10;
|
||||
/** by default textures are <code>UPLOADABLE</code> and <code>SAMPLEABLE</code>*/
|
||||
public static final int DEFAULT = UPLOADABLE | SAMPLEABLE;
|
||||
}
|
||||
|
||||
public static final int BASE_LEVEL = 0;
|
||||
|
||||
/**
|
||||
* Queries the width of a given level of this texture.
|
||||
* @param level to query the with of. Must be between 0 and {@link #getLevels}
|
||||
* @return The width in texel of the given level
|
||||
*/
|
||||
public int getWidth(@IntRange(from = 0) int level) {
|
||||
return nGetWidth(getNativeObject(), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the height of a given level of this texture.
|
||||
* @param level to query the height of. Must be between 0 and {@link #getLevels}
|
||||
* @return The height in texel of the given level
|
||||
*/
|
||||
public int getHeight(@IntRange(from = 0) int level) {
|
||||
return nGetHeight(getNativeObject(), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the number of layers of given level of this texture has.
|
||||
* @param level to query the number of layers of. Must be between 0 and {@link #getLevels}
|
||||
* @return The number of layers of the given level
|
||||
*/
|
||||
public int getDepth(@IntRange(from = 0) int level) {
|
||||
return nGetDepth(getNativeObject(), level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of mipmap levels of this texture
|
||||
*/
|
||||
public int getLevels() {
|
||||
return nGetLevels(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return This texture {@link Sampler Sampler} type.
|
||||
*/
|
||||
@NonNull
|
||||
public Sampler getTarget() {
|
||||
return Sampler.values()[nGetTarget(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return This texture's {@link InternalFormat InternalFormat}.
|
||||
*/
|
||||
@NonNull
|
||||
public InternalFormat getFormat() {
|
||||
return InternalFormat.values()[nGetInternalFormat(getNativeObject())];
|
||||
@@ -421,12 +749,65 @@ public class Texture {
|
||||
|
||||
// TODO: add a setImage() version that takes an android Bitmap
|
||||
|
||||
/**
|
||||
* <code>setImage</code> is used to modify the whole content of the texure from a CPU-buffer.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D SAMPLER_2D} or
|
||||
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}. If the later is specified
|
||||
* and external textures are supported by the driver implementation,
|
||||
* this method will have no effect, otherwise it will behave as if the
|
||||
* texture was specified with {@link Sampler#SAMPLER_2D SAMPLER_2D}.</p>
|
||||
*
|
||||
* This is equivalent to calling: <br>
|
||||
*
|
||||
* <code>setImage(engine, level, 0, 0, getWidth(level), getHeight(level), buffer)</code>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
|
||||
* @param buffer Client-side buffer containing the image to set.
|
||||
* <code>buffer</code>'s {@link Format format} must match that
|
||||
* of {@link #getFormat()}
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*
|
||||
* @see Builder#sampler
|
||||
* @see PixelBufferDescriptor
|
||||
*/
|
||||
public void setImage(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int level,
|
||||
@NonNull PixelBufferDescriptor buffer) {
|
||||
setImage(engine, level, 0, 0, getWidth(level), getHeight(level), buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <code>setImage</code> is used to modify a sub-region of the texure from a CPU-buffer.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D SAMPLER_2D} or
|
||||
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}. If the later is specified
|
||||
* and external textures are supported by the driver implementation,
|
||||
* this method will have no effect, otherwise it will behave as if the
|
||||
* texture was specified with {@link Sampler#SAMPLER_2D SAMPLER_2D}.</p>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
|
||||
* @param xoffset x-offset in texel of the region to modify
|
||||
* @param yoffset y-offset in texel of the region to modify
|
||||
* @param width width in texel of the region to modify
|
||||
* @param height height in texel of the region to modify
|
||||
* @param buffer Client-side buffer containing the image to set.
|
||||
* <code>buffer</code>'s {@link Format format} must match that
|
||||
* of {@link #getFormat()}
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*
|
||||
* @see Builder#sampler
|
||||
* @see PixelBufferDescriptor
|
||||
*/
|
||||
public void setImage(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@@ -453,9 +834,33 @@ public class Texture {
|
||||
}
|
||||
}
|
||||
|
||||
// note: faceOffsetsInBytes are offsets in byte in the buffer relative to the current position()
|
||||
// note: use Texture CubemapFace to index the faceOffsetsInBytes array
|
||||
// note: we assume all 6 faces are tightly packed
|
||||
/**
|
||||
* <code>setImage</code> is used to specify all six images of a cubemap level and
|
||||
* follows exactly the OpenGL conventions
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use
|
||||
* {@link Sampler#SAMPLER_CUBEMAP SAMPLER_CUBEMAP}.</p>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
|
||||
* @param buffer Client-side buffer containing the image to set.
|
||||
* <code>buffer</code>'s {@link Format format} must match that
|
||||
* of {@link #getFormat()}
|
||||
* @param faceOffsetsInBytes Offsets in bytes into <code>buffer</code> for all six images.
|
||||
* The offsets are specified in the following order:
|
||||
* +x, -x, +y, -y, +z, -z.
|
||||
*
|
||||
* <p><code>faceOffsetsInBytes</code> are offsets in byte in the <code>buffer</code> relative
|
||||
* to the current {@link Buffer#position()}. Use {@link CubemapFace} to index the
|
||||
* <code>faceOffsetsInBytes</code> array. All six faces must be tightly packed.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*
|
||||
* @see Builder#sampler
|
||||
* @see PixelBufferDescriptor
|
||||
*/
|
||||
public void setImage(@NonNull Engine engine, @IntRange(from = 0) int level,
|
||||
@NonNull PixelBufferDescriptor buffer,
|
||||
@NonNull @Size(min = 6) int[] faceOffsetsInBytes) {
|
||||
@@ -478,10 +883,60 @@ public class Texture {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the external image to associate with this <code>Texture</code>.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use
|
||||
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}.</p>
|
||||
* <p>Typically the external image is OS specific, and can be a video or camera frame.
|
||||
* There are many restrictions when using an external image as a texture, such as:</p>
|
||||
* <ul>
|
||||
* <li> only the level of detail (LOD) 0 can be specified</li>
|
||||
* <li> only {@link TextureSampler.MagFilter#NEAREST NEAREST} or
|
||||
* {@link TextureSampler.MagFilter#LINEAR LINEAR} filtering is supported</li>
|
||||
* <li> the size and format of the texture is defined by the external image</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param eglImage An opaque handle to a platform specific image. Supported types are
|
||||
* <code>eglImageOES</code> on Android and <code>CVPixelBufferRef</code> on iOS.
|
||||
* <p>On iOS the following pixel formats are supported: <ul>
|
||||
* <li><code>kCVPixelFormatType_32BGRA</code></li>
|
||||
* <li><code>kCVPixelFormatType_420YpCbCr8BiPlanarFullRange</code></li>
|
||||
* </ul></p>
|
||||
*
|
||||
* @see Builder#sampler
|
||||
*/
|
||||
public void setExternalImage(@NonNull Engine engine, long eglImage) {
|
||||
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the external stream to associate with this <code>Texture</code>.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must use
|
||||
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}.</p>
|
||||
* <p>Typically the external image is OS specific, and can be a video or camera frame.
|
||||
* There are many restrictions when using an external image as a texture, such as:</p>
|
||||
* <ul>
|
||||
* <li> only the level of detail (LOD) 0 can be specified</li>
|
||||
* <li> only {@link TextureSampler.MagFilter#NEAREST NEAREST} or
|
||||
* {@link TextureSampler.MagFilter#LINEAR LINEAR} filtering is supported</li>
|
||||
* <li> the size and format of the texture is defined by the external image</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param stream A {@link Stream} object
|
||||
*
|
||||
* @exception IllegalStateException if the sampler type is not
|
||||
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}
|
||||
*
|
||||
* @see Stream
|
||||
* @see Builder#sampler
|
||||
*
|
||||
*/
|
||||
public void setExternalStream(@NonNull Engine engine, @NonNull Stream stream) {
|
||||
long nativeObject = getNativeObject();
|
||||
long streamNativeObject = stream.getNativeObject();
|
||||
@@ -492,10 +947,68 @@ public class Texture {
|
||||
nSetExternalStream(nativeObject, engine.getNativeObject(), streamNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates all the mipmap levels automatically. This requires the texture to have a
|
||||
* color-renderable format.
|
||||
*
|
||||
* <p>This <code>Texture</code> instance must <b>not</b> use
|
||||
* {@link Sampler#SAMPLER_CUBEMAP SAMPLER_CUBEMAP}, or it has no effect.</p>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
*/
|
||||
public void generateMipmaps(@NonNull Engine engine) {
|
||||
nGenerateMipmaps(getNativeObject(), engine.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a reflection map from an environment map.
|
||||
*
|
||||
* <p>This is a utility function that replaces calls to {@link #setImage}.
|
||||
* The provided environment map is processed and all mipmap levels are populated. The
|
||||
* processing is similar to the offline tool <code>cmgen</code> at a lower quality setting.</p>
|
||||
*
|
||||
* <p>This function is intended to be used when the environment cannot be processed offline,
|
||||
* for instance if it's generated at runtime.</p>
|
||||
*
|
||||
* <p>The source data must obey to some constraints:</p>
|
||||
* <ul>
|
||||
* <li>the data {@link Format format} must be {@link Format#RGB}</li>
|
||||
* <li>the data {@link Type type} must be one of
|
||||
* <ul>
|
||||
* <li>{@link Type#FLOAT}</li>
|
||||
* <li>{@link Type#HALF}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>The current texture must be a cubemap.</p>
|
||||
*
|
||||
* <p>The reflections cubemap's {@link InternalFormat internal format} cannot be a compressed format.</p>
|
||||
*
|
||||
* <p>The reflections cubemap's dimension must be a power-of-two.</p>
|
||||
*
|
||||
* <p>This operation is computationally intensive, especially with large environments and
|
||||
* is currently <b>synchronous</b>. Expect about 1ms for a 16 × 16 cubemap.</p>
|
||||
*
|
||||
* @param engine {@link Engine} this texture is associated to. Must be the
|
||||
* instance passed to {@link Builder#build Builder.build()}.
|
||||
* @param buffer Client-side buffer containing the image to set.
|
||||
* <code>buffer</code>'s {@link Format format} and {@link Type type} must match
|
||||
* the constraints above.
|
||||
* @param faceOffsetsInBytes Offsets in bytes into <code>buffer</code> for all six images.
|
||||
* The offsets are specified in the following order:
|
||||
* +x, -x, +y, -y, +z, -z.
|
||||
*
|
||||
* @param options Optional parameter to control user-specified quality and options.
|
||||
*
|
||||
* <p><code>faceOffsetsInBytes</code> are offsets in byte in the <code>buffer</code> relative
|
||||
* to the current {@link Buffer#position()}. Use {@link CubemapFace} to index the
|
||||
* <code>faceOffsetsInBytes</code> array. All six faces must be tightly packed.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void generatePrefilterMipmap(@NonNull Engine engine,
|
||||
@NonNull PixelBufferDescriptor buffer, @NonNull @Size(min = 6) int[] faceOffsetsInBytes,
|
||||
PrefilterOptions options) {
|
||||
|
||||
@@ -16,26 +16,62 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* <code>TextureSampler</code> defines how a texture is accessed.
|
||||
*/
|
||||
public class TextureSampler {
|
||||
public enum WrapMode {
|
||||
/**
|
||||
* The edge of the texture extends to infinity.
|
||||
*/
|
||||
CLAMP_TO_EDGE,
|
||||
/**
|
||||
* The texture infinitely repeats in the wrap direction.
|
||||
*/
|
||||
REPEAT,
|
||||
/**
|
||||
* The texture infinitely repeats and mirrors in the wrap direction.
|
||||
*/
|
||||
MIRRORED_REPEAT
|
||||
}
|
||||
|
||||
public enum MinFilter {
|
||||
/**
|
||||
* No filtering. Nearest neighbor is used.
|
||||
*/
|
||||
NEAREST,
|
||||
/**
|
||||
* Box filtering. Weighted average of 4 neighbors is used.
|
||||
*/
|
||||
LINEAR,
|
||||
/**
|
||||
* Mip-mapping is activated. But no filtering occurs.
|
||||
*/
|
||||
NEAREST_MIPMAP_NEAREST,
|
||||
/**
|
||||
* Box filtering within a mip-map level.
|
||||
*/
|
||||
LINEAR_MIPMAP_NEAREST,
|
||||
/**
|
||||
* Mip-map levels are interpolated, but no other filtering occurs.
|
||||
*/
|
||||
NEAREST_MIPMAP_LINEAR,
|
||||
/**
|
||||
* Both interpolated Mip-mapping and linear filtering are used.
|
||||
*/
|
||||
LINEAR_MIPMAP_LINEAR,
|
||||
}
|
||||
|
||||
public enum MagFilter {
|
||||
/**
|
||||
* No filtering. Nearest neighbor is used.
|
||||
*/
|
||||
NEAREST,
|
||||
/**
|
||||
* Box filtering. Weighted average of 4 neighbors is used.
|
||||
*/
|
||||
LINEAR
|
||||
}
|
||||
|
||||
@@ -44,114 +80,246 @@ public class TextureSampler {
|
||||
COMPARE_TO_TEXTURE
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison functions for the depth sampler.
|
||||
*/
|
||||
public enum CompareFunction {
|
||||
/**
|
||||
* Less or equal
|
||||
*/
|
||||
LESS_EQUAL,
|
||||
/**
|
||||
* Greater or equal
|
||||
*/
|
||||
GREATER_EQUAL,
|
||||
/**
|
||||
* Strictly less than
|
||||
*/
|
||||
LESS,
|
||||
/**
|
||||
* Strictly greater than
|
||||
*/
|
||||
GREATER,
|
||||
/**
|
||||
* Equal
|
||||
*/
|
||||
EQUAL,
|
||||
/**
|
||||
* Not equal
|
||||
*/
|
||||
NOT_EQUAL,
|
||||
/**
|
||||
* Always. Depth testing is deactivated.
|
||||
*/
|
||||
ALWAYS,
|
||||
/**
|
||||
* Never. The depth test always fails.
|
||||
*/
|
||||
NEVER
|
||||
}
|
||||
|
||||
int mSampler = 0; // bit field used by native
|
||||
|
||||
/**
|
||||
* Min filter: LINEAR_MIPMAP_LINEAR
|
||||
* Mag filter: LINEAR
|
||||
* Wrap mode: REPEAT
|
||||
* Initializes the <code>TextureSampler</code> with default values.
|
||||
* <br>Minification filter: {@link MinFilter#LINEAR_MIPMAP_LINEAR}
|
||||
* <br>Magnification filter: {@link MagFilter#LINEAR}
|
||||
* <br>Wrap modes: {@link WrapMode#REPEAT}
|
||||
*/
|
||||
public TextureSampler() {
|
||||
this(MinFilter.LINEAR_MIPMAP_LINEAR, MagFilter.LINEAR, WrapMode.REPEAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with default values, but specifying the
|
||||
* minification and magnification filters.
|
||||
*
|
||||
* @param minMag {@link MagFilter magnification filter},
|
||||
* the minification filter will be set to the same value.
|
||||
*/
|
||||
public TextureSampler(@NonNull MagFilter minMag) {
|
||||
this(minMag, WrapMode.CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with user specified values.
|
||||
*
|
||||
* @param minMag {@link MagFilter magnification filter},
|
||||
* the minification filter will be set to the same value.
|
||||
* @param wrap {@link WrapMode wrapping mode} for all directions
|
||||
*/
|
||||
public TextureSampler(@NonNull MagFilter minMag, @NonNull WrapMode wrap) {
|
||||
this(minFilterFromMagFilter(minMag), minMag, wrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with user specified values.
|
||||
*
|
||||
* @param min {@link MagFilter magnification filter}
|
||||
* @param mag {@link MinFilter minification filter}
|
||||
* @param wrap {@link WrapMode wrapping mode} for all directions
|
||||
*/
|
||||
public TextureSampler(@NonNull MinFilter min, @NonNull MagFilter mag, @NonNull WrapMode wrap) {
|
||||
this(min, mag, wrap, wrap, wrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with user specified values.
|
||||
*
|
||||
* @param min {@link MagFilter magnification filter}
|
||||
* @param mag {@link MinFilter minification filter}
|
||||
* @param s {@link WrapMode wrapping mode} for the s (horizontal) direction
|
||||
* @param t {@link WrapMode wrapping mode} for the t (vertical) direction
|
||||
* @param r {@link WrapMode wrapping mode} fot the r (depth) direction
|
||||
*/
|
||||
public TextureSampler(@NonNull MinFilter min, @NonNull MagFilter mag,
|
||||
@NonNull WrapMode s, @NonNull WrapMode t, @NonNull WrapMode r) {
|
||||
mSampler = nCreateSampler(min.ordinal(), mag.ordinal(),
|
||||
s.ordinal(), t.ordinal(), r.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with user specified comparison mode. The
|
||||
* comparison fonction is set to {@link CompareFunction#LESS_EQUAL}.
|
||||
*
|
||||
* @param mode {@link CompareMode comparison mode}
|
||||
*/
|
||||
public TextureSampler(@NonNull CompareMode mode) {
|
||||
this(mode, CompareFunction.LESS_EQUAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with user specified comparison mode and function.
|
||||
*
|
||||
* @param mode {@link CompareMode comparison mode}
|
||||
* @param function {@link CompareFunction comparison function}
|
||||
*/
|
||||
public TextureSampler(@NonNull CompareMode mode, @NonNull CompareFunction function) {
|
||||
mSampler = nCreateCompareSampler(mode.ordinal(), function.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minification filter
|
||||
*/
|
||||
public MinFilter getMinFilter() {
|
||||
return MinFilter.values()[nGetMinFilter(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minification filter.
|
||||
*
|
||||
* @param filter minification filter
|
||||
*/
|
||||
public void setMinFilter(MinFilter filter) {
|
||||
mSampler = nSetMinFilter(mSampler, filter.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the magnification filter
|
||||
*/
|
||||
public MagFilter getMagFilter() {
|
||||
return MagFilter.values()[nGetMagFilter(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the magnification filter.
|
||||
*
|
||||
* @param filter magnification filter
|
||||
*/
|
||||
public void setMagFilter(MagFilter filter) {
|
||||
mSampler = nSetMagFilter(mSampler, filter.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the wrapping mode in the s (horizontal) direction
|
||||
*/
|
||||
public WrapMode getWrapModeS() {
|
||||
return WrapMode.values()[nGetWrapModeS(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wrapping mode in the s (horizontal) direction.
|
||||
* @param mode wrapping mode
|
||||
*/
|
||||
public void setWrapModeS(WrapMode mode) {
|
||||
mSampler = nSetWrapModeS(mSampler, mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the wrapping mode in the t (vertical) direction
|
||||
*/
|
||||
public WrapMode getWrapModeT() {
|
||||
return WrapMode.values()[nGetWrapModeT(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wrapping mode in the t (vertical) direction.
|
||||
* @param mode wrapping mode
|
||||
*/
|
||||
public void setWrapModeT(WrapMode mode) {
|
||||
mSampler = nSetWrapModeT(mSampler, mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the wrapping mode in the r (depth) direction
|
||||
*/
|
||||
public WrapMode getWrapModeR() {
|
||||
return WrapMode.values()[nGetWrapModeR(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wrapping mode in the t (depth) direction.
|
||||
* @param mode wrapping mode
|
||||
*/
|
||||
public void setWrapModeR(WrapMode mode) {
|
||||
mSampler = nSetWrapModeR(mSampler, mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the anisotropy value
|
||||
* @see #setAnisotropy
|
||||
*/
|
||||
public float getAnisotropy() {
|
||||
return nGetAnisotropy(mSampler);
|
||||
}
|
||||
|
||||
/**
|
||||
* This controls anisotropic filtering.
|
||||
*
|
||||
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 0.
|
||||
* The maximum permissible value is 7.
|
||||
*/
|
||||
public void setAnisotropy(float anisotropy) {
|
||||
mSampler = nSetAnisotropy(mSampler, anisotropy);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the comparison mode
|
||||
*/
|
||||
public CompareMode getCompareMode() {
|
||||
return CompareMode.values()[nGetCompareMode(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the comparison mode.
|
||||
*
|
||||
* @param mode comparison mode
|
||||
*/
|
||||
public void setCompareMode(CompareMode mode) {
|
||||
mSampler = nSetCompareMode(mSampler, mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the comparison function
|
||||
*/
|
||||
public CompareFunction getCompareFunction() {
|
||||
return CompareFunction.values()[nGetCompareFunction(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the comparison function.
|
||||
* @param function the comparison function
|
||||
*/
|
||||
public void setCompareFunction(CompareFunction function) {
|
||||
mSampler = nSetCompareFunction(mSampler, function.ordinal());
|
||||
}
|
||||
|
||||
@@ -16,51 +16,158 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
public class TransformManager {
|
||||
/**
|
||||
* <code>TransformManager</code> is used to add transform components to entities.
|
||||
*
|
||||
* <p>A transform component gives an entity a position and orientation in space in the coordinate
|
||||
* space of its parent transform. The <code>TransformManager</code> takes care of computing the
|
||||
* world-space transform of each component (i.e. its transform relative to the root).</p>
|
||||
*
|
||||
* <h1>Creation and destruction</h1>
|
||||
*
|
||||
* A transform component is created using {@link TransformManager#create} and destroyed by calling
|
||||
* {@link TransformManager#destroy}.
|
||||
*
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
* EntityManager entityManager = EntityManager().get();
|
||||
* int object = entityManager.create();
|
||||
*
|
||||
* TransformManager tcm = engine.getTransformManager();
|
||||
*
|
||||
* // create the transform component
|
||||
* tcm.create(object);
|
||||
*
|
||||
* // set its transform
|
||||
* float[] transform = ...; // transform to set
|
||||
* EntityInstance i = tcm.getInstance(object);
|
||||
* tcm.setTransform(i, transform));
|
||||
*
|
||||
* // destroy the transform component
|
||||
* tcm.destroy(object);
|
||||
* </pre>
|
||||
*
|
||||
*/public class TransformManager {
|
||||
private long mNativeObject;
|
||||
|
||||
TransformManager(long nativeTransformManager) {
|
||||
mNativeObject = nativeTransformManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a particular {@link Entity} is associated with a component of this
|
||||
* <code>TransformManager</code>
|
||||
*
|
||||
* @param entity an {@link Entity}
|
||||
* @return true if this {@link Entity} has a component associated with this manager
|
||||
*/
|
||||
public boolean hasComponent(@Entity int entity) {
|
||||
return nHasComponent(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link EntityInstance} representing the transform component associated with the
|
||||
* given {@link Entity}.
|
||||
*
|
||||
* @param entity an {@link Entity}
|
||||
* @return an {@link EntityInstance}, which represents the transform component associated with
|
||||
* the {@link Entity} <code>entity</code>
|
||||
* @see #hasComponent
|
||||
*/
|
||||
@EntityInstance
|
||||
public int getInstance(@Entity int entity) {
|
||||
return nGetInstance(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component and associates it with the given entity. The component is
|
||||
* initialized with the identity transform.
|
||||
* If this component already exists on the given entity, it is first
|
||||
* destroyed as if {@link #destroy} was called.
|
||||
*
|
||||
* @param entity an {@link Entity} to associate a transform component to.
|
||||
* @see #destroy
|
||||
*/
|
||||
@EntityInstance
|
||||
public int create(@Entity int entity) {
|
||||
return nCreate(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component with a parent and associates it with the given entity.
|
||||
* If this component already exists on the given entity, it is first
|
||||
* destroyed as if {@link #destroy} was called.
|
||||
*
|
||||
* @param entity an {@link Entity} to associate a transform component to.
|
||||
* @param parent the {@link EntityInstance} of the parent transform
|
||||
* @param localTransform the transform, relative to the parent, to initialize the transform
|
||||
* component with.
|
||||
* @see #destroy
|
||||
*/
|
||||
@EntityInstance
|
||||
public int create(@Entity int entity, @EntityInstance int parent,
|
||||
@Nullable @Size(min = 16) float[] localTransform) {
|
||||
return nCreateArray(mNativeObject, entity, parent, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this component from the given entity, children are orphaned.
|
||||
*
|
||||
* @param entity an {@link Entity}.
|
||||
* If this transform had children, these are orphaned, which means their local
|
||||
* transform becomes a world transform. Usually it's nonsensical.
|
||||
* It's recommended to make sure that a destroyed transform doesn't have children.
|
||||
* @see #create
|
||||
*/
|
||||
public void destroy(@Entity int entity) {
|
||||
nDestroy(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-parents an entity to a new one.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to re-parent
|
||||
* @param newParent the {@link EntityInstance} of the new parent transform.
|
||||
* It is an error to re-parent an entity to a descendant and will cause
|
||||
* undefined behaviour.
|
||||
* @see #getInstance
|
||||
*/
|
||||
public void setParent(@EntityInstance int i, @EntityInstance int newParent) {
|
||||
nSetParent(mNativeObject, i, newParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component.
|
||||
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
* will be particularly bad when updating a lot of transforms. In that case,
|
||||
* consider using {@link #openLocalTransformTransaction} / {@link #commitLocalTransformTransaction}.</p>
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to set the local
|
||||
* transform to.
|
||||
* @param localTransform the local transform (i.e. relative to the parent).
|
||||
* @see #getTransform
|
||||
*/
|
||||
public void setTransform(@EntityInstance int i,
|
||||
@NonNull @Size(min = 16) float[] localTransform) {
|
||||
Asserts.assertMat4fIn(localTransform);
|
||||
nSetTransform(mNativeObject, i, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* local transform from.
|
||||
* @param outLocalTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated.
|
||||
* @return the local transform of the component (i.e. relative to the parent). This always
|
||||
* returns the value set by setTransform().
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public float[] getTransform(@EntityInstance int i,
|
||||
@@ -70,6 +177,17 @@ public class TransformManager {
|
||||
return outLocalTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* world transform from.
|
||||
* @param outWorldTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated
|
||||
* @return The world transform of the component (i.e. relative to the root). This is the
|
||||
* composition of this component's local transform with its parent's world transform.
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public float[] getWorldTransform(@EntityInstance int i,
|
||||
@@ -79,10 +197,36 @@ public class TransformManager {
|
||||
return outWorldTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a local transform transaction. During a transaction, {@link #getWorldTransform} can
|
||||
* return an invalid transform until {@link #commitLocalTransformTransaction} is called.
|
||||
* However, {@link #setTransform} will perform significantly better and in constant time.
|
||||
*
|
||||
* <p>This is useful when updating many transforms and the transform hierarchy is deep (say more
|
||||
* than 4 or 5 levels).</p>
|
||||
*
|
||||
* <p>If the local transform transaction is already open, this is a no-op.</p>
|
||||
*
|
||||
* @see #commitLocalTransformTransaction
|
||||
* @see #setTransform
|
||||
*/
|
||||
public void openLocalTransformTransaction() {
|
||||
nOpenLocalTransformTransaction(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits the currently open local transform transaction. When this returns, calls
|
||||
* to {@link #getWorldTransform} will return the proper value.
|
||||
*
|
||||
* <p>Failing to call this method when done updating the local transform will cause
|
||||
* a lot of rendering problems. The system never closes the transaction
|
||||
* automatically.</p>
|
||||
*
|
||||
* <p>If the local transform transaction is not open, this is a no-op.</p>
|
||||
*
|
||||
* @see #openLocalTransformTransaction
|
||||
* @see #setTransform
|
||||
*/
|
||||
public void commitLocalTransformTransaction() {
|
||||
nCommitLocalTransformTransaction(mNativeObject);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,40 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
/**
|
||||
* Holds a set of buffers that define the geometry of a <code>Renderable</code>.
|
||||
*
|
||||
* <p>
|
||||
* The geometry of the <code>Renderable</code> itself is defined by a set of vertex attributes such as
|
||||
* position, color, normals, tangents, etc...
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* There is no need to have a 1-to-1 mapping between attributes and buffer. A buffer can hold the
|
||||
* data of several attributes -- attributes are then referred as being "interleaved".
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The buffers themselves are GPU resources, therefore mutating their data can be relatively slow.
|
||||
* For this reason, it is best to separate the constant data from the dynamic data into multiple
|
||||
* buffers.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* It is possible, and even encouraged, to use a single vertex buffer for several
|
||||
* <code>Renderable</code>s.
|
||||
* </p>
|
||||
*
|
||||
* @see IndexBuffer
|
||||
* @see RenderableManager
|
||||
*/
|
||||
public class VertexBuffer {
|
||||
private long mNativeObject;
|
||||
|
||||
@@ -31,13 +58,22 @@ public class VertexBuffer {
|
||||
}
|
||||
|
||||
public enum VertexAttribute {
|
||||
POSITION, // XYZ position (float3)
|
||||
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
|
||||
COLOR, // vertex color (float4)
|
||||
UV0, // texture coordinates (float2)
|
||||
UV1, // texture coordinates (float2)
|
||||
POSITION, // XYZ position (float3)
|
||||
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
|
||||
COLOR, // vertex color (float4)
|
||||
UV0, // texture coordinates (float2)
|
||||
UV1, // texture coordinates (float2)
|
||||
BONE_INDICES, // indices of 4 bones (uvec4)
|
||||
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
|
||||
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
|
||||
UNUSED, // reserved for future use
|
||||
CUSTOM0, // custom or MORPH_POSITION_0
|
||||
CUSTOM1, // custom or MORPH_POSITION_1
|
||||
CUSTOM2, // custom or MORPH_POSITION_2
|
||||
CUSTOM3, // custom or MORPH_POSITION_3
|
||||
CUSTOM4, // custom or MORPH_TANGENTS_0
|
||||
CUSTOM5, // custom or MORPH_TANGENTS_1
|
||||
CUSTOM6, // custom or MORPH_TANGENTS_2
|
||||
CUSTOM7 // custom or MORPH_TANGENTS_3
|
||||
}
|
||||
|
||||
public enum AttributeType {
|
||||
@@ -68,22 +104,47 @@ public class VertexBuffer {
|
||||
HALF3,
|
||||
HALF4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the quaternion type for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public enum QuatType {
|
||||
HALF4, // 2 bytes per component as half-floats (8 bytes per quat)
|
||||
SHORT4, // 2 bytes per component as normalized integers (8 bytes per quat)
|
||||
FLOAT4, // 4 bytes per component as floats (16 bytes per quat)
|
||||
/** 2 bytes per component as half-floats (8 bytes per quat) */
|
||||
HALF4,
|
||||
|
||||
/** 2 bytes per component as normalized integers (8 bytes per quat) */
|
||||
SHORT4,
|
||||
|
||||
/** 4 bytes per component as floats (16 bytes per quat) */
|
||||
FLOAT4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the parameters for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public static class QuatTangentContext {
|
||||
public QuatType quatType; // desired quaternion type (required)
|
||||
public int quatCount; // number of quaternions (required)
|
||||
public Buffer outBuffer; // pre-allocated output buffer (required)
|
||||
public int outStride; // desired stride in bytes (optional)
|
||||
public Buffer normals; // source normals (required)
|
||||
public int normalsStride; // normals stride in bytes (optional)
|
||||
public Buffer tangents; // source tangents (optional)
|
||||
public int tangentsStride; // tangents stride in bytes (optional)
|
||||
/** desired quaternion type (required) */
|
||||
public QuatType quatType;
|
||||
|
||||
/** number of quaternions (required) */
|
||||
public int quatCount;
|
||||
|
||||
/** pre-allocated output buffer (required) */
|
||||
public Buffer outBuffer;
|
||||
|
||||
/** desired stride in bytes (optional) */
|
||||
public int outStride;
|
||||
|
||||
/** source normals (required) */
|
||||
public Buffer normals;
|
||||
|
||||
/** normals stride in bytes (optional) */
|
||||
public int normalsStride;
|
||||
|
||||
/** source tangents (optional) */
|
||||
public Buffer tangents;
|
||||
|
||||
/** tangents stride in bytes (optional) */
|
||||
public int tangentsStride;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@@ -96,18 +157,64 @@ public class VertexBuffer {
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of each buffer in this set, expressed in in number of vertices.
|
||||
*
|
||||
* @param vertexCount number of vertices in each buffer in this set
|
||||
*
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder vertexCount(@IntRange(from = 1) int vertexCount) {
|
||||
nBuilderVertexCount(mNativeBuilder, vertexCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how many buffers will be created in this vertex buffer set. These buffers are
|
||||
* later referenced by index from 0 to <code>bufferCount</code> - 1.
|
||||
*
|
||||
* This call is mandatory. The default is 0.
|
||||
*
|
||||
* @param bufferCount number of buffers in this vertex buffer set. The maximum value is 8.
|
||||
*
|
||||
* @return this <code>Builder</code> for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder bufferCount(@IntRange(from = 1) int bufferCount) {
|
||||
nBuilderBufferCount(mNativeBuilder, bufferCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an attribute for this vertex buffer set.
|
||||
*
|
||||
* Using <code>byteOffset</code> and <code>byteStride</code>, attributes can be interleaved
|
||||
* in the same buffer.
|
||||
*
|
||||
* <p>
|
||||
* This is a no-op if the <code>attribute</code> is an invalid enum.
|
||||
* This is a no-op if the <code>bufferIndex</code> is out of bounds.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Warning: <code>VertexAttribute.TANGENTS</code> must be specified as a quaternion and is
|
||||
* how normals are specified.
|
||||
* </p>
|
||||
*
|
||||
* @param attribute the attribute to set up
|
||||
* @param bufferIndex the index of the buffer containing the data for this attribute. Must
|
||||
* be between 0 and bufferCount() - 1.
|
||||
* @param attributeType the type of the attribute data (e.g. byte, float3, etc...)
|
||||
* @param byteOffset offset in <i>bytes</i> into the buffer <code>bufferIndex</code>
|
||||
* @param byteStride stride in <i>bytes</i> to the next element of this attribute. When
|
||||
* set to zero the attribute size, as defined by
|
||||
* <code>attributeType</code> is used.
|
||||
*
|
||||
* @return A reference to this <code>Builder</code> for chaining calls.
|
||||
*
|
||||
* @see VertexAttribute
|
||||
*/
|
||||
@NonNull
|
||||
public Builder attribute(@NonNull VertexAttribute attribute,
|
||||
@IntRange(from = 0) int bufferIndex, @NonNull AttributeType attributeType,
|
||||
@@ -117,24 +224,82 @@ public class VertexBuffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an attribute for this vertex buffer set.
|
||||
*
|
||||
* Using <code>byteOffset</code> and <code>byteStride</code>, attributes can be interleaved
|
||||
* in the same buffer.
|
||||
*
|
||||
* <p>
|
||||
* This is a no-op if the <code>attribute</code> is an invalid enum.
|
||||
* This is a no-op if the <code>bufferIndex</code> is out of bounds.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Warning: <code>VertexAttribute.TANGENTS</code> must be specified as a quaternion and is
|
||||
* how normals are specified.
|
||||
* </p>
|
||||
*
|
||||
* @param attribute the attribute to set up
|
||||
* @param bufferIndex the index of the buffer containing the data for this attribute. Must
|
||||
* be between 0 and bufferCount() - 1.
|
||||
* @param attributeType the type of the attribute data (e.g. byte, float3, etc...)
|
||||
*
|
||||
* @return A reference to this <code>Builder</code> for chaining calls.
|
||||
*
|
||||
* @see VertexAttribute
|
||||
*/
|
||||
@NonNull
|
||||
public Builder attribute(@NonNull VertexAttribute attribute,
|
||||
@IntRange(from = 0) int bufferIndex, @NonNull AttributeType attributeType) {
|
||||
return attribute(attribute, bufferIndex, attributeType, 0, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether a given attribute should be normalized. By default attributes are not
|
||||
* normalized. A normalized attribute is mapped between 0 and 1 in the shader. This applies
|
||||
* only to integer types.
|
||||
*
|
||||
* @param attribute enum of the attribute to set the normalization flag to
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls.
|
||||
*
|
||||
* This is a no-op if the <code>attribute</code> is an invalid enum.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder normalized(@NonNull VertexAttribute attribute) {
|
||||
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether a given attribute should be normalized. By default attributes are not
|
||||
* normalized. A normalized attribute is mapped between 0 and 1 in the shader. This applies
|
||||
* only to integer types.
|
||||
*
|
||||
* @param attribute enum of the attribute to set the normalization flag to
|
||||
* @param enabled true to automatically normalize the given attribute
|
||||
*
|
||||
* @return this <code>Builder</code> object for chaining calls.
|
||||
*
|
||||
* This is a no-op if the <code>attribute</code> is an invalid enum.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder normalized(@NonNull VertexAttribute attribute, boolean enabled) {
|
||||
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the <code>VertexBuffer</code> object and returns a pointer to it.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>VertexBuffer</code>
|
||||
* with
|
||||
*
|
||||
* @return the newly created <code>VertexBuffer</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the VertexBuffer could not be created
|
||||
*/
|
||||
@NonNull
|
||||
public VertexBuffer build(@NonNull Engine engine) {
|
||||
long nativeVertexBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -159,24 +324,68 @@ public class VertexBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vertex count.
|
||||
*
|
||||
* @return number of vertices in this vertex buffer set
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getVertexCount() {
|
||||
return nGetVertexCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes the specified buffer from the given buffer data.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>VertexBuffer</code> with
|
||||
* @param bufferIndex index of the buffer to initialize. Must be between 0 and
|
||||
* bufferCount() - 1.
|
||||
* @param buffer a CPU-side {@link Buffer} representing the data used to initialize
|
||||
* the <code>VertexBuffer</code> at index <code>bufferIndex</code>.
|
||||
* <code>buffer</code> should contain raw, untyped data that will
|
||||
* be copied as-is into the buffer.
|
||||
*/
|
||||
public void setBufferAt(@NonNull Engine engine, int bufferIndex, @NonNull Buffer buffer) {
|
||||
setBufferAt(engine, bufferIndex, buffer, 0, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes a region of the specified buffer from the given buffer data.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>VertexBuffer</code> with
|
||||
* @param bufferIndex index of the buffer to initialize. Must be between 0 and
|
||||
* bufferCount() - 1.
|
||||
* @param buffer a CPU-side {@link Buffer} representing the data used to initialize
|
||||
* the <code>VertexBuffer</code> at index <code>bufferIndex</code>.
|
||||
* <code>buffer</code> should contain raw, untyped data that will
|
||||
* be copied as-is into the buffer.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the buffer at index
|
||||
* <code>bufferIndex</code> of this vertex buffer set.
|
||||
*/
|
||||
public void setBufferAt(@NonNull Engine engine, int bufferIndex, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count) {
|
||||
setBufferAt(engine, bufferIndex, buffer, destOffsetInBytes, count, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valid handler types:
|
||||
* - Android: Handler, Executor
|
||||
* - Other: Executor
|
||||
* Asynchronously copy-initializes a region of the specified buffer from the given buffer data.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>VertexBuffer</code> with
|
||||
* @param bufferIndex index of the buffer to initialize. Must be between 0 and
|
||||
* bufferCount() - 1.
|
||||
* @param buffer a CPU-side {@link Buffer} representing the data used to initialize
|
||||
* the <code>VertexBuffer</code> at index <code>bufferIndex</code>.
|
||||
* <code>buffer</code> should contain raw, untyped data that will
|
||||
* be copied as-is into the buffer.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the buffer at index
|
||||
* <code>bufferIndex</code> of this vertex buffer set.
|
||||
* @param handler an {@link java.util.concurrent.Executor Executor}. On Android this
|
||||
* can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback a callback executed by <code>handler</code> when <code>buffer</code>
|
||||
* is no longer needed.
|
||||
*/
|
||||
public void setBufferAt(@NonNull Engine engine, int bufferIndex, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count,
|
||||
@@ -188,7 +397,30 @@ public class VertexBuffer {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that consumes normal vectors (and, optionally, tangent vectors) and
|
||||
* produces quaternions that can be passed into a TANGENTS buffer.
|
||||
*
|
||||
* <p>
|
||||
* The given output buffer must be preallocated with at least quatCount * outStride bytes.
|
||||
* <p>
|
||||
*
|
||||
* <p>
|
||||
* Normals are required but tangents are optional, in which case this function tries to generate
|
||||
* reasonable tangents. The given normals should be unit length.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If supplied, the tangent vectors should be unit length and should be orthogonal to the
|
||||
* normals. The w component of the tangent is a sign (-1 or +1) indicating handedness of the
|
||||
* basis.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated Instead please use SurfaceOrientation since it has additional capabilities and a
|
||||
* builder-style API.
|
||||
*
|
||||
* @param context an initialized QuatTangentContext object
|
||||
*/
|
||||
public static void populateTangentQuaternions(@NonNull QuatTangentContext context) {
|
||||
nPopulateTangentQuaternions(context.quatType.ordinal(), context.quatCount,
|
||||
context.outBuffer, context.outBuffer.remaining(), context.outStride,
|
||||
|
||||
@@ -16,13 +16,44 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import static com.google.android.filament.Colors.*;
|
||||
import static com.google.android.filament.Colors.LinearColor;
|
||||
|
||||
/**
|
||||
* Encompasses all the state needed for rendering a {@link Scene}.
|
||||
*
|
||||
* <p>
|
||||
* {@link Renderer#render} operates on <code>View</code> objects. These <code>View</code> objects
|
||||
* specify important parameters such as:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>The Scene</li>
|
||||
* <li>The Camera</li>
|
||||
* <li>The Viewport</li>
|
||||
* <li>Some rendering parameters</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* <code>View</code> instances are heavy objects that internally cache a lot of data needed for
|
||||
* rendering. It is not advised for an application to use many View objects.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* For example, in a game, a <code>View</code> could be used for the main scene and another one for
|
||||
* the game's user interface. More <code>View</code> instances could be used for creating special
|
||||
* effects (e.g. a <code>View</code> is akin to a rendering pass).
|
||||
* </p>
|
||||
*
|
||||
* @see Renderer
|
||||
* @see Scene
|
||||
* @see Camera
|
||||
* @see RenderTarget
|
||||
*/
|
||||
public class View {
|
||||
private long mNativeObject;
|
||||
private String mName;
|
||||
@@ -31,28 +62,14 @@ public class View {
|
||||
private Viewport mViewport = new Viewport(0, 0, 0, 0);
|
||||
private DynamicResolutionOptions mDynamicResolution;
|
||||
private RenderQuality mRenderQuality;
|
||||
private DepthPrepass mDepthPrepass = DepthPrepass.DEFAULT;
|
||||
private AmbientOcclusionOptions mAmbientOcclusionOptions;
|
||||
private BloomOptions mBloomOptions;
|
||||
private FogOptions mFogOptions;
|
||||
private RenderTarget mRenderTarget;
|
||||
|
||||
public static class DynamicResolutionOptions {
|
||||
public boolean enabled = false;
|
||||
public boolean homogeneousScaling = false;
|
||||
public float targetFrameTimeMilli = 1000.0f / 60.0f;
|
||||
public float headRoomRatio = 0.0f;
|
||||
public float scaleRate = 0.125f;
|
||||
public float minScale = 0.5f;
|
||||
public float maxScale = 1.0f;
|
||||
public int history = 9;
|
||||
}
|
||||
|
||||
public static class AmbientOcclusionOptions {
|
||||
public float radius = 0.3f;
|
||||
public float bias = 0.005f;
|
||||
public float power = 0.0f;
|
||||
public float resolution = 0.5f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Quality Level
|
||||
*/
|
||||
public enum QualityLevel {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
@@ -60,92 +77,459 @@ public class View {
|
||||
ULTRA
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic resolution can be used to either reach a desired target frame rate by lowering the
|
||||
* resolution of a <code>View</code>, or to increase the quality when the rendering is faster
|
||||
* than the target frame rate.
|
||||
*
|
||||
* <p>
|
||||
* This structure can be used to specify the minimum scale factor used when lowering the
|
||||
* resolution of a <code>View</code>, and the maximum scale factor used when increasing the
|
||||
* resolution for higher quality rendering. The scale factors can be controlled on each X and Y
|
||||
* axis independently. By default, all scale factors are set to 1.0.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Dynamic resolution is only supported on platforms where the time to render a frame can be
|
||||
* measured accurately. Dynamic resolution is currently only supported on Android.
|
||||
* </p>
|
||||
*/
|
||||
public static class DynamicResolutionOptions {
|
||||
/**
|
||||
* Enables or disables dynamic resolution on a View.
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
|
||||
/**
|
||||
* If false, the system scales the major axis first.
|
||||
*/
|
||||
public boolean homogeneousScaling = false;
|
||||
|
||||
/**
|
||||
* Desired frame time in milliseconds.
|
||||
*/
|
||||
public float targetFrameTimeMilli = 1000.0f / 60.0f;
|
||||
|
||||
/**
|
||||
* Additional headroom for the GPU as a ratio of the targetFrameTime.
|
||||
*/
|
||||
public float headRoomRatio = 0.0f;
|
||||
|
||||
/**
|
||||
* Rate at which the scale will change to reach the target frame rate.
|
||||
*/
|
||||
public float scaleRate = 0.125f;
|
||||
|
||||
/**
|
||||
* The minimum scale in X and Y this View should use.
|
||||
*/
|
||||
public float minScale = 0.5f;
|
||||
|
||||
/**
|
||||
* The maximum scale in X and Y this View should use.
|
||||
*/
|
||||
public float maxScale = 1.0f;
|
||||
|
||||
/**
|
||||
* History size. higher values, tend to filter more (clamped to 30).
|
||||
*/
|
||||
public int history = 9;
|
||||
|
||||
/**
|
||||
* Upscaling quality. LOW: 1 bilinear taps, MEDIUM: 4 bilinear taps, HIGH: 9 bilinear taps.
|
||||
* If minScale needs to be very low, it might help to use MEDIUM or HIGH here.
|
||||
* The default upsacling quality is set to LOW.
|
||||
*/
|
||||
@NonNull
|
||||
public QualityLevel quality = QualityLevel.LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for Ambient Occlusion
|
||||
* @see #setAmbientOcclusion
|
||||
*/
|
||||
public static class AmbientOcclusionOptions {
|
||||
/**
|
||||
* Ambient Occlusion radius in meters, between 0 and ~10.
|
||||
*/
|
||||
public float radius = 0.3f;
|
||||
|
||||
/**
|
||||
* Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
|
||||
*/
|
||||
public float bias = 0.0005f;
|
||||
|
||||
/**
|
||||
* Controls ambient occlusion's contrast. Must be positive. Default is 1.
|
||||
* Good values are between 0.5 and 3.
|
||||
*/
|
||||
public float power = 1.0f;
|
||||
|
||||
/**
|
||||
* How each dimension of the AO buffer is scaled. Must be positive and <= 1.
|
||||
*/
|
||||
public float resolution = 0.5f;
|
||||
|
||||
/**
|
||||
* Strength of the Ambient Occlusion effect. Must be positive.
|
||||
*/
|
||||
public float intensity = 1.0f;
|
||||
|
||||
/**
|
||||
* The quality setting controls the number of samples used for evaluating Ambient
|
||||
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
|
||||
* applications.
|
||||
*/
|
||||
@NonNull
|
||||
public QualityLevel quality = QualityLevel.LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for controlling the Bloom effect
|
||||
*
|
||||
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
|
||||
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
|
||||
* maximum is 12. This value together with resolution influences the spread of the
|
||||
* blur effect. This value can be silently reduced to accommodate the original
|
||||
* image size.
|
||||
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 4096. This parameter is
|
||||
* silently clamped to the minimum and maximum.
|
||||
* It is highly recommended that this value be smaller than the target resolution
|
||||
* after dynamic resolution is applied (horizontally and vertically).
|
||||
* strength: how much of the bloom is added to the original image. Between 0 and 1.
|
||||
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
|
||||
* image (true).
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons and is usually needed when a dirt texture is used.
|
||||
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
|
||||
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
|
||||
* enabled for the dirt effect to work properly.
|
||||
* dirtStrength: Strength of the dirt texture.
|
||||
*
|
||||
* @see setBloomOptions
|
||||
*/
|
||||
public static class BloomOptions {
|
||||
|
||||
public enum BlendingMode {
|
||||
ADD,
|
||||
INTERPOLATE
|
||||
}
|
||||
|
||||
/**
|
||||
* User provided dirt texture
|
||||
*/
|
||||
@Nullable
|
||||
public Texture dirt = null;
|
||||
|
||||
/**
|
||||
* strength of the dirt texture
|
||||
*/
|
||||
public float dirtStrength = 0.2f;
|
||||
|
||||
/**
|
||||
* Strength of the bloom effect, between 0.0 and 1.0
|
||||
*/
|
||||
public float strength = 0.10f;
|
||||
|
||||
/**
|
||||
* Resolution of minor axis (2^levels to 4096)
|
||||
*/
|
||||
public int resolution = 360;
|
||||
|
||||
/**
|
||||
* Bloom x/y aspect-ratio (1/32 to 32)
|
||||
*/
|
||||
public float anamorphism = 1.0f;
|
||||
|
||||
/**
|
||||
* Number of blur levels (3 to 12)
|
||||
*/
|
||||
public int levels = 6;
|
||||
|
||||
/**
|
||||
* How the bloom effect is applied
|
||||
*/
|
||||
public BlendingMode blendingMode = BlendingMode.ADD;
|
||||
|
||||
/**
|
||||
* Whether to threshold the source
|
||||
*/
|
||||
public boolean threshold = true;
|
||||
|
||||
/**
|
||||
* enable or disable bloom
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to control fog in the scene
|
||||
*
|
||||
* @see setFogOptions
|
||||
*/
|
||||
public static class FogOptions {
|
||||
/**
|
||||
* distance in world units from the camera where the fog starts ( >= 0.0 )
|
||||
*/
|
||||
public float distance = 0.0f;
|
||||
|
||||
/**
|
||||
* fog's maximum opacity between 0 and 1
|
||||
*/
|
||||
public float maximumOpacity = 1.0f;
|
||||
|
||||
/**
|
||||
* fog's floor in world units
|
||||
*/
|
||||
public float height = 0.0f;
|
||||
|
||||
/**
|
||||
* how fast fog dissipates with altitude
|
||||
*/
|
||||
public float heightFalloff = 1.0f;
|
||||
|
||||
/**
|
||||
* fog's color (linear)
|
||||
*/
|
||||
@NonNull
|
||||
public float[] color = { 0.5f, 0.5f, 0.5f };
|
||||
|
||||
/**
|
||||
* fog's density at altitude given by 'height'
|
||||
*/
|
||||
public float density = 0.1f;
|
||||
|
||||
/**
|
||||
* distance in world units from the camera where in-scattering starts
|
||||
*/
|
||||
public float inScatteringStart = 0.0f;
|
||||
|
||||
/**
|
||||
* size of in-scattering (>=0 to activate). Good values are >> 1 (e.g. ~10 - 100)
|
||||
*/
|
||||
public float inScatteringSize = 0.0f;
|
||||
|
||||
/**
|
||||
* fog color will be modulated by the IBL color in the view direction
|
||||
*/
|
||||
public boolean fogColorFromIbl = false;
|
||||
|
||||
/**
|
||||
* enable or disable fog
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure used to set the color precision for the rendering of a <code>View</code>.
|
||||
*
|
||||
* <p>
|
||||
* This structure offers separate quality settings for different parts of the rendering
|
||||
* pipeline.
|
||||
* </p>
|
||||
*
|
||||
* @see #setRenderQuality
|
||||
* @see #getRenderQuality
|
||||
*/
|
||||
public static class RenderQuality {
|
||||
/**
|
||||
* <p>
|
||||
* A quality of <code>HIGH</code> or <code>ULTRA</code> means using an RGB16F or RGBA16F color
|
||||
* buffer. This means colors in the LDR range (0..1) have 10 bit precision. A quality of
|
||||
* <code>LOW</code> or <code>MEDIUM</code> means using an R11G11B10F opaque color buffer or an
|
||||
* RGBA16F transparent color buffer. With R11G11B10F colors in the LDR range have a precision of
|
||||
* either 6 bits (red and green channels) or 5 bits (blue channel).
|
||||
* </p>
|
||||
*/
|
||||
public QualityLevel hdrColorBuffer = QualityLevel.HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available ambient occlusion techniques.
|
||||
*
|
||||
* @see #setAmbientOcclusion
|
||||
*/
|
||||
public enum AmbientOcclusion {
|
||||
NONE,
|
||||
SSAO
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available post-processing anti-aliasing techniques.
|
||||
*
|
||||
* @see #setAntiAliasing
|
||||
* @see #getAntiAliasing
|
||||
*/
|
||||
public enum AntiAliasing {
|
||||
/**
|
||||
* No anti aliasing performed as part of post-processing.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* FXAA is a low-quality but very efficient type of anti-aliasing. (default).
|
||||
*/
|
||||
FXAA
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available tone-mapping operators
|
||||
*/
|
||||
public enum ToneMapping {
|
||||
/**
|
||||
* Equivalent to disabling tone-mapping.
|
||||
*/
|
||||
LINEAR,
|
||||
|
||||
/**
|
||||
* The Academy Color Encoding System (ACES).
|
||||
*/
|
||||
ACES
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available post-processing dithering techniques.
|
||||
*/
|
||||
public enum Dithering {
|
||||
NONE,
|
||||
TEMPORAL
|
||||
}
|
||||
|
||||
public enum DepthPrepass {
|
||||
DEFAULT(-1),
|
||||
DISABLED(0),
|
||||
ENABLED(1);
|
||||
|
||||
final int value;
|
||||
|
||||
DepthPrepass(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
};
|
||||
|
||||
View(long nativeView) {
|
||||
mNativeObject = nativeView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the View's name. Only useful for debugging.
|
||||
*/
|
||||
public void setName(@NonNull String name) {
|
||||
mName = name;
|
||||
nSetName(getNativeObject(), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the View's name.
|
||||
*/
|
||||
@Nullable
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this View instance's Scene.
|
||||
*
|
||||
* <p>
|
||||
* This method associates the specified Scene with this View. Note that a particular scene can
|
||||
* be associated with several View instances. To remove an existing association, simply pass
|
||||
* null.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The View does not take ownership of the Scene pointer. Before destroying a Scene, be sure
|
||||
* to remove it from all assoicated Views.
|
||||
* </p>
|
||||
*
|
||||
* @see #getScene
|
||||
*/
|
||||
public void setScene(@Nullable Scene scene) {
|
||||
mScene = scene;
|
||||
nSetScene(getNativeObject(), scene == null ? 0 : scene.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this View's associated Scene, or null if none has been assigned.
|
||||
*
|
||||
* @see #setScene
|
||||
*/
|
||||
@Nullable
|
||||
public Scene getScene() {
|
||||
return mScene;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this View's Camera.
|
||||
*
|
||||
* <p>
|
||||
* This method associates the specified Camera with this View. A Camera can be associated with
|
||||
* several View instances. To remove an existing association, simply pass
|
||||
* null.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The View does not take ownership of the Scene pointer. Before destroying a Camera, be sure
|
||||
* to remove it from all assoicated Views.
|
||||
* </p>
|
||||
*
|
||||
* @see #getCamera
|
||||
*/
|
||||
public void setCamera(@Nullable Camera camera) {
|
||||
mCamera = camera;
|
||||
nSetCamera(getNativeObject(), camera == null ? 0 : camera.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this View's associated Camera, or null if none has been assigned.
|
||||
*
|
||||
* @see #setCamera
|
||||
*/
|
||||
@Nullable
|
||||
public Camera getCamera() {
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the rectangular rendering area.
|
||||
*
|
||||
* <p>
|
||||
* The viewport specifies where the content of the View (i.e. the Scene) is rendered in
|
||||
* the render target. The render target is automatically clipped to the Viewport.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you wish subsequent changes to take effect please call this method again in order to
|
||||
* propagate the changes down to the native layer.
|
||||
* </p>
|
||||
*
|
||||
* @param viewport The Viewport to render the Scene into.
|
||||
*/
|
||||
public void setViewport(@NonNull Viewport viewport) {
|
||||
mViewport = viewport;
|
||||
nSetViewport(getNativeObject(),
|
||||
mViewport.left, mViewport.bottom, mViewport.width, mViewport.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rectangular rendering area.
|
||||
*
|
||||
* @see #setViewport
|
||||
*/
|
||||
@NonNull
|
||||
public Viewport getViewport() {
|
||||
return mViewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color used to clear the Viewport when rendering this View.
|
||||
*
|
||||
* <p>This is ignored if a {@link Skybox} is present or if clearing has been disabled
|
||||
* via {@link #setClearTargets}. Defaults to black.</p>
|
||||
*
|
||||
* @see #getClearColor
|
||||
*/
|
||||
public void setClearColor(
|
||||
@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) {
|
||||
nSetClearColor(getNativeObject(), r, g, b, a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the View clear color in a provided 4-tuple.
|
||||
*
|
||||
* @return A reference to the passed-in array.
|
||||
*
|
||||
* @see #setClearColor
|
||||
*/
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getClearColor(@NonNull @Size(min = 4) float[] out) {
|
||||
out = Asserts.assertFloat4(out);
|
||||
@@ -153,65 +537,178 @@ public class View {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which targets to clear (default: true, true, false)
|
||||
*
|
||||
* @see #setClearColor
|
||||
*/
|
||||
public void setClearTargets(boolean color, boolean depth, boolean stencil) {
|
||||
nSetClearTargets(getNativeObject(), color, depth, stencil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which layers are visible.
|
||||
*
|
||||
* <p>
|
||||
* Renderable objects can have one or several layers associated to them. Layers are
|
||||
* represented with an 8-bits bitmask, where each bit corresponds to a layer.
|
||||
* By default all layers are visible.
|
||||
* </p>
|
||||
*
|
||||
* @see RenderableManager#setLayerMask
|
||||
*
|
||||
* @param select a bitmask specifying which layer to set or clear using <code>values</code>.
|
||||
* @param values a bitmask where each bit sets the visibility of the corresponding layer
|
||||
* (1: visible, 0: invisible), only layers in <code>select</code> are affected.
|
||||
*/
|
||||
public void setVisibleLayers(
|
||||
@IntRange(from = 0, to = 255) int select,
|
||||
@IntRange(from = 0, to = 255) int values) {
|
||||
nSetVisibleLayers(getNativeObject(), select & 0xFF, values & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables shadow mapping. Enabled by default.
|
||||
*
|
||||
* @see LightManager.Builder#castShadows
|
||||
* @see RenderableManager.Builder#receiveShadows
|
||||
* @see RenderableManager.Builder#castShadows
|
||||
*/
|
||||
public void setShadowsEnabled(boolean enabled) {
|
||||
nSetShadowsEnabled(getNativeObject(), enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies an offscreen render target to render into.
|
||||
*
|
||||
* <p>
|
||||
* By default, the view's associated render target is null, which corresponds to the
|
||||
* SwapChain associated with the engine.
|
||||
* </p>
|
||||
*
|
||||
* @param target render target associated with view, or null for the swap chain
|
||||
*/
|
||||
public void setRenderTarget(@Nullable RenderTarget target) {
|
||||
mRenderTarget = target;
|
||||
nSetRenderTarget(getNativeObject(), target != null ? target.getNativeObject() : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offscreen render target associated with this view.
|
||||
*
|
||||
* Returns null if the render target is the swap chain (which is default).
|
||||
*
|
||||
* @see #setRenderTarget
|
||||
*/
|
||||
@Nullable
|
||||
public RenderTarget getRenderTarget() {
|
||||
return mRenderTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how many samples are to be used for MSAA in the post-process stage.
|
||||
* Default is 1 and disables MSAA.
|
||||
*
|
||||
* <p>
|
||||
* Note that anti-aliasing can also be performed in the post-processing stage, generally at
|
||||
* lower cost. See the FXAA option in {@link #setAntiAliasing}.
|
||||
* </p>
|
||||
*
|
||||
* @param count number of samples to use for multi-sampled anti-aliasing.
|
||||
*/
|
||||
public void setSampleCount(int count) {
|
||||
nSetSampleCount(getNativeObject(), count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective MSAA sample count.
|
||||
*
|
||||
* <p>
|
||||
* A value of 0 or 1 means MSAA is disabled.
|
||||
* </p>
|
||||
*
|
||||
* @return value set by {@link #setSampleCount}
|
||||
*/
|
||||
public int getSampleCount() {
|
||||
return nGetSampleCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables anti-aliasing in the post-processing stage. Enabled by default.
|
||||
*
|
||||
* <p>
|
||||
* For MSAA anti-aliasing, see {@link #setSampleCount}.
|
||||
* </p>
|
||||
*
|
||||
* @param type FXAA for enabling, NONE for disabling anti-aliasing.
|
||||
*/
|
||||
public void setAntiAliasing(@NonNull AntiAliasing type) {
|
||||
nSetAntiAliasing(getNativeObject(), type.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether anti-aliasing is enabled during the post-processing stage. To query
|
||||
* whether MSAA is enabled, see {@link #getSampleCount}.
|
||||
*
|
||||
* @return The post-processing anti-aliasing method.
|
||||
*/
|
||||
@NonNull
|
||||
public AntiAliasing getAntiAliasing() {
|
||||
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables tone-mapping in the post-processing stage. Enabled by default.
|
||||
*
|
||||
* @param type Tone-mapping function.
|
||||
*/
|
||||
public void setToneMapping(@NonNull ToneMapping type) {
|
||||
nSetToneMapping(getNativeObject(), type.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tone-mapping function.
|
||||
* @return tone-mapping function.
|
||||
*/
|
||||
@NonNull
|
||||
public ToneMapping getToneMapping() {
|
||||
return ToneMapping.values()[nGetToneMapping(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables dithering in the post-processing stage. Enabled by default.
|
||||
*
|
||||
* @param dithering dithering type
|
||||
*/
|
||||
public void setDithering(@NonNull Dithering dithering) {
|
||||
nSetDithering(getNativeObject(), dithering.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries whether dithering is enabled during the post-processing stage.
|
||||
*
|
||||
* @return the current dithering type for this view.
|
||||
*/
|
||||
@NonNull
|
||||
public Dithering getDithering() {
|
||||
return Dithering.values()[nGetDithering(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the dynamic resolution options for this view.
|
||||
*
|
||||
* <p>
|
||||
* Dynamic resolution options controls whether dynamic resolution is enabled, and if it is,
|
||||
* how it behaves.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you wish subsequent changes to take effect please call this method again in order to
|
||||
* propagate the changes down to the native layer.
|
||||
* </p>
|
||||
*
|
||||
* @param options The dynamic resolution options to use on this view
|
||||
*/
|
||||
public void setDynamicResolutionOptions(@NonNull DynamicResolutionOptions options) {
|
||||
mDynamicResolution = options;
|
||||
nSetDynamicResolutionOptions(getNativeObject(),
|
||||
@@ -222,9 +719,14 @@ public class View {
|
||||
options.scaleRate,
|
||||
options.minScale,
|
||||
options.maxScale,
|
||||
options.history);
|
||||
options.history,
|
||||
options.quality.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dynamic resolution options associated with this view.
|
||||
* @return value set by {@link #setDynamicResolutionOptions}.
|
||||
*/
|
||||
@NonNull
|
||||
public DynamicResolutionOptions getDynamicResolutionOptions() {
|
||||
if (mDynamicResolution == null) {
|
||||
@@ -233,11 +735,20 @@ public class View {
|
||||
return mDynamicResolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rendering quality for this view (e.g. color precision).
|
||||
*
|
||||
* @param renderQuality The render quality to use on this view
|
||||
*/
|
||||
public void setRenderQuality(@NonNull RenderQuality renderQuality) {
|
||||
mRenderQuality = renderQuality;
|
||||
nSetRenderQuality(getNativeObject(), renderQuality.hdrColorBuffer.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the render quality used by this view.
|
||||
* @return value set by {@link #setRenderQuality}.
|
||||
*/
|
||||
@NonNull
|
||||
public RenderQuality getRenderQuality() {
|
||||
if (mRenderQuality == null) {
|
||||
@@ -246,50 +757,129 @@ public class View {
|
||||
return mRenderQuality;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public DepthPrepass getDepthPrepass() {
|
||||
return mDepthPrepass;
|
||||
}
|
||||
|
||||
public void setDepthPrepass(@NonNull DepthPrepass depthPrepass) {
|
||||
mDepthPrepass = depthPrepass;
|
||||
nSetDepthPrepass(getNativeObject(), depthPrepass.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if post-processing is enabled.
|
||||
*
|
||||
* @see #setPostProcessingEnabled
|
||||
*/
|
||||
public boolean isPostProcessingEnabled() {
|
||||
return nIsPostProcessingEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables post processing. Enabled by default.
|
||||
*
|
||||
* <p>Post-processing includes:</p>
|
||||
* <ul>
|
||||
* <li>Tone-mapping & gamma encoding</li>
|
||||
* <li>Dithering</li>
|
||||
* <li>MSAA</li>
|
||||
* <li>FXAA</li>
|
||||
* <li>Dynamic scaling</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Disabling post-processing forgoes color correctness as well as anti-aliasing and
|
||||
* should only be used experimentally (e.g., for UI overlays).
|
||||
* </p>
|
||||
*
|
||||
* @param enabled true enables post processing, false disables it
|
||||
*
|
||||
* @see #setToneMapping
|
||||
* @see #setAntiAliasing
|
||||
* @see #setDithering
|
||||
* @see #setSampleCount
|
||||
*/
|
||||
public void setPostProcessingEnabled(boolean enabled) {
|
||||
nSetPostProcessingEnabled(getNativeObject(), enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if post-processing is enabled.
|
||||
*
|
||||
* @see #setPostProcessingEnabled
|
||||
*/
|
||||
public boolean isFrontFaceWindingInverted() {
|
||||
return nIsFrontFaceWindingInverted(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
|
||||
* winding order. When the winding order is inverted, front faces are faces with a clockwise
|
||||
* winding order.
|
||||
*
|
||||
* Changing the winding order will directly affect the culling mode in materials
|
||||
* (see Material#getCullingMode).
|
||||
*
|
||||
* Inverting the winding order of front faces is useful when rendering mirrored reflections
|
||||
* (water, mirror surfaces, front camera in AR, etc.).
|
||||
*
|
||||
* @param inverted True to invert front faces, false otherwise.
|
||||
*/
|
||||
public void setFrontFaceWindingInverted(boolean inverted) {
|
||||
nSetFrontFaceWindingInverted(getNativeObject(), inverted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets options relative to dynamic lighting for this view.
|
||||
*
|
||||
* <p>
|
||||
* Together <code>zLightNear</code> and <code>zLightFar</code> must be chosen so that the
|
||||
* visible influence of lights is spread between these two values.
|
||||
* </p>
|
||||
*
|
||||
* @param zLightNear Distance from the camera where the lights are expected to shine.
|
||||
* This parameter can affect performance and is useful because depending
|
||||
* on the scene, lights that shine close to the camera may not be
|
||||
* visible -- in this case, using a larger value can improve performance.
|
||||
* e.g. when standing and looking straight, several meters of the ground
|
||||
* isn't visible and if lights are expected to shine there, there is no
|
||||
* point using a short zLightNear. (Default 5m).
|
||||
*
|
||||
* @param zLightFar Distance from the camera after which lights are not expected to be visible.
|
||||
* Similarly to zLightNear, setting this value properly can improve
|
||||
* performance. (Default 100m).
|
||||
*
|
||||
*/
|
||||
public void setDynamicLightingOptions(float zLightNear, float zLightFar) {
|
||||
nSetDynamicLightingOptions(getNativeObject(), zLightNear, zLightFar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates or deactivates ambient occlusion.
|
||||
*
|
||||
* @param ao Type of ambient occlusion to use.
|
||||
*/
|
||||
public void setAmbientOcclusion(@NonNull AmbientOcclusion ao) {
|
||||
nSetAmbientOcclusion(getNativeObject(), ao.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries the type of ambient occlusion active for this View.
|
||||
*
|
||||
* @return ambient occlusion type.
|
||||
*/
|
||||
@NonNull
|
||||
public AmbientOcclusion getAmbientOcclusion() {
|
||||
return AmbientOcclusion.values()[nGetAmbientOcclusion(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ambient occlusion options.
|
||||
*
|
||||
* @param options Options for ambient occlusion.
|
||||
*/
|
||||
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
|
||||
mAmbientOcclusionOptions = options;
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power, options.resolution);
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
|
||||
options.resolution, options.intensity, options.quality.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ambient occlusion options.
|
||||
*
|
||||
* @return ambient occlusion options currently set.
|
||||
*/
|
||||
@NonNull
|
||||
public AmbientOcclusionOptions getAmbientOcclusionOptions() {
|
||||
if (mAmbientOcclusionOptions == null) {
|
||||
@@ -298,6 +888,46 @@ public class View {
|
||||
return mAmbientOcclusionOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bloom options.
|
||||
*
|
||||
* @param options Options for bloom.
|
||||
*/
|
||||
public void setBloomOptions(@NonNull BloomOptions options) {
|
||||
mBloomOptions = options;
|
||||
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
|
||||
options.dirtStrength, options.strength, options.resolution,
|
||||
options.anamorphism, options.levels, options.blendingMode.ordinal(),
|
||||
options.threshold, options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets fog options.
|
||||
*
|
||||
* @param options Options for fog.
|
||||
*/
|
||||
public void setFogOptions(@NonNull FogOptions options) {
|
||||
mFogOptions = options;
|
||||
nSetFogOptions(getNativeObject(), options.distance, options.maximumOpacity, options.height,
|
||||
options.heightFalloff, options.color[0], options.color[1], options.color[2],
|
||||
options.density, options.inScatteringStart, options.inScatteringSize,
|
||||
options.fogColorFromIbl,
|
||||
options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bloom options
|
||||
*
|
||||
* @return bloom options currently set.
|
||||
*/
|
||||
@NonNull
|
||||
public BloomOptions getBloomOptions() {
|
||||
if (mBloomOptions == null) {
|
||||
mBloomOptions = new BloomOptions();
|
||||
}
|
||||
return mBloomOptions;
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed View");
|
||||
@@ -330,15 +960,17 @@ public class View {
|
||||
private static native void nSetDynamicResolutionOptions(long nativeView,
|
||||
boolean enabled, boolean homogeneousScaling,
|
||||
float targetFrameTimeMilli, float headRoomRatio, float scaleRate,
|
||||
float minScale, float maxScale, int history);
|
||||
float minScale, float maxScale, int history, int quality);
|
||||
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
|
||||
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
|
||||
private static native void nSetDepthPrepass(long nativeView, int value);
|
||||
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsPostProcessingEnabled(long nativeView);
|
||||
private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted);
|
||||
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
|
||||
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
|
||||
}
|
||||
|
||||
@@ -16,8 +16,18 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.IntRange;
|
||||
import androidx.annotation.IntRange;
|
||||
|
||||
/**
|
||||
* Specifies a rectangular region within a render target in terms of pixel coordinates.
|
||||
*
|
||||
* <p>
|
||||
* The rectangle spans from <code>(left,bottom)</code> to <code>(left+width-1, top+height-1)</code>,
|
||||
* inclusive. Width and height must be non-negative.
|
||||
* </p>
|
||||
*
|
||||
* @see View#setViewport
|
||||
*/
|
||||
public class Viewport {
|
||||
public Viewport(int left, int bottom, @IntRange(from = 0) int width, @IntRange(from = 0) int height) {
|
||||
this.left = left;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.google.android.filament.android;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
@@ -34,21 +34,6 @@ public final class TextureHelper {
|
||||
private static final int BITMAP_CONFIG_RGBA_F16 = 4;
|
||||
private static final int BITMAP_CONFIG_HARDWARE = 5;
|
||||
|
||||
private static Method sEngineGetNativeObject;
|
||||
private static Method sTextureGetNativeObject;
|
||||
|
||||
static {
|
||||
try {
|
||||
sEngineGetNativeObject = Engine.class.getDeclaredMethod("getNativeObject");
|
||||
sTextureGetNativeObject = Texture.class.getDeclaredMethod("getNativeObject");
|
||||
|
||||
sEngineGetNativeObject.setAccessible(true);
|
||||
sTextureGetNativeObject.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Cannot happen
|
||||
}
|
||||
}
|
||||
|
||||
private TextureHelper() {
|
||||
}
|
||||
|
||||
@@ -69,14 +54,10 @@ public final class TextureHelper {
|
||||
throw new IllegalArgumentException("Unsupported config: ARGB_4444 or HARDWARE");
|
||||
}
|
||||
|
||||
try {
|
||||
long nativeTexture = (Long) sTextureGetNativeObject.invoke(texture);
|
||||
long nativeEngine = (Long) sEngineGetNativeObject.invoke(engine);
|
||||
nSetBitmap(nativeTexture, nativeEngine, level, xoffset, yoffset, width, height,
|
||||
bitmap, format);
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
long nativeTexture = texture.getNativeObject();
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
nSetBitmap(nativeTexture, nativeEngine, level, xoffset, yoffset, width, height,
|
||||
bitmap, format);
|
||||
}
|
||||
|
||||
private static int toNativeFormat(Bitmap.Config config) {
|
||||
|
||||
@@ -18,15 +18,15 @@ package com.google.android.filament.android;
|
||||
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.SurfaceTexture;
|
||||
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
|
||||
import com.google.android.filament.SwapChain;
|
||||
|
||||
/**
|
||||
@@ -99,10 +99,6 @@ import com.google.android.filament.SwapChain;
|
||||
* // Always detach the surface before destroying the engine
|
||||
* mUiHelper.detach();
|
||||
*
|
||||
* // This ensures that all the commands we've sent to Filament have
|
||||
* // been processed before we attempt to destroy anything
|
||||
* Fence.waitAndDestroy(mEngine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH);
|
||||
*
|
||||
* mEngine.destroy();
|
||||
* }
|
||||
*
|
||||
@@ -135,6 +131,7 @@ public class UiHelper {
|
||||
private RenderSurface mRenderSurface;
|
||||
|
||||
private boolean mOpaque = true;
|
||||
private boolean mOverlay = false;
|
||||
|
||||
/**
|
||||
* Enum used to decide whether UiHelper should perform extra error checking.
|
||||
@@ -177,7 +174,7 @@ public class UiHelper {
|
||||
void detach();
|
||||
}
|
||||
|
||||
private class SurfaceViewHandler implements RenderSurface {
|
||||
private static class SurfaceViewHandler implements RenderSurface {
|
||||
private SurfaceView mSurfaceView;
|
||||
|
||||
SurfaceViewHandler(SurfaceView surface) {
|
||||
@@ -327,6 +324,30 @@ public class UiHelper {
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the SurfaceView used as a render target should be positioned above
|
||||
* other surfaces but below the activity's surface. False by default.
|
||||
*/
|
||||
public boolean isMediaOverlay() {
|
||||
return mOverlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether the surface of the SurfaceView used as a render target should be
|
||||
* positioned above other surfaces but below the activity's surface. This property
|
||||
* only has an effect when used in combination with {@link #setOpaque(boolean) setOpaque(false)}
|
||||
* and does not affect TextureView targets.
|
||||
*
|
||||
* Must be called before calling {@link #attachTo(SurfaceView)}
|
||||
* or {@link #attachTo(TextureView)}.
|
||||
*
|
||||
* @param overlay Indicates whether the render target should be rendered below the activity's
|
||||
* surface when transparent.
|
||||
*/
|
||||
public void setMediaOverlay(boolean overlay) {
|
||||
mOverlay = overlay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags to pass to
|
||||
* {@link com.google.android.filament.Engine#createSwapChain(Object, long)} to honor all
|
||||
@@ -344,11 +365,18 @@ public class UiHelper {
|
||||
*/
|
||||
public void attachTo(@NonNull SurfaceView view) {
|
||||
if (attach(view)) {
|
||||
if (!isOpaque()) {
|
||||
view.setZOrderOnTop(true);
|
||||
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
|
||||
boolean translucent = !isOpaque();
|
||||
// setZOrderOnTop() and setZOrderMediaOverlay() override each other,
|
||||
// we must only call one of them
|
||||
if (isMediaOverlay()) {
|
||||
view.setZOrderMediaOverlay(translucent);
|
||||
} else {
|
||||
view.setZOrderOnTop(translucent);
|
||||
}
|
||||
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
view.getHolder().setFormat(format);
|
||||
|
||||
mRenderSurface = new SurfaceViewHandler(view);
|
||||
|
||||
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
|
||||
@@ -381,7 +409,6 @@ public class UiHelper {
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
callback.surfaceCreated(holder);
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
callback.surfaceChanged(holder, format,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
|
||||
@@ -26,16 +26,14 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* Note that adding this annotation to a method is not enough to guarantee that
|
||||
* it is kept - either its class must be referenced elsewhere in the program, or
|
||||
* the class must be annotated with this as well.
|
||||
* the class must be annotated with this as well. Usage example:
|
||||
* <pre>
|
||||
*
|
||||
* Usage example:<br />
|
||||
* {@code
|
||||
* @UsedByNative("NativeCrashHandler.cpp")
|
||||
public static void reportCrash(int signal, int code, int address) {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
* @UsedByNative("NativeCrashHandler.cpp")
|
||||
* public static void reportCrash(int signal, int code, int address) {
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@Target({
|
||||
ElementType.METHOD,
|
||||
|
||||
@@ -26,16 +26,14 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* Note that adding this annotation to a method is not enough to guarantee that
|
||||
* it is kept - either its class must be referenced elsewhere in the program, or
|
||||
* the class must be annotated with this as well.
|
||||
* the class must be annotated with this as well. Usage example:
|
||||
* <pre>
|
||||
*
|
||||
* Usage example:<br />
|
||||
* {@code
|
||||
* @UsedByReflection("PeopleListItemView.java")
|
||||
public PeopleListItemViewV11(Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
||||
* @UsedByReflection("PeopleListItemView.java")
|
||||
* public PeopleListItemViewV11(Context context) {
|
||||
* super(context);
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
@Target({
|
||||
ElementType.METHOD,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user