Compare commits
415
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
791f51dcb4 | ||
|
|
4621f3ec5d | ||
|
|
ab9c09d0d9 | ||
|
|
dbf51c1c7d | ||
|
|
ebd5f150c1 | ||
|
|
156dcb54e8 | ||
|
|
88ef76989c | ||
|
|
fc284af684 | ||
|
|
3a8685cd15 | ||
|
|
f035655f5b | ||
|
|
f498e08d1e | ||
|
|
db3186a65f | ||
|
|
248815a3e0 | ||
|
|
ebb62b5d55 | ||
|
|
b9a5ad205a | ||
|
|
100986d8d9 | ||
|
|
b7c9a36d57 | ||
|
|
d76551ab28 | ||
|
|
92bc0752d1 | ||
|
|
657c251463 | ||
|
|
b6b8fee483 | ||
|
|
be5b60f895 | ||
|
|
681d31758f | ||
|
|
80dc2f5c9d | ||
|
|
ce7dd7a1fb | ||
|
|
85617c96a2 | ||
|
|
58760adb6a | ||
|
|
4ef0b72773 | ||
|
|
45631c3b81 | ||
|
|
6f6dde2579 | ||
|
|
e0acbe42cf | ||
|
|
4f137ccf89 | ||
|
|
04010e7dd9 | ||
|
|
f4f9f331c0 | ||
|
|
dada291f6b | ||
|
|
18f2f8b6d4 | ||
|
|
d4117ac968 | ||
|
|
eccbc8c242 | ||
|
|
3cdf24f515 | ||
|
|
d91faf9df8 | ||
|
|
d950efa6ea | ||
|
|
861d69ea7c | ||
|
|
b2cc904fab | ||
|
|
3f87b520bb | ||
|
|
135a362176 | ||
|
|
391ebc3702 | ||
|
|
b4d1443720 | ||
|
|
c06737aca2 | ||
|
|
f847232296 | ||
|
|
89f06b8923 | ||
|
|
90a2b1f3c9 | ||
|
|
059f51338d | ||
|
|
d3cea5121e | ||
|
|
c37301d2dc | ||
|
|
aa16778fbd | ||
|
|
ee499ad2ca | ||
|
|
958dd5bb27 | ||
|
|
f988b75999 | ||
|
|
e3ccb4bb3c | ||
|
|
3f0dc6f7e6 | ||
|
|
c212dd5bc7 | ||
|
|
1eceab0040 | ||
|
|
ab9d1e5956 | ||
|
|
c906290416 | ||
|
|
d52a24b6e9 | ||
|
|
9aeec3a759 | ||
|
|
550fcfe2e3 | ||
|
|
b2cdf9f2b4 | ||
|
|
19a3fe3dce | ||
|
|
754abbf78e | ||
|
|
9b855e9a03 | ||
|
|
2534fdf92d | ||
|
|
dab02e915e | ||
|
|
68da1a25eb | ||
|
|
c67b363576 | ||
|
|
5c0e7d8211 | ||
|
|
3d57c60840 | ||
|
|
8ab2725a79 | ||
|
|
ff27f8109c | ||
|
|
8e09d8bd71 | ||
|
|
d6df4cd03a | ||
|
|
df03fdf3d7 | ||
|
|
6c59945395 | ||
|
|
d16cc50561 | ||
|
|
e667484a94 | ||
|
|
71e5e6c6c0 | ||
|
|
c1df902593 | ||
|
|
3c3320a2ba | ||
|
|
35753bc6c2 | ||
|
|
5f7967d09c | ||
|
|
404b6e8af3 | ||
|
|
898c20e584 | ||
|
|
f278b76b04 | ||
|
|
6353f17635 | ||
|
|
9cae34babf | ||
|
|
c37cc61b30 | ||
|
|
9aced8e9b8 | ||
|
|
dde060bf4d | ||
|
|
b60518caa5 | ||
|
|
69000ef1f2 | ||
|
|
39d6106ef2 | ||
|
|
96a1cbe69f | ||
|
|
09fe495384 | ||
|
|
8457d6092d | ||
|
|
72c16e07ed | ||
|
|
12b96cba04 | ||
|
|
e4d943e942 | ||
|
|
7fa66325f3 | ||
|
|
e188a7875e | ||
|
|
ac9822b8c8 | ||
|
|
edb5fddd03 | ||
|
|
35f4a97e32 | ||
|
|
487b10fdda | ||
|
|
271cda88aa | ||
|
|
25b73ddcfa | ||
|
|
35b8146a87 | ||
|
|
091e5a33ac | ||
|
|
ffe4b7390d | ||
|
|
604d3e34a4 | ||
|
|
e116dd4aec | ||
|
|
d53614fb0a | ||
|
|
c91e5df117 | ||
|
|
96574816b3 | ||
|
|
b43a609ebc | ||
|
|
2c490ec799 | ||
|
|
fbb08d338a | ||
|
|
8e1718458a | ||
|
|
6bcd709320 | ||
|
|
1a6e3ec88e | ||
|
|
f5f50eca06 | ||
|
|
886fb7fb94 | ||
|
|
a82b3bedb2 | ||
|
|
d879bbc80a | ||
|
|
bf437b7933 | ||
|
|
49dff3c439 | ||
|
|
0d6c017cfb | ||
|
|
ba042db3f4 | ||
|
|
faeba6ad95 | ||
|
|
163e28ca7a | ||
|
|
3dbc168d76 | ||
|
|
fe49946852 | ||
|
|
6310ea46e3 | ||
|
|
ef8e3e5224 | ||
|
|
26cc722f74 | ||
|
|
043fdf7a51 | ||
|
|
c01105b49a | ||
|
|
f56f5a300c | ||
|
|
8b79f3683e | ||
|
|
319bd123ce | ||
|
|
e23243a65b | ||
|
|
c4261a8c10 | ||
|
|
009b58537e | ||
|
|
e51709a4e8 | ||
|
|
78813ed9b7 | ||
|
|
2e649a9f16 | ||
|
|
d36783cd1d | ||
|
|
101a59138c | ||
|
|
3809259f47 | ||
|
|
e103b28b41 | ||
|
|
8e7d0c0df9 | ||
|
|
d8845e5fcc | ||
|
|
b2ed544ee8 | ||
|
|
a40ee77326 | ||
|
|
85135e60c7 | ||
|
|
bee9f160fa | ||
|
|
64c67258b0 | ||
|
|
49e0f484e9 | ||
|
|
dbc78ff0aa | ||
|
|
ebca955682 | ||
|
|
d8ea26e305 | ||
|
|
37aafdd912 | ||
|
|
edf78afa8e | ||
|
|
1df4218deb | ||
|
|
1c5715824f | ||
|
|
6da46b3b62 | ||
|
|
e8d8080928 | ||
|
|
e7934314ad | ||
|
|
c79fcf6d8d | ||
|
|
3eb2a20c7f | ||
|
|
da99fe63be | ||
|
|
d9067af3a3 | ||
|
|
f10bedf186 | ||
|
|
19b0ad2605 | ||
|
|
6e7af103d3 | ||
|
|
8a91723dcf | ||
|
|
47e30c337e | ||
|
|
fb627d8b66 | ||
|
|
1cb59685c5 | ||
|
|
2b395f1d89 | ||
|
|
e9718fa346 | ||
|
|
81fc2c1d23 | ||
|
|
dc60f57a9a | ||
|
|
5c4f12fa00 | ||
|
|
00ffd9ca74 | ||
|
|
166f859c72 | ||
|
|
1969186fe1 | ||
|
|
e1e7854d97 | ||
|
|
9d5220e28e | ||
|
|
fc0b41d587 | ||
|
|
e4cb861817 | ||
|
|
640f080ea6 | ||
|
|
eed4b3b839 | ||
|
|
f48dafe87e | ||
|
|
daff8fea9f | ||
|
|
51b4a38e20 | ||
|
|
2171e372ce | ||
|
|
1a30709121 | ||
|
|
2ed9b11f50 | ||
|
|
1797ff5d90 | ||
|
|
8c46e6de9b | ||
|
|
613adfa342 | ||
|
|
684b0622eb | ||
|
|
426f345f19 | ||
|
|
f80df6e061 | ||
|
|
e2177e8b36 | ||
|
|
37353cca55 | ||
|
|
c72817fc25 | ||
|
|
81c1d3ed1a | ||
|
|
0e1234c57d | ||
|
|
50fa816a6e | ||
|
|
07f4211dd3 | ||
|
|
44a433398f | ||
|
|
6821cb60b5 | ||
|
|
b8788bc390 | ||
|
|
94c59d9d97 | ||
|
|
5201b5a1ba | ||
|
|
215ef460ef | ||
|
|
90be8ebfa2 | ||
|
|
f62d58bd45 | ||
|
|
9e5da2d75f | ||
|
|
e12f079ac1 | ||
|
|
3c0f18753f | ||
|
|
a0e4d3df32 | ||
|
|
4f590e3326 | ||
|
|
6fdfe606e6 | ||
|
|
1baab6c3ae | ||
|
|
61e67a2766 | ||
|
|
8277015785 | ||
|
|
97952e0ddc | ||
|
|
b80d73f3cf | ||
|
|
a1bf6a427d | ||
|
|
67144bec73 | ||
|
|
f801763e6b | ||
|
|
542dd331d7 | ||
|
|
4ac3454dc6 | ||
|
|
23b578ef89 | ||
|
|
b6c26ab4e4 | ||
|
|
4fbcfc3168 | ||
|
|
9d0aab4d21 | ||
|
|
6420bc6dd8 | ||
|
|
9fa41d06d6 | ||
|
|
805227d6fc | ||
|
|
67d4632868 | ||
|
|
7efe967add | ||
|
|
a8cdfc6b23 | ||
|
|
7964ebf3c5 | ||
|
|
49b8e5e5d2 | ||
|
|
54e6b6b24a | ||
|
|
0fe6cfb224 | ||
|
|
0ee540df9c | ||
|
|
249f0a80d8 | ||
|
|
b3368a3fb2 | ||
|
|
327576274f | ||
|
|
0e7004a7f8 | ||
|
|
ca8549549c | ||
|
|
fa6d9a4b01 | ||
|
|
3693e4909b | ||
|
|
697a8370cb | ||
|
|
155a362d60 | ||
|
|
fed95d70b0 | ||
|
|
cd126138e0 | ||
|
|
7e7398aa92 | ||
|
|
ede7c579f9 | ||
|
|
67aa6f1913 | ||
|
|
80eba1de10 | ||
|
|
5e05a23e94 | ||
|
|
8c8061a637 | ||
|
|
9ef3c59698 | ||
|
|
5f7c6c2fbf | ||
|
|
991360da97 | ||
|
|
50d9fb2b5b | ||
|
|
001a3e3dc8 | ||
|
|
b6eca61786 | ||
|
|
cc75eb3aa2 | ||
|
|
f5fda88cf6 | ||
|
|
e99f13b14d | ||
|
|
08e809bf75 | ||
|
|
1d6aeb5de1 | ||
|
|
d13ccd1c26 | ||
|
|
54482e6451 | ||
|
|
9491b36a25 | ||
|
|
d387e14d4c | ||
|
|
5c41b332ad | ||
|
|
fd69c7ed75 | ||
|
|
3ff8d6dc22 | ||
|
|
af6fd21e11 | ||
|
|
5bd5c50c8d | ||
|
|
2c8d296044 | ||
|
|
df6a100fcb | ||
|
|
3f6188edff | ||
|
|
cc0486b3cc | ||
|
|
8314bafc0e | ||
|
|
764c695e4e | ||
|
|
808ca42992 | ||
|
|
4a8428318b | ||
|
|
c93059783b | ||
|
|
d21f092645 | ||
|
|
9844803b26 | ||
|
|
2e0ace5026 | ||
|
|
b8725ffa22 | ||
|
|
d2da478923 | ||
|
|
0b3e557b65 | ||
|
|
0d2faa4573 | ||
|
|
1924810c17 | ||
|
|
6ab45a4cf0 | ||
|
|
5e2c94c31a | ||
|
|
c1a99921b0 | ||
|
|
4a0dbbce12 | ||
|
|
7398183d6f | ||
|
|
edf405c8fd | ||
|
|
4cc8f88a21 | ||
|
|
5dba7fdae0 | ||
|
|
e2b8573bd7 | ||
|
|
6eeb4c9d3a | ||
|
|
996981b102 | ||
|
|
4f4330c95e | ||
|
|
e48f54a863 | ||
|
|
2aa8ea4687 | ||
|
|
cde055e5bf | ||
|
|
19729db982 | ||
|
|
2029c9584e | ||
|
|
d9cbe60ca6 | ||
|
|
04337fdb68 | ||
|
|
a43b17716f | ||
|
|
63032ed0a6 | ||
|
|
b6cd6668a6 | ||
|
|
dee41e6120 | ||
|
|
7b03cb9b76 | ||
|
|
8aa83d4886 | ||
|
|
c17b3756ea | ||
|
|
73e339b05d | ||
|
|
42172c7395 | ||
|
|
fbc0b8dab5 | ||
|
|
91b45d2890 | ||
|
|
9df13c1cd2 | ||
|
|
5a3853a442 | ||
|
|
70e14a1757 | ||
|
|
4c4a93d9b5 | ||
|
|
001dcefd8a | ||
|
|
d114d547be | ||
|
|
6403e0ce44 | ||
|
|
41cf507746 | ||
|
|
c49fcf9018 | ||
|
|
354c39be6b | ||
|
|
26bbe8ade1 | ||
|
|
1952f0a1f7 | ||
|
|
61fdc0d375 | ||
|
|
4060b558c7 | ||
|
|
a783df39ba | ||
|
|
a9ccaf2ffb | ||
|
|
f40b08d826 | ||
|
|
9fd0397d45 | ||
|
|
69fb7170a7 | ||
|
|
b69546c229 | ||
|
|
45054eece9 | ||
|
|
785f7de25d | ||
|
|
509fb4ad23 | ||
|
|
6577519bd7 | ||
|
|
43948421d7 | ||
|
|
328650df17 | ||
|
|
b657ccd75a | ||
|
|
11cbb3d395 | ||
|
|
c21d7c3f5e | ||
|
|
975665c9c9 | ||
|
|
613e1052c7 | ||
|
|
ba9e7fa17f | ||
|
|
fa54bdd682 | ||
|
|
1678d02c87 | ||
|
|
5e535165a6 | ||
|
|
3de427b74f | ||
|
|
15899af7cf | ||
|
|
443181c719 | ||
|
|
02f96e2a1e | ||
|
|
67e0aa5488 | ||
|
|
c969005bcc | ||
|
|
5417d0953b | ||
|
|
ddb4865ceb | ||
|
|
7b5cac6d4f | ||
|
|
fb76f8ed80 | ||
|
|
4b572cf065 | ||
|
|
3e3fc76688 | ||
|
|
700b4d5d38 | ||
|
|
9e29d042b9 | ||
|
|
13f3ebca89 | ||
|
|
3e30632b8c | ||
|
|
a8d72bb226 | ||
|
|
bf3f7e0aef | ||
|
|
0fb04c576d | ||
|
|
caaa404d96 | ||
|
|
2fa6e6d031 | ||
|
|
62bb25b26d | ||
|
|
8d1402d37b | ||
|
|
afd657d6af | ||
|
|
27a5158147 | ||
|
|
dead7ab2ac | ||
|
|
352acff396 | ||
|
|
00d9c6921d | ||
|
|
6805940bbf | ||
|
|
954f9112e4 | ||
|
|
6465b9ade8 | ||
|
|
b67963176b | ||
|
|
fb1eb35ba5 | ||
|
|
047543a4a6 | ||
|
|
5e0615040d | ||
|
|
1ceed1519b |
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
@@ -50,8 +50,7 @@ jobs:
|
||||
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
|
||||
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
@@ -80,8 +79,7 @@ jobs:
|
||||
cd build/web && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
@@ -123,15 +121,13 @@ jobs:
|
||||
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
|
||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
@@ -158,8 +154,7 @@ jobs:
|
||||
cd build/ios && printf "y" | ./build.sh release
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
pip3 install PyGithub
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
@@ -168,7 +163,7 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'windows'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
+1
-1
@@ -349,7 +349,7 @@ 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/2.0.23.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
|
||||
+8
-4
@@ -123,6 +123,10 @@ if (ANDROID OR WEBGL OR IOS OR FILAMENT_LINUX_IS_MOBILE)
|
||||
set(IS_MOBILE_TARGET TRUE)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
add_definitions(-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS AND NOT FILAMENT_LINUX_IS_MOBILE)
|
||||
set(IS_HOST_PLATFORM TRUE)
|
||||
endif()
|
||||
@@ -264,7 +268,7 @@ 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")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function -Wno-deprecated-declarations")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_USE_EXTERNAL_GLES3)
|
||||
@@ -295,7 +299,7 @@ if (LINUX)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Werror=unguarded-availability")
|
||||
endif()
|
||||
|
||||
if (CYGWIN)
|
||||
@@ -643,12 +647,14 @@ add_subdirectory(${LIBRARIES}/gltfio)
|
||||
add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/iblprefilter)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/ktxreader)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/mathio)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
add_subdirectory(${LIBRARIES}/viewer)
|
||||
add_subdirectory(${FILAMENT}/filament)
|
||||
add_subdirectory(${FILAMENT}/shaders)
|
||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
@@ -701,8 +707,6 @@ if (IS_HOST_PLATFORM)
|
||||
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/libassimp/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libpng/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.16.0'
|
||||
implementation 'com.google.android.filament:filament-android:1.21.3'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,7 +43,6 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite) | Trimmed version of `filament-utils` that does not support some glTF features. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||
|
||||
@@ -52,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.16.0'
|
||||
pod 'Filament', '~> 1.21.3'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -63,7 +62,7 @@ steps:
|
||||
1. Find the [commit](https://github.com/google/filament/commits/main) 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.
|
||||
4. On the top left click _Summary_, then in the _Artifacts_ section choose the desired artifact.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -126,6 +125,7 @@ steps:
|
||||
- Transparent shadows
|
||||
- Contact shadows
|
||||
- Screen-space ambient occlusion
|
||||
- Screen-space reflections
|
||||
- Screen-space refraction
|
||||
- Global fog
|
||||
- Dynamic resolution (with support for AMD FidelityFX FSR)
|
||||
@@ -168,13 +168,16 @@ steps:
|
||||
- [x] KHR_draco_mesh_compression
|
||||
- [x] KHR_lights_punctual
|
||||
- [x] KHR_materials_clearcoat
|
||||
- [x] KHR_materials_emissive_strength
|
||||
- [x] KHR_materials_ior
|
||||
- [x] KHR_materials_pbrSpecularGlossiness
|
||||
- [x] KHR_materials_sheen
|
||||
- [x] KHR_materials_transmission
|
||||
- [x] KHR_materials_unlit
|
||||
- [x] KHR_materials_variants
|
||||
- [x] KHR_materials_volume
|
||||
- [x] KHR_mesh_quantization
|
||||
- [x] KHR_texture_basisu
|
||||
- [x] KHR_texture_transform
|
||||
|
||||
|
||||
|
||||
+122
-6
@@ -3,10 +3,126 @@
|
||||
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.
|
||||
|
||||
## v1.16.2 (currently main branch)
|
||||
## v1.22.1 (currently main branch)
|
||||
|
||||
## v1.22.0
|
||||
|
||||
- engine: Changed UBOs layout [⚠️ **Material breakage**].
|
||||
- engine: Improve effects relying on mipmapping
|
||||
|
||||
## v1.21.3
|
||||
|
||||
- Java: Renamed the `KTXLoader` Kotlin class to `KTX1Loader`. [⚠️ **API Change**].
|
||||
- libs: Added `Ktx2Reader` and `BasisEncoder` to support Basis-encoded KTX2 files.
|
||||
- engine: Remove deprecated `Stream` APIs, see `Texture::import()` for an alternative [⚠️ **API Change**].
|
||||
- tools: Removed KTX1 compression support from mipgen. [⚠️ **API Change**].
|
||||
- tools: Added support for KTX2 to mipgen.
|
||||
- gltfio: Added `resetBoneMatrices()` method.
|
||||
- gltfio: Introduced `TextureProvider` interface. [⚠️ **API Change**].
|
||||
- gltfio: Fix progress indicator when error occurs.
|
||||
- samples: Desktop and Web Suzanne samples now use KTX2 instead of KTX1.
|
||||
- samples: Fix regression with sample-gltf-viewer and zip files.
|
||||
|
||||
## v1.21.2
|
||||
|
||||
- Java: Add Java binding to get skins in `FilamentAsset`.
|
||||
- libs: Add libs/ktxreader [⚠️ **API Change**].
|
||||
- mipgen: fixups / clarification regarding sRGB.
|
||||
- WebGL: fix intermittent 'detached ArrayBuffer' errors.
|
||||
|
||||
## v1.21.1
|
||||
|
||||
- engine: Allow both screen-space refraction and screen-space reflections on the same object [⚠️ **Material breakage**].
|
||||
- engine: Optimizations for screen-space reflections.
|
||||
- engine: Remove `Viewport::scale()` [⚠️ **API Change**].
|
||||
- engine: Fix 12x overallocation of memory in `MorphTargetBuffer`.
|
||||
- Metal: Fix validation error when reading from default `SwapChain`.
|
||||
|
||||
## v1.21.0
|
||||
|
||||
- engine: OpenGL performance improvements with some drivers.
|
||||
- engine: Fix incorrect shadows with some custom projection matrices.
|
||||
- engine: Fix low frame rates seen with a lot of morph targets.
|
||||
- gltfio: Add support for KHR_materials_variants.
|
||||
- gltfio: Add support for KHR_materials_emissive_strength.
|
||||
- gltfio: Java now exposes morph target names as an array for consistency [⚠️ **API Change**].
|
||||
|
||||
## v1.20.5
|
||||
|
||||
- engine: New behavior for MASKED to work with translucent views. [⚠️ **Recompile Materials** to get the fix]
|
||||
- engine: Fix screen-space reflections when post-processing and MSAA are off.
|
||||
- engine: Update MAX_MORPH_TARGETS constant to 256.
|
||||
- engine: Fix point light lighting with ortho projection.
|
||||
- libs: BlueGL symbols are now prefixed with `bluegl` on all platforms.
|
||||
- gltfio: Add skinning getters to `FilamentAsset`.
|
||||
|
||||
## v1.20.4
|
||||
|
||||
- gltfio: Java clients must now destroy the MaterialProvider [⚠️ **API Change**].
|
||||
- gltfio: Fix, bone pose not applied if glTF model doesn't have animations.
|
||||
- libs: Added `math::quat::fromDirectedRotation` [**NEW API**].
|
||||
- WebGL: Restore GL state when frame ends.
|
||||
|
||||
## v1.20.3
|
||||
|
||||
- Java: Fix URI bug in Android Viewer sample when dropping some zips.
|
||||
- Vulkan: Fix "uninitialized texture" warnings from the Vulkan backend.
|
||||
|
||||
## v1.20.2
|
||||
|
||||
- engine: Binary size optimizations.
|
||||
- engine: Fix, Mat4 from Quaternion was transposed.
|
||||
- Vulkan: Internal bug fixes and robustness improvements.
|
||||
- Vulkan: Reduced log spam.
|
||||
|
||||
## v1.20.1
|
||||
|
||||
- engine: Binary size improvements.
|
||||
- engine: Add basic support for instanced renderables [**NEW API**].
|
||||
- engine: Fix, first imaged passsed to `Stream::SetAcquiredImage` is ignored and leaked.
|
||||
- Vulkan: Robustness improvements.
|
||||
- Java: Fix, lookAt z axis negated.
|
||||
- gltfio: Be graceful when model has > 4 weights per vert.
|
||||
|
||||
## v1.20.0
|
||||
|
||||
- engine: Support rough screen-space reflections [⚠️ **Material breakage**].
|
||||
- engine: Added `Scene::forEach` API to iterate through a scene's entities.
|
||||
- engine: Fix incorrect normals with skinned models.
|
||||
- Vulkan: Fix segfault during shutdown.
|
||||
- WebGL: Support web apps that have multiple `FilamentViewer`s.
|
||||
- gltfio: Performance enhancements when loading models.
|
||||
|
||||
## v1.19.0
|
||||
|
||||
- engine: Support 256 morph targets.
|
||||
- engine: Screen-space reflection improvements.
|
||||
- engine: Morphing improvements and bug fixes.
|
||||
- gltfio: Generate morphing normals when they are missing.
|
||||
- gltfio: Support material extras.
|
||||
- Java: Add bindings for new morphing API.
|
||||
- Vulkan: Fix segfault on macOS.
|
||||
|
||||
## v1.18.0
|
||||
|
||||
- engine: Add support separate samplers in fragment and vertex shaders [⚠️ **Material breakage**].
|
||||
- engine: Support legacy morphing mode with vertex attributes.
|
||||
- engine: Allow more flexible quality settings for the ColorGrading LUT.
|
||||
- engine: Improve screen-space reflections quality and allow reflections and refractions together.
|
||||
- Vulkan: Bug fixes and improvements.
|
||||
|
||||
## v1.17.0
|
||||
|
||||
- engine: Add experimental glossy screen-space reflections.
|
||||
- engine: Add support for GPU morphing and 128 morph targets.
|
||||
- engine: Fix crash with non-shadow receiving renderables and VSM.
|
||||
- engine: Bring back the 3x3 filter for PCF shadows.
|
||||
- engine: Correct AABB calculation for skinned glTF models.
|
||||
|
||||
## v1.16.1
|
||||
|
||||
- engine: Added line/triangle strip support.
|
||||
|
||||
## v1.16.0
|
||||
|
||||
- engine: Fixes skinning calculations (#4887) [⚠️ **Material breakage**].
|
||||
@@ -17,10 +133,10 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## v1.15.2
|
||||
|
||||
- engine: add support for PCSS (Percentage Closer Soft Shadows).
|
||||
- engine: fix spotlight shadow bias.
|
||||
- samples: avoid leaking IBLs in Android sample-gltf-viewer.
|
||||
- libs: fix `libibl` on mobile.
|
||||
- engine: Add support for PCSS (Percentage Closer Soft Shadows).
|
||||
- engine: Fix spotlight shadow bias.
|
||||
- samples: Avoid leaking IBLs in Android sample-gltf-viewer.
|
||||
- libs: Fix `libibl` on mobile.
|
||||
|
||||
## v1.15.1
|
||||
|
||||
@@ -355,7 +471,7 @@ devices.
|
||||
- engine: Fix RenderTarget NPE when depth is not present.
|
||||
- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera.
|
||||
- engine: VSM shadows now support `shadowMultiplier`.
|
||||
- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
- java: Expose several MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
should have been public.
|
||||
- java: fix bug with Texture::setImage buffer size calculation.
|
||||
|
||||
|
||||
+16
-6
@@ -11,6 +11,9 @@
|
||||
// com.google.android.filament.exclude-vulkan
|
||||
// When set, support for Vulkan will be excluded.
|
||||
//
|
||||
// com.google.android.filament.matdbg
|
||||
// When set, enables matdbg, disables shader optimizations
|
||||
//
|
||||
// com.google.android.filament.skip-samples
|
||||
// Exclude samples from the project. Useful to speed up compilation.
|
||||
//
|
||||
@@ -59,6 +62,11 @@ buildscript {
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def matdbg = providers
|
||||
.gradleProperty("com.google.android.filament.matdbg")
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
|
||||
def newAbis = providers
|
||||
.gradleProperty("com.google.android.filament.abis")
|
||||
@@ -73,9 +81,9 @@ buildscript {
|
||||
'minSdk': 19,
|
||||
'targetSdk': 31,
|
||||
'compileSdk': 31,
|
||||
'kotlin': '1.6.0',
|
||||
'kotlin_coroutines': '1.5.2',
|
||||
'buildTools': '31.0.0',
|
||||
'kotlin': '1.6.10',
|
||||
'kotlin_coroutines': '1.6.0',
|
||||
'buildTools': '32.0.0',
|
||||
'ndk': '23.1.7779620'
|
||||
]
|
||||
|
||||
@@ -92,8 +100,8 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
// NOTE: See TODO in gradle.properties once we move to Gradle 7.2
|
||||
classpath 'com.android.tools.build:gradle:7.0.3'
|
||||
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -102,7 +110,9 @@ buildscript {
|
||||
"-DANDROID_PLATFORM=21",
|
||||
"-DANDROID_STL=c++_static",
|
||||
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString()
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
|
||||
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
|
||||
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
|
||||
]
|
||||
|
||||
ext.cppFlags = [
|
||||
|
||||
@@ -370,3 +370,10 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariant
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->variantFilter((uint8_t) variantFilter);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUseLegacyMorphing(JNIEnv*,
|
||||
jclass, jlong nativeBuilder) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->useLegacyMorphing();
|
||||
}
|
||||
|
||||
+15
-1
@@ -133,7 +133,7 @@ public class MaterialBuilder {
|
||||
FADE, // material is transparent and color is alpha-pre-multiplied,
|
||||
// affects specular lighting
|
||||
MULTIPLY, // material darkens what's behind it
|
||||
SCREN // material brightens what's behind it
|
||||
SCREEN // material brightens what's behind it
|
||||
}
|
||||
|
||||
public enum VertexDomain {
|
||||
@@ -459,6 +459,19 @@ public class MaterialBuilder {
|
||||
@NonNull
|
||||
public MaterialBuilder variantFilter(int variantFilter) {
|
||||
nMaterialBuilderVariantFilter(mNativeObject, variantFilter);
|
||||
useLegacyMorphing();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy morphing uses the data in the {@link VertexBuffer.VertexAttribute} slots
|
||||
* (<code>MORPH_POSITION_0</code>, etc) and is limited to 4 morph targets.
|
||||
*
|
||||
* @see RenderableManager.Builder#morphing()
|
||||
*/
|
||||
@NonNull
|
||||
public MaterialBuilder useLegacyMorphing() {
|
||||
nMaterialBuilderUseLegacyMorphing(mNativeObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -599,4 +612,5 @@ public class MaterialBuilder {
|
||||
private static native void nMaterialBuilderOptimization(long nativeBuilder, int optimization);
|
||||
private static native void nMaterialBuilderVariantFilter(long nativeBuilder,
|
||||
int variantFilter);
|
||||
private static native void nMaterialBuilderUseLegacyMorphing(long nativeBuilder);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ add_library(filament-jni SHARED
|
||||
src/main/cpp/Material.cpp
|
||||
src/main/cpp/MaterialInstance.cpp
|
||||
src/main/cpp/MathUtils.cpp
|
||||
src/main/cpp/MorphTargetBuffer.cpp
|
||||
src/main/cpp/RenderableManager.cpp
|
||||
src/main/cpp/Renderer.cpp
|
||||
src/main/cpp/RenderTarget.cpp
|
||||
|
||||
@@ -50,6 +50,19 @@ Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, j
|
||||
builder->quality(quality);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderFormat(JNIEnv*, jclass, jlong nativeBuilder, jint format_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
ColorGrading::LutFormat format = (ColorGrading::LutFormat) format_;
|
||||
builder->format(format);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderDimensions(JNIEnv*, jclass, jlong nativeBuilder, jint dim_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->dimensions((uint8_t)dim_);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderToneMapper(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong toneMapper_) {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 <functional>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <filament/MorphTargetBuffer.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new MorphTargetBuffer::Builder();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint vertexCount) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
builder->vertexCount((size_t) vertexCount);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint count) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
builder->count((size_t) count);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nSetPositionsAt(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jlong nativeEngine,
|
||||
jint targetIndex, jfloatArray positions, jint count) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
jfloat* data = env->GetFloatArrayElements(positions, NULL);
|
||||
morphTargetBuffer->setPositionsAt(*engine, targetIndex,
|
||||
(math::float4*) data, size_t(count));
|
||||
env->ReleaseFloatArrayElements(positions, data, JNI_ABORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nSetTangentsAt(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jlong nativeEngine,
|
||||
jint targetIndex, jshortArray tangents, jint count) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
jshort* data = env->GetShortArrayElements(tangents, NULL);
|
||||
morphTargetBuffer->setTangentsAt(*engine, targetIndex,
|
||||
(math::short4*) data, size_t(count));
|
||||
env->ReleaseShortArrayElements(tangents, data, JNI_ABORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nGetVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeObject) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
return (jint)morphTargetBuffer->getVertexCount();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nGetCount(JNIEnv*, jclass,
|
||||
jlong nativeObject) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
return (jint)morphTargetBuffer->getCount();
|
||||
}
|
||||
@@ -209,9 +209,18 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv*
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
jlong nativeBuilder, jint targetCount) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->morphing(enabled);
|
||||
builder->morphing(targetCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSetMorphTargetBufferAt(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, int level, int primitiveIndex, jlong nativeMorphTargetBuffer,
|
||||
int offset, int count) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
|
||||
builder->morphing(level, primitiveIndex, morphTargetBuffer, offset, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -221,6 +230,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderLightChannel(JNIEnv*,
|
||||
builder->lightChannel(channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderInstances(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint instanceCount) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->instances(instanceCount);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -267,12 +283,29 @@ Java_com_google_android_filament_RenderableManager_nSetBonesAsQuaternions(JNIEnv
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetMorphWeights(JNIEnv* env, jclass,
|
||||
jlong nativeRenderableManager, jint instance, jfloatArray weights) {
|
||||
jlong nativeRenderableManager, jint instance, jfloatArray weights, jint offset) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
jfloat* vec = env->GetFloatArrayElements(weights, NULL);
|
||||
math::float4 floatvec(vec[0], vec[1], vec[2], vec[3]);
|
||||
jsize count = env->GetArrayLength(weights);
|
||||
rm->setMorphWeights((RenderableManager::Instance)instance, vec, count, offset);
|
||||
env->ReleaseFloatArrayElements(weights, vec, JNI_ABORT);
|
||||
rm->setMorphWeights((RenderableManager::Instance)instance, floatvec);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetMorphTargetBufferAt(JNIEnv*,
|
||||
jclass, jlong nativeRenderableManager, jint i, int level, jint primitiveIndex,
|
||||
jlong nativeMorphTargetBuffer, jint offset, jint count) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
|
||||
rm->setMorphTargetBufferAt((RenderableManager::Instance) i, (uint8_t) level,
|
||||
(size_t) primitiveIndex, morphTargetBuffer, (size_t) offset, (size_t) count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetMorphTargetCount(JNIEnv* env, jclass,
|
||||
jlong nativeRenderableManager, jint instance) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
return rm->getMorphTargetCount((RenderableManager::Instance)instance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -98,16 +98,6 @@ Java_com_google_android_filament_Stream_nBuilderStreamSource(JNIEnv* env,
|
||||
builder->setStreamSource(env, streamSource);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jlong externalTextureId) {
|
||||
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
builder->builder()->stream(externalTextureId);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderWidth(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jint width) {
|
||||
@@ -143,41 +133,6 @@ Java_com_google_android_filament_Stream_nSetDimensions(JNIEnv*, jclass, jlong na
|
||||
stream->setDimensions((uint32_t) width, (uint32_t) height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
|
||||
jlong nativeStream, jlong nativeEngine,
|
||||
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) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
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,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
stream->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
@@ -201,8 +156,8 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
|
||||
if (!AHardwareBuffer_fromHardwareBuffer_fn) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Filament", "AHardwareBuffer_fromHardwareBuffer is not available.");
|
||||
sHardwareBufferSupported = false;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AHardwareBuffer* nativeBuffer = AHardwareBuffer_fromHardwareBuffer_fn(env, hwbuffer);
|
||||
|
||||
@@ -49,8 +49,8 @@ Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jcl
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass,
|
||||
jfloat contrast, jfloat shoulder, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
|
||||
return (jlong) new GenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax);
|
||||
jfloat contrast, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
|
||||
return (jlong) new GenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
@@ -58,11 +58,6 @@ Java_com_google_android_filament_ToneMapper_nGenericGetContrast(JNIEnv*, jclass,
|
||||
return ((GenericToneMapper*) nativeObject)->getContrast();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetShoulder(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getShoulder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getMidGrayIn();
|
||||
@@ -84,12 +79,6 @@ Java_com_google_android_filament_ToneMapper_nGenericSetContrast(JNIEnv*, jclass,
|
||||
((GenericToneMapper*) nativeObject)->setContrast(contrast);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetShoulder(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat shoulder) {
|
||||
((GenericToneMapper*) nativeObject)->setShoulder(shoulder);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat midGrayIn) {
|
||||
|
||||
@@ -390,6 +390,16 @@ Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *,
|
||||
.filterWidth = filterWidth, .feedback = feedback, .enabled = (bool) enabled});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetScreenSpaceReflectionsOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat thickness, jfloat bias, jfloat maxDistance, jfloat stride, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setScreenSpaceReflectionsOptions({.thickness = thickness, .bias = bias,
|
||||
.maxDistance = maxDistance, .stride = stride, .enabled = (bool) enabled
|
||||
});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlong nativeView) {
|
||||
|
||||
@@ -105,6 +105,14 @@ public class ColorGrading {
|
||||
ULTRA
|
||||
}
|
||||
|
||||
/**
|
||||
* Color grading LUT format.
|
||||
*/
|
||||
public enum LutFormat {
|
||||
INTEGER,
|
||||
FLOAT
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available tone-mapping operators.
|
||||
*
|
||||
@@ -162,6 +170,36 @@ public class ColorGrading {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When color grading is implemented using a 3D LUT, this sets the texture format of
|
||||
* of the LUT. This overrides the value set by quality().
|
||||
*
|
||||
* The default is INTEGER
|
||||
*
|
||||
* @param format The desired format of the 3D LUT.
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder format(LutFormat format) {
|
||||
nBuilderFormat(mNativeBuilder, format.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When color grading is implemented using a 3D LUT, this sets the dimension of the LUT.
|
||||
* This overrides the value set by quality().
|
||||
*
|
||||
* The default is 32
|
||||
*
|
||||
* @param dim The desired dimension of the LUT. Between 16 and 64.
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder dimensions(int dim) {
|
||||
nBuilderDimensions(mNativeBuilder, dim);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the tone mapping operator to apply to the HDR color buffer as the last
|
||||
* operation of the color grading post-processing step.
|
||||
@@ -557,6 +595,8 @@ public class ColorGrading {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
|
||||
private static native void nBuilderQuality(long nativeBuilder, int quality);
|
||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||
private static native void nBuilderDimensions(long nativeBuilder, int dim);
|
||||
private static native void nBuilderToneMapper(long nativeBuilder, long toneMapper);
|
||||
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapping);
|
||||
private static native void nBuilderLuminanceScaling(long nativeBuilder, boolean luminanceScaling);
|
||||
|
||||
+4
@@ -239,6 +239,10 @@ public class MaterialInstance {
|
||||
|
||||
/**
|
||||
* Sets a texture and sampler parameter on this material's default instance.
|
||||
* <p>
|
||||
* Note: Depth textures can't be sampled with a linear filter unless the comparison mode is set
|
||||
* to COMPARE_TO_TEXTURE.
|
||||
* </p>
|
||||
*
|
||||
* @param name The name of the material texture parameter
|
||||
* @param texture The texture to set as parameter
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class MorphTargetBuffer {
|
||||
private long mNativeObject;
|
||||
private MorphTargetBuffer(long nativeMorphTargetBuffer) {
|
||||
mNativeObject = nativeMorphTargetBuffer;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final MorphTargetBuffer.Builder.BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new MorphTargetBuffer.Builder.BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the morph targets in vertex counts.
|
||||
*
|
||||
* @param vertexCount Number of vertex counts the morph targets can hold.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder vertexCount(@IntRange(from = 1) int vertexCount) {
|
||||
nBuilderVertexCount(mNativeBuilder, vertexCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the morph targets in targets.
|
||||
*
|
||||
* @param count Number of targets the morph targets can hold.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder count(@IntRange(from = 1) int count) {
|
||||
nBuilderCount(mNativeBuilder, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>MorphTargetBuffer</code> object.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>MorphTargetBuffer</code>
|
||||
* with.
|
||||
*
|
||||
* @return the newly created <code>MorphTargetBuffer</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the MorphTargetBuffer could not be created
|
||||
*
|
||||
* @see #setMorphTargetBufferAt
|
||||
*/
|
||||
@NonNull
|
||||
public MorphTargetBuffer build(@NonNull Engine engine) {
|
||||
long nativeMorphTargetBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
if (nativeMorphTargetBuffer == 0)
|
||||
throw new IllegalStateException("Couldn't create MorphTargetBuffer");
|
||||
return new MorphTargetBuffer(nativeMorphTargetBuffer);
|
||||
}
|
||||
|
||||
private static class BuilderFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
BuilderFinalizer(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyBuilder(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positions of morph target at the index.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param positions Pointer to at least count positions
|
||||
* @param count Number of position elements in positions
|
||||
*/
|
||||
public void setPositionsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@NonNull float[] positions, @IntRange(from = 0, to = 125) int count) {
|
||||
int result = nSetPositionsAt(mNativeObject, engine.getNativeObject(), targetIndex,
|
||||
positions, count);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates tangents of morph target at the index.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param tangents Pointer to at least count tangents
|
||||
* @param count Number of tangent elements in tangents
|
||||
*/
|
||||
public void setTangentsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@NonNull short[] tangents, @IntRange(from = 0, to = 125) int count) {
|
||||
int result = nSetTangentsAt(mNativeObject, engine.getNativeObject(), targetIndex,
|
||||
tangents, count);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of vertex count in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getVertexCount() {
|
||||
return nGetVertexCount(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of target count in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getCount() {
|
||||
return nGetCount(mNativeObject);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
void clearNativeObject() {
|
||||
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 nBuilderCount(long nativeBuilder, int count);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
|
||||
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
|
||||
private static native int nGetVertexCount(long nativeObject);
|
||||
private static native int nGetCount(long nativeObject);
|
||||
}
|
||||
+116
-11
@@ -284,6 +284,22 @@ public class RenderableManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the number of draw instance of this renderable. The default is 1 instance and
|
||||
* the maximum number of instances allowed is 65535. 0 is invalid.
|
||||
* All instances are culled using the same bounding box, so care must be taken to make
|
||||
* sure all instances render inside the specified bounding box.
|
||||
* The material can use getInstanceIndex() in the vertex shader to get the instance index and
|
||||
* possibly adjust the position or transform.
|
||||
*
|
||||
* @param instanceCount the number of instances silently clamped between 1 and 65535.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder instances(@IntRange(from = 1, to = 65535) int instanceCount) {
|
||||
nBuilderInstances(mNativeBuilder, instanceCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if this renderable casts shadows, false by default.
|
||||
*
|
||||
@@ -400,17 +416,67 @@ public class RenderableManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if the renderable has vertex morphing targets, false by default.
|
||||
* Controls if the renderable has vertex morphing targets, zero by default. This is
|
||||
* required to enable GPU morphing.
|
||||
*
|
||||
* <p>This is required to enable GPU morphing for up to 4 attributes. The attached VertexBuffer
|
||||
* must provide data in the appropriate VertexAttribute slots (<code>MORPH_POSITION_0</code> etc).</p>
|
||||
* <p>Filament supports two morphing modes: standard (default) and legacy.</p>
|
||||
*
|
||||
* <p>For standard morphing, A {@link MorphTargetBuffer} must be created and provided via
|
||||
* {@link RenderableManager#setMorphTargetBufferAt}. Standard morphing supports up to
|
||||
* <code>CONFIG_MAX_MORPH_TARGET_COUNT</code> morph targets.</p>
|
||||
*
|
||||
* For legacy morphing, the attached {@link VertexBuffer} must provide data in the
|
||||
* appropriate {@link VertexBuffer.VertexAttribute} slots (<code>MORPH_POSITION_0</code> etc).
|
||||
* Legacy morphing only supports up to 4 morph targets and will be deprecated in the future.
|
||||
* Legacy morphing must be enabled on the material definition: either via the
|
||||
* <code>legacyMorphing</code> material attribute or by calling
|
||||
* {@link MaterialBuilder::useLegacyMorphing}.
|
||||
*
|
||||
* <p>See also {@link RenderableManager#setMorphWeights}, which can be called on a per-frame basis
|
||||
* to advance the animation.</p>
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(boolean enabled) {
|
||||
nBuilderMorphing(mNativeBuilder, enabled);
|
||||
public Builder morphing(@IntRange(from = 0, to = 255) int targetCount) {
|
||||
nBuilderMorphing(mNativeBuilder, targetCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the morph target buffer for a primitive.
|
||||
*
|
||||
* The morph target buffer must have an associated renderable and geometry. Two conditions
|
||||
* must be met:
|
||||
* 1. The number of morph targets in the buffer must equal the renderable's morph target
|
||||
* count.
|
||||
* 2. The vertex count of each morph target must equal the geometry's vertex count.
|
||||
*
|
||||
* @param level the level of detail (lod), only 0 can be specified
|
||||
* @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor
|
||||
* @param morphTargetBuffer specifies the morph target buffer
|
||||
* @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices)
|
||||
* @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3)
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer,
|
||||
@IntRange(from = 0) int offset,
|
||||
@IntRange(from = 0) int count) {
|
||||
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), offset, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to specify morph target buffer for a primitive.
|
||||
* For details, see the {@link RenderableManager.Builder#morphing}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer) {
|
||||
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -497,15 +563,50 @@ public class RenderableManager {
|
||||
/**
|
||||
* Updates the vertex morphing weights on a renderable, all zeroes by default.
|
||||
*
|
||||
* <p>This is specified using a 4-tuple, one float per morph target. If the renderable has fewer
|
||||
* than 4 morph targets, then clients should fill the unused components with zeroes.</p>
|
||||
* <p>The renderable must be built with morphing enabled. In legacy morphing mode, only the
|
||||
* first 4 weights are considered.</p>
|
||||
*
|
||||
* @see Builder#morphing
|
||||
*/
|
||||
public void setMorphWeights(@EntityInstance int i, @NonNull float[] weights, @IntRange(from = 0) int offset) {
|
||||
nSetMorphWeights(mNativeObject, i, weights, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the morph target buffer for the given primitive.
|
||||
*
|
||||
* <p>The renderable must be built with morphing enabled.</p>
|
||||
*
|
||||
* @see Builder#morphing
|
||||
*/
|
||||
public void setMorphWeights(@EntityInstance int i, @NonNull @Size(min = 4) float[] weights) {
|
||||
nSetMorphWeights(mNativeObject, i, weights);
|
||||
public void setMorphTargetBufferAt(@EntityInstance int i,
|
||||
@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer,
|
||||
@IntRange(from = 0) int offset,
|
||||
@IntRange(from = 0) int count) {
|
||||
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to change morph target buffer for the given primitive.
|
||||
* For details, see the {@link RenderableManager#setMorphTargetBufferAt}.
|
||||
*/
|
||||
public void setMorphTargetBufferAt(@EntityInstance int i,
|
||||
@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer) {
|
||||
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the morph target count on a renderable.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getMorphTargetCount(@EntityInstance int i) {
|
||||
return nGetMorphTargetCount(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -762,14 +863,18 @@ public class RenderableManager {
|
||||
private static native void nBuilderSkinning(long nativeBuilder, int boneCount);
|
||||
private static native int nBuilderSkinningBones(long nativeBuilder, int boneCount, Buffer bones, int remaining);
|
||||
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
|
||||
private static native void nBuilderMorphing(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderMorphing(long nativeBuilder, int targetCount);
|
||||
private static native void nBuilderSetMorphTargetBufferAt(long nativeBuilder, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
|
||||
private static native void nEnableSkinningBuffers(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
|
||||
private static native void nBuilderInstances(long nativeRenderableManager, int instances);
|
||||
|
||||
private static native void nSetSkinningBuffer(long nativeObject, int i, long nativeSkinningBuffer, int count, int offset);
|
||||
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
|
||||
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
|
||||
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights);
|
||||
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights, int offset);
|
||||
private static native void nSetMorphTargetBufferAt(long nativeObject, int i, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
|
||||
private static native int nGetMorphTargetCount(long nativeObject, int i);
|
||||
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
|
||||
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||
|
||||
@@ -531,6 +531,10 @@ public class Renderer {
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>OpenGL only: if issuing a <code>readPixels</code> on a {@link RenderTarget} backed by a
|
||||
* {@link Texture} that had data uploaded to it via {@link Texture#setImage}, the data returned
|
||||
* from <code>readPixels</code> will be y-flipped with respect to the {@link Texture#setImage}
|
||||
* call.</p>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
|
||||
+4
-4
@@ -118,8 +118,8 @@ public class SkinningBuffer {
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsMatrices(@NonNull Engine engine,
|
||||
@NonNull Buffer matrices, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
@NonNull Buffer matrices, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsMatrices(mNativeObject, engine.getNativeObject(),
|
||||
matrices, matrices.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
@@ -138,8 +138,8 @@ public class SkinningBuffer {
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsQuaternions(@NonNull Engine engine,
|
||||
@NonNull Buffer quaternions, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
@NonNull Buffer quaternions, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsQuaternions(mNativeObject, engine.getNativeObject(),
|
||||
quaternions, quaternions.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
|
||||
@@ -103,9 +103,6 @@ public class Stream {
|
||||
/** 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,
|
||||
};
|
||||
@@ -121,7 +118,7 @@ public class Stream {
|
||||
* 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
|
||||
* To create a {@link StreamType#NATIVE NATIVE} stream, call one of the <pre>stream</pre> methods
|
||||
* on the builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
@@ -156,27 +153,6 @@ 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
|
||||
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@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
|
||||
@@ -276,92 +252,6 @@ public class Stream {
|
||||
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,
|
||||
@NonNull Texture.PixelBufferDescriptor buffer) {
|
||||
|
||||
if (buffer.storage.isReadOnly()) {
|
||||
throw new ReadOnlyBufferException();
|
||||
}
|
||||
|
||||
int result = nReadPixels(getNativeObject(), mNativeEngine,
|
||||
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 the presentation time of the currently displayed frame in nanosecond.
|
||||
*
|
||||
@@ -387,7 +277,6 @@ public class Stream {
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeStreamBuilder);
|
||||
private static native void nBuilderStreamSource(long nativeStreamBuilder, Object streamSource);
|
||||
private static native void nBuilderStream(long nativeStreamBuilder, long externalTextureId);
|
||||
private static native void nBuilderWidth(long nativeStreamBuilder, int width);
|
||||
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
|
||||
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
|
||||
|
||||
@@ -542,7 +542,7 @@ public class Texture {
|
||||
* @param alignment Alignment in bytes.
|
||||
* @return Size of the buffer in bytes.
|
||||
*/
|
||||
static int computeDataSize(@NonNull Format format, @NonNull Type type,
|
||||
public static int computeDataSize(@NonNull Format format, @NonNull Type type,
|
||||
int stride, int height, @IntRange(from = 1, to = 8) int alignment) {
|
||||
if (type == Type.COMPRESSED) {
|
||||
return 0;
|
||||
|
||||
@@ -109,7 +109,6 @@ public class ToneMapper {
|
||||
* The tone mapping curve is defined by 5 parameters:
|
||||
* <ul>
|
||||
* <li>contrast: controls the contrast of the curve</li>
|
||||
* <li>shoulder: controls the shoulder of the curve, i.e. how quickly scene
|
||||
* referred values map to output white</li>
|
||||
* <li>midGrayIn: sets the input middle gray</li>
|
||||
* <li>midGrayOut: sets the output middle gray</li>
|
||||
@@ -123,15 +122,14 @@ public class ToneMapper {
|
||||
* the {@link ACESLegacy} tone mapper. The default values are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>contrast = 1.585f</li>
|
||||
* <li>shoulder = 0.5f</li>
|
||||
* <li>contrast = 1.55f</li>
|
||||
* <li>midGrayIn = 0.18f</li>
|
||||
* <li>midGrayOut = 0.268f</li>
|
||||
* <li>midGrayOut = 0.215f</li>
|
||||
* <li>hdrMax = 10.0f</li>
|
||||
* </ul>
|
||||
*/
|
||||
public Generic() {
|
||||
this(1.585f, 0.5f, 0.18f, 0.268f, 10.0f);
|
||||
this(1.55f, 0.18f, 0.215f, 10.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,16 +137,14 @@ public class ToneMapper {
|
||||
*
|
||||
* @param contrast: controls the contrast of the curve, must be > 0.0, values
|
||||
* in the range 0.5..2.0 are recommended.
|
||||
* @param shoulder: controls the shoulder of the curve, i.e. how quickly scene
|
||||
* referred values map to output white, between 0.0 and 1.0.
|
||||
* @param midGrayIn: sets the input middle gray, between 0.0 and 1.0.
|
||||
* @param midGrayOut: sets the output middle gray, between 0.0 and 1.0.
|
||||
* @param hdrMax: defines the maximum input value that will be mapped to
|
||||
* output white. Must be >= 1.0.
|
||||
*/
|
||||
public Generic(
|
||||
float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax) {
|
||||
super(nCreateGenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax));
|
||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax) {
|
||||
super(nCreateGenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax));
|
||||
}
|
||||
|
||||
/** Returns the contrast of the curve as a strictly positive value. */
|
||||
@@ -161,16 +157,6 @@ public class ToneMapper {
|
||||
nGenericSetContrast(getNativeObject(), contrast);
|
||||
}
|
||||
|
||||
/** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */
|
||||
public float getShoulder() {
|
||||
return nGenericGetShoulder(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets how quickly scene referred values map to output white, between 0.0 and 1.0. */
|
||||
public void setShoulder(float shoulder) {
|
||||
nGenericSetShoulder(getNativeObject(), shoulder);
|
||||
}
|
||||
|
||||
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
|
||||
public float getMidGrayIn() {
|
||||
return nGenericGetMidGrayIn(getNativeObject());
|
||||
@@ -209,17 +195,15 @@ public class ToneMapper {
|
||||
private static native long nCreateACESLegacyToneMapper();
|
||||
private static native long nCreateFilmicToneMapper();
|
||||
private static native long nCreateGenericToneMapper(
|
||||
float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax);
|
||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
|
||||
|
||||
// Generic tone mappper
|
||||
private static native float nGenericGetContrast(long nativeObject);
|
||||
private static native float nGenericGetShoulder(long nativeObject);
|
||||
private static native float nGenericGetMidGrayIn(long nativeObject);
|
||||
private static native float nGenericGetMidGrayOut(long nativeObject);
|
||||
private static native float nGenericGetHdrMax(long nativeObject);
|
||||
|
||||
private static native void nGenericSetContrast(long nativeObject, float contrast);
|
||||
private static native void nGenericSetShoulder(long nativeObject, float shoulder);
|
||||
private static native void nGenericSetMidGrayIn(long nativeObject, float midGrayIn);
|
||||
private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut);
|
||||
private static native void nGenericSetHdrMax(long nativeObject, float hdrMax);
|
||||
|
||||
@@ -79,6 +79,7 @@ public class View {
|
||||
private VignetteOptions mVignetteOptions;
|
||||
private ColorGrading mColorGrading;
|
||||
private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions;
|
||||
private ScreenSpaceReflectionsOptions mScreenSpaceReflectionsOptions;
|
||||
private MultiSampleAntiAliasingOptions mMultiSampleAntiAliasingOptions;
|
||||
private VsmShadowOptions mVsmShadowOptions;
|
||||
private SoftShadowOptions mSoftShadowOptions;
|
||||
@@ -335,6 +336,28 @@ public class View {
|
||||
public boolean enabled = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for Screen-space Reflections.
|
||||
* @see View#setScreenSpaceReflectionOptions
|
||||
*/
|
||||
public static class ScreenSpaceReflectionsOptions {
|
||||
/** ray thickness, in world units */
|
||||
public float thickness = 0.1f;
|
||||
|
||||
/** bias, in world units, to prevent self-intersections */
|
||||
public float bias = 0.01f;
|
||||
|
||||
/** maximum distance, in world units, to raycast */
|
||||
public float maxDistance = 3.0f;
|
||||
|
||||
/** stride, in texels, for samples along the ray. */
|
||||
public float stride = 2.0f;
|
||||
|
||||
/** enables or disables screen-space reflections */
|
||||
public boolean enabled = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Options for controlling the Bloom effect
|
||||
*
|
||||
@@ -1185,6 +1208,17 @@ public class View {
|
||||
options.feedback, options.filterWidth, options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable screen-space reflections. Disabled by default.
|
||||
*
|
||||
* @param options screen-space reflections options
|
||||
*/
|
||||
public void setScreenSpaceReflectionsOptions(@NonNull ScreenSpaceReflectionsOptions options) {
|
||||
mScreenSpaceReflectionsOptions = options;
|
||||
nSetScreenSpaceReflectionsOptions(getNativeObject(), options.thickness, options.bias,
|
||||
options.maxDistance, options.stride, options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns temporal anti-aliasing options.
|
||||
*
|
||||
@@ -1198,6 +1232,19 @@ public class View {
|
||||
return mTemporalAntiAliasingOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns screen-space reflections options.
|
||||
*
|
||||
* @return screen-space reflections options
|
||||
*/
|
||||
@NonNull
|
||||
public ScreenSpaceReflectionsOptions getScreenSpaceReflectionsOptions() {
|
||||
if (mScreenSpaceReflectionsOptions == null) {
|
||||
mScreenSpaceReflectionsOptions = new ScreenSpaceReflectionsOptions();
|
||||
}
|
||||
return mScreenSpaceReflectionsOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables tone-mapping in the post-processing stage. Enabled by default.
|
||||
*
|
||||
@@ -1337,21 +1384,26 @@ public class View {
|
||||
*
|
||||
* <p>Post-processing includes:</p>
|
||||
* <ul>
|
||||
* <li>Tone-mapping & gamma encoding</li>
|
||||
* <li>Depth-of-field</li>
|
||||
* <li>Bloom</li>
|
||||
* <li>Vignetting</li>
|
||||
* <li>Temporal Anti-aliasing (TAA)</li>
|
||||
* <li>Color grading & 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).
|
||||
* Disabling post-processing forgoes color correctness as well as some anti-aliasing techniques
|
||||
* and should only be used for debugging, UI overlays or when using custom render targets
|
||||
* (see RenderTarget).
|
||||
* </p>
|
||||
*
|
||||
* @param enabled true enables post processing, false disables it
|
||||
*
|
||||
* @see #setToneMapping
|
||||
* @see #setBloomOptions
|
||||
* @see #setColorGrading
|
||||
* @see #setAntiAliasing
|
||||
* @see #setDithering
|
||||
* @see #setSampleCount
|
||||
@@ -1777,6 +1829,7 @@ public class View {
|
||||
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
|
||||
private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled);
|
||||
private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled);
|
||||
private static native void nSetScreenSpaceReflectionsOptions(long nativeView, float thickness, float bias, float maxDistance, float stride, boolean enabled);
|
||||
private static native void nSetMultiSampleAntiAliasingOptions(long nativeView, boolean enabled, int sampleCount, boolean customResolve);
|
||||
private static native boolean nIsShadowingEnabled(long nativeView);
|
||||
private static native void nSetScreenSpaceRefractionEnabled(long nativeView, boolean enabled);
|
||||
|
||||
@@ -14,6 +14,10 @@ add_library(image STATIC IMPORTED)
|
||||
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
|
||||
add_library(viewer STATIC IMPORTED)
|
||||
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
|
||||
@@ -64,5 +68,6 @@ target_link_libraries(filament-utils-jni
|
||||
camutils
|
||||
iblprefilter
|
||||
image
|
||||
ktxreader
|
||||
viewer
|
||||
)
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
dimension "functionality"
|
||||
}
|
||||
|
||||
lite {
|
||||
dimension "functionality"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
// hack: this is needed because filament-utils-android/CMakeLists.txt builds
|
||||
// gltfio from source, which needs this defined
|
||||
arguments.add("-DGLTFIO_LITE=ON")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
kotlin.srcDirs += "src/main/java"
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
@@ -55,9 +41,7 @@ dependencies {
|
||||
implementation deps.coroutines.android
|
||||
|
||||
api project(':filament-android')
|
||||
|
||||
fullApi module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
liteApi module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
|
||||
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
@@ -65,14 +49,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
afterEvaluate {
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
POM_NAME=Filament Android Utilities
|
||||
POM_ARTIFACT_ID_FULL=filament-utils-android
|
||||
POM_ARTIFACT_ID_LITE=filament-utils-android-lite
|
||||
POM_ARTIFACT_ID=filament-utils-android
|
||||
POM_PACKAGING=aar
|
||||
|
||||
@@ -20,13 +20,14 @@
|
||||
#include <filament/IndirectLight.h>
|
||||
#include <filament/Skybox.h>
|
||||
|
||||
#include <image/KtxUtility.h>
|
||||
#include <ktxreader/Ktx1Reader.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
using namespace ktxreader;
|
||||
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
|
||||
@@ -35,9 +36,9 @@ static jlong nCreateKTXTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
return (jlong) ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
return (jlong) Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
}
|
||||
@@ -46,9 +47,9 @@ static jlong nCreateIndirectLight(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
|
||||
@@ -68,9 +69,9 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
KtxBundle* bundle = (KtxBundle*) userdata;
|
||||
Ktx1Bundle* bundle = new Ktx1Bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Texture* cubemap = Ktx1Reader::createTexture(engine, *bundle, srgb, [](void* userdata) {
|
||||
Ktx1Bundle* bundle = (Ktx1Bundle*) userdata;
|
||||
delete bundle;
|
||||
}, bundle);
|
||||
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
|
||||
@@ -79,7 +80,7 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
|
||||
jfloatArray outSphericalHarmonics_) {
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
Ktx1Bundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
|
||||
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
|
||||
const auto success = bundle.getSphericalHarmonics(
|
||||
@@ -98,8 +99,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
|
||||
int rc;
|
||||
|
||||
// KTXLoader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
|
||||
// KTX1Loader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTX1Loader");
|
||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod ktxMethods[] = {
|
||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ import com.google.android.filament.Renderer;
|
||||
*
|
||||
* When executing a test, clients should call tick() after each frame is rendered, which provides an
|
||||
* opportunity to push settings to Filament, increment the current test index (if enough time has
|
||||
* elapsed), and request an asychronous screenshot.
|
||||
* elapsed), and request an asynchronous screenshot.
|
||||
*
|
||||
* The time to sleep between tests is configurable and can be set to zero. Automation also waits a
|
||||
* specified minimum number of frames between tests.
|
||||
|
||||
+2
-2
@@ -24,12 +24,12 @@ import com.google.android.filament.Texture
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
|
||||
* Utilities for consuming KTX1 files and producing Filament textures, IBLs, and sky boxes.
|
||||
*
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KTXLoader {
|
||||
object KTX1Loader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
+183
-58
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.*
|
||||
@@ -22,6 +24,10 @@ enum class MatrixColumn {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
enum class RotationsOrder {
|
||||
XYZ, XZY, YXZ, YZX, ZXY, ZYX
|
||||
}
|
||||
|
||||
data class Mat2(
|
||||
var x: Float2 = Float2(x = 1.0f),
|
||||
var y: Float2 = Float2(y = 1.0f)) {
|
||||
@@ -39,14 +45,14 @@ data class Mat2(
|
||||
fun identity() = Mat2()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
else -> throw IllegalArgumentException("column must be in 0..1")
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
else -> throw IllegalArgumentException("column must be X or Y")
|
||||
@@ -64,16 +70,8 @@ data class Mat2(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat2(-x, -y)
|
||||
operator fun inc(): Mat2 {
|
||||
x++
|
||||
y++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat2 {
|
||||
x--
|
||||
y--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat2(x++, y++)
|
||||
operator fun dec() = Mat2(x--, y--)
|
||||
|
||||
operator fun plus(v: Float) = Mat2(x + v, y + v)
|
||||
operator fun minus(v: Float) = Mat2(x - v, y - v)
|
||||
@@ -130,7 +128,7 @@ data class Mat3(
|
||||
fun identity() = Mat3()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
@@ -138,7 +136,7 @@ data class Mat3(
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
@@ -157,18 +155,8 @@ data class Mat3(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat3(-x, -y, -z)
|
||||
operator fun inc(): Mat3 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat3 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat3(x++, y++, z++)
|
||||
operator fun dec() = Mat3(x--, y--, z--)
|
||||
|
||||
operator fun plus(v: Float) = Mat3(x + v, y + v, z + v)
|
||||
operator fun minus(v: Float) = Mat3(x - v, y - v, z - v)
|
||||
@@ -279,7 +267,7 @@ data class Mat4(
|
||||
inline val upperLeft: Mat3
|
||||
get() = Mat3(x.xyz, y.xyz, z.xyz)
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
@@ -288,7 +276,7 @@ data class Mat4(
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
@@ -307,20 +295,8 @@ data class Mat4(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat4(-x, -y, -z, -w)
|
||||
operator fun inc(): Mat4 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
w++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat4 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
w--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat4(x++, y++, z++, w++)
|
||||
operator fun dec() = Mat4(x--, y--, z--, w--)
|
||||
|
||||
operator fun plus(v: Float) = Mat4(x + v, y + v, z + v, w + v)
|
||||
operator fun minus(v: Float) = Mat4(x - v, y - v, z - v, w - v)
|
||||
@@ -361,6 +337,8 @@ data class Mat4(
|
||||
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
|
||||
)
|
||||
|
||||
fun toQuaternion() = quaternion(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x, w.x,
|
||||
x.y, y.y, z.y, w.y,
|
||||
@@ -408,7 +386,7 @@ fun inverse(m: Mat3): Mat3 {
|
||||
val det = a * A + b * B + c * C
|
||||
|
||||
return Mat3.of(
|
||||
A / det, B / det, C / det,
|
||||
A / det, B / det, C / det,
|
||||
(c * h - b * i) / det, (a * i - c * g) / det, (b * g - a * h) / det,
|
||||
(b * f - c * e) / det, (c * d - a * f) / det, (a * e - b * d) / det
|
||||
)
|
||||
@@ -496,18 +474,90 @@ fun translation(t: Float3) = Mat4(w = Float4(t, 1.0f))
|
||||
fun translation(m: Mat4) = translation(m.translation)
|
||||
|
||||
fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.forward))
|
||||
fun rotation(d: Float3): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
val c = transform(r) { x -> cos(x) }
|
||||
val s = transform(r) { x -> sin(x) }
|
||||
|
||||
return Mat4.of(
|
||||
c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f,
|
||||
c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f,
|
||||
-s.y , s.x * c.y , c.x * c.y , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
)
|
||||
/**
|
||||
* Construct a rotation matrix from Euler angles using YPR around a specified order
|
||||
*
|
||||
* Uses intrinsic Tait-Bryan angles. This means that rotations are performed with respect to the
|
||||
* local coordinate system.
|
||||
* That is, for order 'XYZ', the rotation is first around the X axis (which is the same as the
|
||||
* world-X axis), then around local-Y (which may now be different from the world Y-axis),
|
||||
* then local-Z (which may be different from the world Z-axis)
|
||||
*
|
||||
* @param d Per axis Euler angles in degrees
|
||||
* Yaw, pitch, roll (YPR) are taken accordingly to the rotations order input.
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*
|
||||
* @return The rotation matrix
|
||||
*/
|
||||
fun rotation(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
return when(order) {
|
||||
RotationsOrder.XZY -> rotation(r.x, r.z, r.y)
|
||||
RotationsOrder.XYZ -> rotation(r.x, r.y, r.z)
|
||||
RotationsOrder.YXZ -> rotation(r.y, r.x, r.z)
|
||||
RotationsOrder.YZX -> rotation(r.y, r.z, r.x)
|
||||
RotationsOrder.ZYX -> rotation(r.z, r.y, r.x)
|
||||
RotationsOrder.ZXY -> rotation(r.z, r.x, r.y)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a rotation matrix from Euler yaw, pitch, roll around a specified order.
|
||||
*
|
||||
* @param roll about 1st rotation axis in radians. Z in case of ZYX order
|
||||
* @param pitch about 2nd rotation axis in radians. Y in case of ZYX order
|
||||
* @param yaw about 3rd rotation axis in radians. X in case of ZYX order
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*
|
||||
* @return The rotation matrix
|
||||
*/
|
||||
fun rotation(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
|
||||
val c1 = cos(yaw)
|
||||
val s1 = sin(yaw)
|
||||
val c2 = cos(pitch)
|
||||
val s2 = sin(pitch)
|
||||
val c3 = cos(roll)
|
||||
val s3 = sin(roll)
|
||||
|
||||
return when (order) {
|
||||
RotationsOrder.XZY -> Mat4.of(
|
||||
c2 * c3, -s2, c2 * s3, 0.0f,
|
||||
s1 * s3 + c1 * c3 * s2, c1 * c2, c1 * s2 * s3 - c3 * s1, 0.0f,
|
||||
c3 * s1 * s2 - c1 * s3, c2 * s1, c1 * c3 + s1 * s2 * s3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.XYZ -> Mat4.of(
|
||||
c2 * c3, -c2 * s3, s2, 0.0f,
|
||||
c1 * s3 + c3 * s1 * s2, c1 * c3 - s1 * s2 * s3, -c2 * s1, 0.0f,
|
||||
s1 * s3 - c1 * c3 * s2, c3 * s1 + c1 * s2 * s3, c1 * c2, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.YXZ -> Mat4.of(
|
||||
c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3, c2 * s1, 0.0f,
|
||||
c2 * s3, c2 * c3, -s2, 0.0f,
|
||||
c1 * s2 * s3 - c3 * s1, c1 * c3 * s2 + s1 * s3, c1 * c2, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.YZX -> Mat4.of(
|
||||
c1 * c2, s1 * s3 - c1 * c3 * s2, c3 * s1 + c1 * s2 * s3, 0.0f,
|
||||
s2, c2 * c3, -c2 * s3, 0.0f,
|
||||
-c2 * s1, c1 * s3 + c3 * s1 * s2, c1 * c3 - s1 * s2 * s3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.ZYX -> Mat4.of(
|
||||
c1 * c2, c1 * s2 * s3 - c3 * s1, s1 * s3 + c1 * c3 * s2, 0.0f,
|
||||
c2 * s1, c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3, 0.0f,
|
||||
-s2, c2 * s3, c2 * c3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.ZXY -> Mat4.of(
|
||||
c1 * c3 - s1 * s2 * s3, -c2 * s1, c1 * s3 + c3 * s1 * s2, 0.0f,
|
||||
c3 * s1 + c1 * s2 * s3, c1 * c2, s1 * s3 - c1 * c3 * s2, 0.0f,
|
||||
-c2 * s3, s2, c2 * c3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
}
|
||||
}
|
||||
|
||||
fun rotation(axis: Float3, angle: Float): Mat4 {
|
||||
val x = axis.x
|
||||
val y = axis.y
|
||||
@@ -519,10 +569,85 @@ fun rotation(axis: Float3, angle: Float): Mat4 {
|
||||
val d = 1.0f - c
|
||||
|
||||
return Mat4.of(
|
||||
x * x * d + c , x * y * d - z * s, x * z * d + y * s, 0.0f,
|
||||
y * x * d + z * s, y * y * d + c , y * z * d - x * s, 0.0f,
|
||||
z * x * d - y * s, z * y * d + x * s, z * z * d + c , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
x * x * d + c, x * y * d - z * s, x * z * d + y * s, 0.0f,
|
||||
y * x * d + z * s, y * y * d + c, y * z * d - x * s, 0.0f,
|
||||
z * x * d - y * s, z * y * d + x * s, z * z * d + c, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion Rotation Matrix following the Hamilton convention
|
||||
*
|
||||
* Assume the destination and local coordinate spaces are initially aligned, and the local
|
||||
* coordinate space is then rotated counter-clockwise about a unit-length axis, k, by an angle,
|
||||
* theta.
|
||||
*/
|
||||
fun rotation(quaternion: Quaternion): Mat4 {
|
||||
val n = normalize(quaternion)
|
||||
return Mat4(
|
||||
Float4(
|
||||
1.0f - 2.0f * (n.y * n.y + n.z * n.z),
|
||||
2.0f * (n.x * n.y + n.z * n.w),
|
||||
2.0f * (n.x * n.z - n.y * n.w),
|
||||
),
|
||||
Float4(
|
||||
2.0f * (n.x * n.y - n.z * n.w),
|
||||
1.0f - 2.0f * (n.x * n.x + n.z * n.z),
|
||||
2.0f * (n.y * n.z + n.x * n.w),
|
||||
),
|
||||
Float4(
|
||||
2.0f * (n.x * n.z + n.y * n.w),
|
||||
2.0f * (n.y * n.z - n.x * n.w),
|
||||
1.0f - 2.0f * (n.x * n.x + n.y * n.y),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Quaternion rotation from a Matrix
|
||||
*/
|
||||
fun quaternion(m: Mat4): Quaternion {
|
||||
val trace = m.x.x + m.y.y + m.z.z
|
||||
return normalize(
|
||||
when {
|
||||
trace > 0.0f -> {
|
||||
val s = 2.0f * sqrt(trace + 1.0f)
|
||||
Quaternion(
|
||||
(m.y.z - m.z.y) / s,
|
||||
(m.z.x - m.x.z) / s,
|
||||
(m.x.y - m.y.x) / s,
|
||||
0.25f * s
|
||||
)
|
||||
}
|
||||
m.x.x > m.y.y && m.x.x > m.z.z -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.x.x - m.y.y - m.z.z)
|
||||
Quaternion(
|
||||
0.25f * s,
|
||||
(m.y.x + m.x.y) / s,
|
||||
(m.z.x + m.x.z) / s,
|
||||
(m.y.z - m.z.y) / s
|
||||
)
|
||||
}
|
||||
m.y.y > m.z.z -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.y.y - m.x.x - m.z.z)
|
||||
Quaternion(
|
||||
(m.y.x + m.x.y) / s,
|
||||
0.25f * s,
|
||||
(m.z.y + m.y.z) / s,
|
||||
(m.z.x - m.x.z) / s
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.z.z - m.x.x - m.y.y)
|
||||
Quaternion(
|
||||
(m.z.x + m.x.z) / s,
|
||||
(m.z.y + m.y.z) / s,
|
||||
0.25f * s,
|
||||
(m.x.y - m.y.x) / s
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -536,7 +661,7 @@ fun lookTowards(eye: Float3, forward: Float3, up: Float3 = Float3(z = 1.0f)): Ma
|
||||
val f = normalize(forward)
|
||||
val r = normalize(f x up)
|
||||
val u = normalize(r x f)
|
||||
return Mat4(Float4(r), Float4(u), Float4(f), Float4(eye, 1.0f))
|
||||
return Mat4(Float4(r), Float4(u), Float4(-f), Float4(eye, 1.0f))
|
||||
}
|
||||
|
||||
fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
|
||||
|
||||
+28
-11
@@ -58,7 +58,10 @@ private const val kSensitivity = 100f
|
||||
*
|
||||
* See `sample-gltf-viewer` for a usage example.
|
||||
*/
|
||||
class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
class ModelViewer(
|
||||
val engine: Engine,
|
||||
private val uiHelper: UiHelper
|
||||
) : android.view.View.OnTouchListener {
|
||||
var asset: FilamentAsset? = null
|
||||
private set
|
||||
|
||||
@@ -71,6 +74,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
var normalizeSkinningWeights = true
|
||||
var recomputeBoundingBoxes = false
|
||||
var ignoreBindTransform = false
|
||||
|
||||
var cameraFocalLength = 28f
|
||||
set(value) {
|
||||
@@ -84,7 +88,6 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
val renderer: Renderer
|
||||
@Entity val light: Int
|
||||
|
||||
private val uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
|
||||
private lateinit var displayHelper: DisplayHelper
|
||||
private lateinit var cameraManipulator: Manipulator
|
||||
private lateinit var gestureDetector: GestureDetector
|
||||
@@ -95,6 +98,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
private var swapChain: SwapChain? = null
|
||||
private var assetLoader: AssetLoader
|
||||
private var materialProvider: MaterialProvider
|
||||
private var resourceLoader: ResourceLoader
|
||||
private val readyRenderables = IntArray(128) // add up to 128 entities at a time
|
||||
|
||||
@@ -110,8 +114,9 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
|
||||
assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
|
||||
materialProvider = UbershaderLoader(engine)
|
||||
assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes, ignoreBindTransform)
|
||||
|
||||
// Always add a direct light source since it is required for shadowing.
|
||||
// We highly recommend adding an indirect light as well.
|
||||
@@ -129,7 +134,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
scene.addEntity(light)
|
||||
}
|
||||
|
||||
constructor(surfaceView: SurfaceView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
|
||||
constructor(
|
||||
surfaceView: SurfaceView,
|
||||
engine: Engine = Engine.create(),
|
||||
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
|
||||
manipulator: Manipulator? = null
|
||||
) : this(engine, uiHelper) {
|
||||
cameraManipulator = manipulator ?: Manipulator.Builder()
|
||||
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
|
||||
.viewport(surfaceView.width, surfaceView.height)
|
||||
@@ -144,7 +154,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(textureView: TextureView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
|
||||
constructor(
|
||||
textureView: TextureView,
|
||||
engine: Engine = Engine.create(),
|
||||
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
|
||||
manipulator: Manipulator? = null
|
||||
) : this(engine, uiHelper) {
|
||||
cameraManipulator = manipulator ?: Manipulator.Builder()
|
||||
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
|
||||
.viewport(textureView.width, textureView.height)
|
||||
@@ -215,8 +230,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
fun transformToUnitCube(centerPoint: Float3 = kDefaultObjectPosition) {
|
||||
asset?.let { asset ->
|
||||
val tm = engine.transformManager
|
||||
var center = asset.boundingBox.center.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
val halfExtent = asset.boundingBox.halfExtent.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
var center = asset.boundingBox.center.let { v -> Float3(v[0], v[1], v[2]) }
|
||||
val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
|
||||
val maxExtent = 2.0f * max(halfExtent)
|
||||
val scaleFactor = 2.0f / maxExtent
|
||||
center -= centerPoint / scaleFactor
|
||||
@@ -284,9 +299,9 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
private fun populateScene(asset: FilamentAsset) {
|
||||
val rcm = engine.renderableManager
|
||||
var count = 0
|
||||
val popRenderables = {count = asset.popRenderables(readyRenderables); count != 0}
|
||||
val popRenderables = { count = asset.popRenderables(readyRenderables); count != 0 }
|
||||
while (popRenderables()) {
|
||||
for (i in 0..count-1) {
|
||||
for (i in 0..count - 1) {
|
||||
val ri = rcm.getInstance(readyRenderables[i])
|
||||
rcm.setScreenSpaceContactShadows(ri, true)
|
||||
}
|
||||
@@ -303,6 +318,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
destroyModel()
|
||||
assetLoader.destroy()
|
||||
materialProvider.destroyMaterials()
|
||||
materialProvider.destroy()
|
||||
resourceLoader.destroy()
|
||||
|
||||
engine.destroyEntity(light)
|
||||
@@ -383,4 +400,4 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
companion object {
|
||||
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Romain Guy
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.*
|
||||
|
||||
enum class QuaternionComponent {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Quaternion and set each value.
|
||||
* The Quaternion will be normalized during construction
|
||||
* Default: Identity
|
||||
*/
|
||||
data class Quaternion(
|
||||
var x: Float = 0.0f,
|
||||
var y: Float = 0.0f,
|
||||
var z: Float = 0.0f,
|
||||
var w: Float = 0.0f) {
|
||||
|
||||
constructor(v: Float3, w: Float = 0.0f) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Float4) : this(v.x, v.y, v.z, v.w)
|
||||
constructor(q: Quaternion) : this(q.x, q.y, q.z, q.w)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Construct a Quaternion from an axis and angle in degrees
|
||||
*
|
||||
* @param axis Rotation direction
|
||||
* @param angle Angle size in degrees
|
||||
*/
|
||||
fun fromAxisAngle(axis: Float3, angle: Float): Quaternion {
|
||||
val r = radians(angle)
|
||||
return Quaternion(sin(r * 0.5f) * normalize(axis), cos(r * 0.5f))
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param d Per axis Euler angles in degrees
|
||||
*/
|
||||
fun fromEuler(d: Float3): Quaternion {
|
||||
val r = transform(d, ::radians)
|
||||
return fromEulerZYX(r.z, r.y, r.x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param roll about X axis in radians
|
||||
* @param pitch about Y axis in radians
|
||||
* @param yaw about Z axis in radians
|
||||
*/
|
||||
fun fromEulerZYX(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f): Quaternion {
|
||||
val cy = cos(yaw * 0.5f)
|
||||
val sy = sin(yaw * 0.5f)
|
||||
val cp = cos(pitch * 0.5f)
|
||||
val sp = sin(pitch * 0.5f)
|
||||
val cr = cos(roll * 0.5f)
|
||||
val sr = sin(roll * 0.5f)
|
||||
|
||||
return Quaternion(
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
cr * cp * cy + sr * sp * sy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inline var xyz: Float3
|
||||
get() = Float3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var imaginary: Float3
|
||||
get() = xyz
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var real: Float
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var xyzw: Float4
|
||||
get() = Float4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
|
||||
operator fun get(index: QuaternionComponent) = when (index) {
|
||||
QuaternionComponent.X -> x
|
||||
QuaternionComponent.Y -> y
|
||||
QuaternionComponent.Z -> z
|
||||
QuaternionComponent.W -> w
|
||||
}
|
||||
|
||||
operator fun get(
|
||||
index1: QuaternionComponent,
|
||||
index2: QuaternionComponent,
|
||||
index3: QuaternionComponent): Float3 {
|
||||
return Float3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(
|
||||
index1: QuaternionComponent,
|
||||
index2: QuaternionComponent,
|
||||
index3: QuaternionComponent,
|
||||
index4: QuaternionComponent): Quaternion {
|
||||
return Quaternion(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
3 -> w
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Float3 {
|
||||
return Float3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int, index3: Int, index4: Int): Quaternion {
|
||||
return Quaternion(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Float) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
2 -> z = v
|
||||
3 -> w = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, index4: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun set(index: QuaternionComponent, v: Float) = when (index) {
|
||||
QuaternionComponent.X -> x = v
|
||||
QuaternionComponent.Y -> y = v
|
||||
QuaternionComponent.Z -> z = v
|
||||
QuaternionComponent.W -> w = v
|
||||
}
|
||||
|
||||
operator fun set(index1: QuaternionComponent, index2: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: QuaternionComponent, index2: QuaternionComponent, index3: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: QuaternionComponent, index2: QuaternionComponent,
|
||||
index3: QuaternionComponent, index4: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Quaternion(-x, -y, -z, -w)
|
||||
|
||||
inline operator fun plus(v: Float) = Quaternion(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Float) = Quaternion(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Float) = Quaternion(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Float) = Quaternion(x / v, y / v, z / v, w / v)
|
||||
|
||||
inline operator fun times(v: Float3) = (this * Quaternion(v, 0.0f) * inverse(this)).xyz
|
||||
|
||||
inline operator fun plus(q: Quaternion) = Quaternion(x + q.x, y + q.y, z + q.z, w + q.w)
|
||||
inline operator fun minus(q: Quaternion) = Quaternion(x - q.x, y - q.y, z - q.z, w - q.w)
|
||||
inline operator fun times(q: Quaternion) = Quaternion(
|
||||
w * q.x + x * q.w + y * q.z - z * q.y,
|
||||
w * q.y - x * q.z + y * q.w + z * q.x,
|
||||
w * q.z + x * q.y - y * q.x + z * q.w,
|
||||
w * q.w - x * q.x - y * q.y - z * q.z)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Quaternion {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toEulerAngles() = eulerAngles(this)
|
||||
|
||||
fun toMatrix() = rotation(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z, w)
|
||||
}
|
||||
|
||||
inline operator fun Float.plus(q: Quaternion) = Quaternion(this + q.x, this + q.y, this + q.z, this + q.w)
|
||||
inline operator fun Float.minus(q: Quaternion) = Quaternion(this - q.x, this - q.y, this - q.z, this - q.w)
|
||||
inline operator fun Float.times(q: Quaternion) = Quaternion(this * q.x, this * q.y, this * q.z, this * q.w)
|
||||
inline operator fun Float.div(q: Quaternion) = Quaternion(this / q.x, this / q.y, this / q.z, this / q.w)
|
||||
|
||||
inline fun abs(q: Quaternion) = Quaternion(abs(q.x), abs(q.y), abs(q.z), abs(q.w))
|
||||
inline fun length(q: Quaternion) = sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w)
|
||||
inline fun length2(q: Quaternion) = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w
|
||||
inline fun dot(a: Quaternion, b: Quaternion) = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
|
||||
|
||||
/**
|
||||
* Rescale the Quaternion to the unit length
|
||||
*/
|
||||
fun normalize(q: Quaternion): Quaternion {
|
||||
val l = 1.0f / length(q)
|
||||
return Quaternion(q.x * l, q.y * l, q.z * l, q.w * l)
|
||||
}
|
||||
|
||||
fun conjugate(q: Quaternion): Quaternion = Quaternion(-q.x, -q.y, -q.z, q.w)
|
||||
|
||||
fun inverse(q: Quaternion): Quaternion {
|
||||
val d = 1.0f / dot(q, q)
|
||||
return Quaternion(-q.x * d, -q.y * d, -q.z * d, q.w * d)
|
||||
}
|
||||
|
||||
fun cross(a: Quaternion, b: Quaternion): Quaternion {
|
||||
val m = a * b
|
||||
return Quaternion(m.x, m.y, m.z, 0.0f)
|
||||
}
|
||||
|
||||
/**
|
||||
* Spherical linear interpolation between two given orientations
|
||||
*
|
||||
* If t is 0 this returns a.
|
||||
* As t approaches 1 slerp may approach either b or -b (whichever is closest to a)
|
||||
* If t is above 1 or below 0 the result will be extrapolated.
|
||||
* @param a The beginning value
|
||||
* @param b The ending value
|
||||
* @param t The ratio between the two floats
|
||||
* @param valueEps Prevent blowing up when slerping between two quaternions that are very near each
|
||||
* other. Linear interpolation (lerp) is returned in this case.
|
||||
*
|
||||
* @return Interpolated value between the two floats
|
||||
*/
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, valueEps: Float = 0.0000000001f): Quaternion {
|
||||
// could also be computed as: pow(q * inverse(p), t) * p;
|
||||
val d = dot(a, b)
|
||||
val absd = abs(d)
|
||||
// Prevent blowing up when slerping between two quaternions that are very near each other.
|
||||
if ((1.0f - absd) < valueEps) {
|
||||
return normalize(lerp(if (d < 0.0f) -a else a, b, t))
|
||||
}
|
||||
val npq = sqrt(dot(a, a) * dot(b, b)) // ||p|| * ||q||
|
||||
val acos = acos(clamp(absd / npq, -1.0f, 1.0f))
|
||||
val acos0 = acos * (1.0f - t)
|
||||
val acos1 = acos * t
|
||||
val sina = sin(acos)
|
||||
if (sina < valueEps) {
|
||||
return normalize(lerp(a, b, t))
|
||||
}
|
||||
val isina = 1.0f / sina
|
||||
val s0 = sin(acos0) * isina
|
||||
val s1 = sin(acos1) * isina
|
||||
// ensure we're taking the "short" side
|
||||
return normalize(s0 * a + (if (d < 0.0f) -s1 else (s1)) * b)
|
||||
}
|
||||
|
||||
fun lerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
return ((1 - t) * a) + (t * b)
|
||||
}
|
||||
|
||||
fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
return normalize(lerp(a, b, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Quaternion to Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order
|
||||
*/
|
||||
fun eulerAngles(q: Quaternion): Float3 {
|
||||
val nq = normalize(q)
|
||||
return Float3(
|
||||
// roll (x-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.y * nq.z + nq.w * nq.x),
|
||||
nq.w * nq.w - nq.x * nq.x - nq.y * nq.y + nq.z * nq.z)),
|
||||
// pitch (y-axis rotation)
|
||||
degrees(asin(-2.0f * (nq.x * nq.z - nq.w * nq.y))),
|
||||
// yaw (z-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.x * nq.y + nq.w * nq.z),
|
||||
nq.w * nq.w + nq.x * nq.x - nq.y * nq.y - nq.z * nq.z)))
|
||||
}
|
||||
+3
-1
@@ -18,6 +18,8 @@
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.pow
|
||||
|
||||
const val FPI = 3.1415926536f
|
||||
const val HALF_PI = FPI * 0.5f
|
||||
const val TWO_PI = FPI * 2.0f
|
||||
@@ -40,4 +42,4 @@ inline fun fract(v: Float) = v % 1
|
||||
|
||||
inline fun sqr(v: Float) = v * v
|
||||
|
||||
inline fun pow(x: Float, y: Float) = StrictMath.pow(x.toDouble(), y.toDouble()).toFloat()
|
||||
inline fun pow(x: Float, y: Float) = (x.toDouble().pow(y.toDouble())).toFloat()
|
||||
|
||||
+45
-65
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE")
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
@@ -117,17 +117,8 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float2(-x, -y)
|
||||
operator fun inc(): Float2 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float2 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float2(x++, y++)
|
||||
operator fun dec() = Float2(x--, y--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float2(x + v, y + v)
|
||||
inline operator fun minus(v: Float) = Float2(x - v, y - v)
|
||||
@@ -144,6 +135,8 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
y = block(y)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y)
|
||||
}
|
||||
|
||||
data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f) {
|
||||
@@ -284,29 +277,15 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
v: Float) {
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float3(-x, -y, -z)
|
||||
operator fun inc(): Float3 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
z += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float3 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
z -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float3(x++, y++, z++)
|
||||
operator fun dec() = Float3(x--, y--, z--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float3(x + v, y + v, z + v)
|
||||
inline operator fun minus(v: Float) = Float3(x - v, y - v, z - v)
|
||||
@@ -329,6 +308,8 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
z = block(z)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z)
|
||||
}
|
||||
|
||||
data class Float4(
|
||||
@@ -529,14 +510,15 @@ data class Float4(
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, index3: VectorComponent,
|
||||
v: Float) {
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent,
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
@@ -545,21 +527,8 @@ data class Float4(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float4(-x, -y, -z, -w)
|
||||
operator fun inc(): Float4 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
z += 1.0f
|
||||
w += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float4 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
z -= 1.0f
|
||||
w -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float4(x++, y++, z++, w++)
|
||||
operator fun dec() = Float4(x--, y--, z--, w--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float4(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Float) = Float4(x - v, y - v, z - v, w - v)
|
||||
@@ -588,6 +557,8 @@ data class Float4(
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z, w)
|
||||
}
|
||||
|
||||
inline operator fun Float.plus(v: Float2) = Float2(this + v.x, this + v.y)
|
||||
@@ -615,25 +586,29 @@ fun refract(i: Float2, n: Float2, eta: Float): Float2 {
|
||||
inline fun clamp(v: Float2, min: Float, max: Float): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max))
|
||||
clamp(v.y, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float2, min: Float2, max: Float2): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y))
|
||||
clamp(v.y, min.y, max.y)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float2, b: Float2, x: Float): Float2 {
|
||||
return Float2(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x))
|
||||
mix(a.y, b.y, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float2, b: Float2, x: Float2): Float2 {
|
||||
return Float2(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y))
|
||||
mix(a.y, b.y, x.y)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Float2) = min(v.x, v.y)
|
||||
@@ -704,28 +679,32 @@ inline fun clamp(v: Float3, min: Float, max: Float): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max))
|
||||
clamp(v.z, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float3, min: Float3, max: Float3): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z))
|
||||
clamp(v.z, min.z, max.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float3, b: Float3, x: Float): Float3 {
|
||||
return Float3(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x))
|
||||
mix(a.z, b.z, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float3, b: Float3, x: Float3): Float3 {
|
||||
return Float3(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z))
|
||||
mix(a.z, b.z, x.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Float3) = min(v.x, min(v.y, v.z))
|
||||
@@ -784,7 +763,8 @@ inline fun clamp(v: Float4, min: Float, max: Float): Float4 {
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max),
|
||||
clamp(v.w, min, max))
|
||||
clamp(v.w, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float4, min: Float4, max: Float4): Float4 {
|
||||
@@ -792,7 +772,8 @@ inline fun clamp(v: Float4, min: Float4, max: Float4): Float4 {
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z),
|
||||
clamp(v.w, min.z, max.w))
|
||||
clamp(v.w, min.z, max.w)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float4, b: Float4, x: Float): Float4 {
|
||||
@@ -800,7 +781,8 @@ inline fun mix(a: Float4, b: Float4, x: Float): Float4 {
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x),
|
||||
mix(a.w, b.w, x))
|
||||
mix(a.w, b.w, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float4, b: Float4, x: Float4): Float4 {
|
||||
@@ -1075,10 +1057,7 @@ data class Bool3(var x: Boolean = false, var y: Boolean = false, var z: Boolean
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
v: Boolean) {
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
@@ -1282,14 +1261,15 @@ data class Bool4(
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, index3: VectorComponent,
|
||||
v: Boolean) {
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent,
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
|
||||
@@ -11,6 +11,18 @@ add_library(dracodec STATIC IMPORTED)
|
||||
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
|
||||
add_library(stb STATIC IMPORTED)
|
||||
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
|
||||
|
||||
add_library(basis_transcoder STATIC IMPORTED)
|
||||
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
@@ -32,6 +44,8 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
|
||||
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/math.h
|
||||
|
||||
${GLTFIO_DIR}/src/Animator.cpp
|
||||
${GLTFIO_DIR}/src/AssetLoader.cpp
|
||||
@@ -44,18 +58,16 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/src/FFilamentInstance.h
|
||||
${GLTFIO_DIR}/src/FilamentInstance.cpp
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/Ktx2Provider.cpp
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/MorphHelper.h
|
||||
${GLTFIO_DIR}/src/MorphHelper.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/StbProvider.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
${GLTFIO_DIR}/src/UbershaderLoader.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.h
|
||||
${GLTFIO_DIR}/src/math.h
|
||||
${GLTFIO_DIR}/src/upcast.h
|
||||
${GLTFIO_DIR}/src/Image.cpp
|
||||
|
||||
src/main/cpp/Animator.cpp
|
||||
src/main/cpp/AssetLoader.cpp
|
||||
@@ -83,6 +95,7 @@ set(GLTFIO_INCLUDE_DIRS
|
||||
../../third_party/hat-trie
|
||||
../../third_party/stb
|
||||
../../libs/utils/include
|
||||
../../libs/ktxreader/include
|
||||
)
|
||||
|
||||
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
|
||||
@@ -92,9 +105,9 @@ set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_
|
||||
|
||||
if(GLTFIO_LITE)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_LITE=1)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources_lite)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources_lite)
|
||||
else()
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log stb ktxreader basis_transcoder gltfio_resources)
|
||||
|
||||
# Enable Draco in the non-lite variant of gltfio.
|
||||
target_link_libraries(gltfio-jni dracodec)
|
||||
|
||||
@@ -36,6 +36,12 @@ Java_com_google_android_filament_gltfio_Animator_nUpdateBoneMatrices(JNIEnv*, jc
|
||||
animator->updateBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nResetBoneMatrices(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
animator->resetBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nGetAnimationCount(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
jclass providerClass = env->GetObjectClass(provider);
|
||||
|
||||
mCreateMaterialInstance = env->GetMethodID(providerClass, "createMaterialInstance",
|
||||
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
|
||||
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;Ljava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
|
||||
assert_invariant(mCreateMaterialInstance);
|
||||
|
||||
mGetMaterials = env->GetMethodID(providerClass, "getMaterials",
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
delete mPreviousMaterials;
|
||||
}
|
||||
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label) override {
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label, const char* extras) override {
|
||||
// Create a Java object for the material key and copy the native fields into it.
|
||||
jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor);
|
||||
|
||||
@@ -99,12 +99,15 @@ public:
|
||||
// Convert the optional label into a Java string.
|
||||
jstring stringLabel = label ? mEnv->NewStringUTF(label) : nullptr;
|
||||
|
||||
// Convert the optional extras into a Java string.
|
||||
jstring stringExtras = extras ? mEnv->NewStringUTF(extras) : nullptr;
|
||||
|
||||
// Allocate space for the output argument.
|
||||
jintArray uvMapArray = mEnv->NewIntArray(8);
|
||||
|
||||
// Call the Java-based material provider.
|
||||
jobject materialInstance = mEnv->CallObjectMethod(mJavaProvider, mCreateMaterialInstance,
|
||||
javaKey, uvMapArray, stringLabel);
|
||||
javaKey, uvMapArray, stringLabel, stringExtras);
|
||||
|
||||
// Copy the UvMap results from the JVM array into the native array.
|
||||
if (uvmap) {
|
||||
@@ -125,6 +128,10 @@ public:
|
||||
mEnv->DeleteLocalRef(stringLabel);
|
||||
}
|
||||
|
||||
if (stringExtras) {
|
||||
mEnv->DeleteLocalRef(stringExtras);
|
||||
}
|
||||
|
||||
if (materialInstance == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -194,7 +201,6 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*, jclass,
|
||||
jlong nativeLoader) {
|
||||
AssetLoader* loader = (AssetLoader*) nativeLoader;
|
||||
delete loader->getMaterialProvider();
|
||||
NameComponentManager* names = loader->getNames();
|
||||
AssetLoader::destroy(&loader);
|
||||
delete names;
|
||||
|
||||
@@ -201,6 +201,44 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jc
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinCount(JNIEnv* , jclass,
|
||||
jlong nativeAsset) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getSkinCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
for (int i = 0; i < available; ++i) {
|
||||
const char* name = asset->getSkinNameAt(i);
|
||||
if (name) {
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointCountAt(JNIEnv* , jclass,
|
||||
jlong nativeAsset, jint skinIndex) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getJointCountAt(skinIndex);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointsAt(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jintArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
|
||||
std::copy_n(asset->getJointsAt(skinIndex),
|
||||
std::min(available, (jsize) asset->getJointCountAt(skinIndex)), entities);
|
||||
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
|
||||
jlong nativeAsset) {
|
||||
@@ -226,6 +264,49 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* e
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetCount(JNIEnv*, jclass,
|
||||
jlong nativeAsset, jint entityId) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity entity = Entity::import(entityId);
|
||||
return (jint) asset->getMorphTargetCountAt(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint entityId, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity entity = Entity::import(entityId);
|
||||
for (int i = 0, n = asset->getMorphTargetCountAt(entity); i < n; ++i) {
|
||||
const char* name = asset->getMorphTargetNameAt(entity, i);
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantCount(JNIEnv*, jclass,
|
||||
jlong nativeAsset) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return (jint) asset->getMaterialVariantCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantNames(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jobjectArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
for (int i = 0; i < asset->getMaterialVariantCount(); ++i) {
|
||||
const char* name = asset->getMaterialVariantName(i);
|
||||
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nApplyMaterialVariant(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint variantIndex) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
asset->applyMaterialVariant(variantIndex);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv* env, jclass,
|
||||
jlong nativeAsset) {
|
||||
|
||||
@@ -54,3 +54,10 @@ Java_com_google_android_filament_gltfio_FilamentInstance_nGetAnimator(JNIEnv* ,
|
||||
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
|
||||
return (jlong) instance->getAnimator();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentInstance_nApplyMaterialVariant(JNIEnv* env, jclass,
|
||||
jlong nativeInstance, jint variantIndex) {
|
||||
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
|
||||
instance->applyMaterialVariant(variantIndex);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
#include <gltfio/TextureProvider.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
@@ -35,10 +36,11 @@ static void destroy(void*, size_t, void *userData) {
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateResourceLoader(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes) {
|
||||
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes,
|
||||
jboolean ignoreBindTransform) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) new ResourceLoader({ engine, {}, (bool) normalizeSkinningWeights,
|
||||
(bool) recomputeBoundingBoxes });
|
||||
(bool) recomputeBoundingBoxes, (bool) ignoreBindTransform});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -113,3 +115,34 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*,
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
loader->asyncCancelLoad();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateStbProvider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createStbProvider(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createKtx2Provider(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nAddTextureProvider(JNIEnv* env, jclass,
|
||||
jlong nativeLoader, jstring url, jlong nativeProvider) {
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
const char* cstring = env->GetStringUTFChars(url, nullptr);
|
||||
loader->addTextureProvider(cstring, provider);
|
||||
env->ReleaseStringUTFChars(url, cstring);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,15 @@ public class Animator {
|
||||
nUpdateBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the identity matrix into all bone nodes, useful for returning to the T pose.
|
||||
*
|
||||
* <p>NOTE: this operation is independent of <code>animation</code>.</p>
|
||||
*/
|
||||
public void resetBoneMatrices() {
|
||||
nResetBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of <code>animation</code> definitions in the glTF asset.
|
||||
*/
|
||||
@@ -109,6 +118,7 @@ public class Animator {
|
||||
|
||||
private static native void nApplyAnimation(long nativeAnimator, int index, float time);
|
||||
private static native void nUpdateBoneMatrices(long nativeAnimator);
|
||||
private static native void nResetBoneMatrices(long nativeAnimator);
|
||||
private static native int nGetAnimationCount(long nativeAnimator);
|
||||
private static native float nGetAnimationDuration(long nativeAnimator, int index);
|
||||
private static native String nGetAnimationName(long nativeAnimator, int index);
|
||||
|
||||
+6
-4
@@ -45,7 +45,8 @@ import java.nio.Buffer;
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
* materialProvider = UbershaderLoader(engine)
|
||||
* assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
*
|
||||
* filamentAsset = assets.open("models/lucy.gltf").use { input ->
|
||||
* val bytes = ByteArray(input.available())
|
||||
@@ -60,7 +61,6 @@ import java.nio.Buffer;
|
||||
* }
|
||||
* resourceLoader.loadResources(filamentAsset)
|
||||
* resourceLoader.destroy()
|
||||
* animator = asset.getAnimator()
|
||||
* filamentAsset.releaseSourceData();
|
||||
*
|
||||
* scene.addEntities(filamentAsset.entities)
|
||||
@@ -104,10 +104,12 @@ public class AssetLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all memory consumed by the native <code>AssetLoader</code> and its material cache.
|
||||
* Frees all memory consumed by the native <code>AssetLoader</code>
|
||||
*
|
||||
* This does not not automatically free the cache of materials, nor
|
||||
* does it free the entities for created assets (see destroyAsset).
|
||||
*/
|
||||
public void destroy() {
|
||||
mMaterialCache.destroyMaterials();
|
||||
nDestroyAssetLoader(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
+84
-6
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -197,11 +198,11 @@ public class FilamentAsset {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or retrieves the <code>Animator</code> interface for this asset.
|
||||
* Retrieves the <code>Animator</code> interface for this asset.
|
||||
*
|
||||
* <p>When calling this for the first time, this must be called after
|
||||
* {@link ResourceLoader#loadResources}. When the asset is destroyed, its
|
||||
* animator becomes invalid.</p>
|
||||
* {@link ResourceLoader#loadResources} or {@link ResourceLoader#asyncBeginLoad}. When the asset
|
||||
* is destroyed, its animator becomes invalid.</p>
|
||||
*/
|
||||
public @NonNull Animator getAnimator() {
|
||||
if (mAnimator != null) {
|
||||
@@ -215,6 +216,47 @@ public class FilamentAsset {
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skin count of this asset.
|
||||
*/
|
||||
public int getSkinCount() {
|
||||
return nGetSkinCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skin name at skin index in this asset.
|
||||
*/
|
||||
public @NonNull String[] getSkinNames() {
|
||||
String[] result = new String[getSkinCount()];
|
||||
nGetSkinNames(getNativeObject(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joint count at skin index in this asset.
|
||||
*/
|
||||
public int getJointCountAt(int skinIndex) {
|
||||
return nGetJointCountAt(getNativeObject(), skinIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets joints at skin index in this asset.
|
||||
*/
|
||||
public @NonNull @Entity int[] getJointsAt(int skinIndex) {
|
||||
int[] result = new int[getJointCountAt(skinIndex)];
|
||||
nGetJointsAt(getNativeObject(), skinIndex, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all morph targets in the given entity.
|
||||
*/
|
||||
public @NonNull String[] getMorphTargetNames(@Entity int entity) {
|
||||
String[] names = new String[nGetMorphTargetCount(mNativeObject, entity)];
|
||||
nGetMorphTargetNames(mNativeObject, entity, names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource URIs for all externally-referenced buffers.
|
||||
*/
|
||||
@@ -224,12 +266,37 @@ public class FilamentAsset {
|
||||
return uris;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of all material variants.
|
||||
*/
|
||||
public @NonNull String[] getMaterialVariantNames() {
|
||||
String[] names = new String[nGetMaterialVariantCount(mNativeObject)];
|
||||
nGetMaterialVariantNames(mNativeObject, names);
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given material variant to all primitives that it affects.
|
||||
*
|
||||
* This is efficient because it merely swaps around persistent MaterialInstances. If you change
|
||||
* a material parameter while a certain variant is active, the updated value will be remembered
|
||||
* after you re-apply that variant.
|
||||
*
|
||||
* If the asset is instanced, this affects all instances in the same way.
|
||||
* To set the variant on an individual instance, use FilamentInstance#applyMaterialVariant.
|
||||
*
|
||||
* Ignored if variantIndex is out of bounds.
|
||||
*/
|
||||
public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
nApplyMaterialVariant(getNativeObject(), variantIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
|
||||
*
|
||||
* This should only be called after ResourceLoader#loadResources().
|
||||
* If using Animator, this should be called after getAnimator().
|
||||
* If this is an instanced asset, this prevents creation of new instances.
|
||||
* This should only be called after ResourceLoader#loadResources() or
|
||||
* ResourceLoader#asyncBeginLoad(). If this is an instanced asset, this prevents creation of new
|
||||
* instances.
|
||||
*/
|
||||
public void releaseSourceData() {
|
||||
nReleaseSourceData(mNativeObject);
|
||||
@@ -260,10 +327,21 @@ public class FilamentAsset {
|
||||
private static native int nGetMaterialInstanceCount(long nativeAsset);
|
||||
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
|
||||
|
||||
private static native int nGetMaterialVariantCount(long nativeAsset);
|
||||
private static native void nGetMaterialVariantNames(long nativeAsset, String[] result);
|
||||
|
||||
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
|
||||
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
|
||||
|
||||
private static native void nGetBoundingBox(long nativeAsset, float[] box);
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
|
||||
private static native int nGetSkinCount(long nativeAsset);
|
||||
private static native void nGetSkinNames(long nativeAsset, String[] result);
|
||||
private static native int nGetJointCountAt(long nativeAsset, int skinIndex);
|
||||
private static native void nGetJointsAt(long nativeAsset, int skinIndex, int[] result);
|
||||
private static native int nGetResourceUriCount(long nativeAsset);
|
||||
private static native void nGetResourceUris(long nativeAsset, String[] result);
|
||||
private static native void nReleaseSourceData(long nativeAsset);
|
||||
|
||||
+12
-4
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.Entity;
|
||||
@@ -74,10 +75,7 @@ public class FilamentInstance {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or retrieves the <code>Animator</code> for this instance.
|
||||
*
|
||||
* <p>When calling this for the first time, this must be called after
|
||||
* {@link ResourceLoader#loadResources}.</p>
|
||||
* Retrieves the <code>Animator</code> for this instance.
|
||||
*/
|
||||
public @NonNull Animator getAnimator() {
|
||||
if (mAnimator != null) {
|
||||
@@ -87,8 +85,18 @@ public class FilamentInstance {
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given material variant to all primitives in this instance.
|
||||
*
|
||||
* Ignored if variantIndex is out of bounds.
|
||||
*/
|
||||
void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
nApplyMaterialVariant(mNativeObject, variantIndex);
|
||||
}
|
||||
|
||||
private static native int nGetRoot(long nativeAsset);
|
||||
private static native int nGetEntityCount(long nativeAsset);
|
||||
private static native void nGetEntities(long nativeAsset, int[] result);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
|
||||
}
|
||||
|
||||
+8
-1
@@ -99,9 +99,10 @@ public interface MaterialProvider {
|
||||
* @param uvmap Output argument that gets populated with a small table that maps from a glTF uv
|
||||
* index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
|
||||
* @param label Optional tag that is not a part of the cache key.
|
||||
* @param extras Optional extras as stringified JSON (not a part of the cache key).
|
||||
*/
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label);
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras);
|
||||
|
||||
/**
|
||||
* Creates and returns an array containing all cached materials.
|
||||
@@ -126,4 +127,10 @@ public interface MaterialProvider {
|
||||
* clients to take ownership of the cache if desired.
|
||||
*/
|
||||
public void destroyMaterials();
|
||||
|
||||
/**
|
||||
* Frees memory consumed by the native <code>MaterialProvider</code>, but does not destroy
|
||||
* cached materials.
|
||||
*/
|
||||
public void destroy();
|
||||
}
|
||||
|
||||
+24
-4
@@ -35,6 +35,8 @@ import java.nio.Buffer;
|
||||
*/
|
||||
public class ResourceLoader {
|
||||
private final long mNativeObject;
|
||||
private final long mNativeStbProvider;
|
||||
private final long mNativeKtx2Provider;
|
||||
|
||||
/**
|
||||
* Constructs a resource loader tied to the given Filament engine.
|
||||
@@ -45,7 +47,12 @@ public class ResourceLoader {
|
||||
*/
|
||||
public ResourceLoader(@NonNull Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false);
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
|
||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,14 +61,20 @@ public class ResourceLoader {
|
||||
* @param engine the engine that gets passed to all builder methods
|
||||
* @param normalizeSkinningWeights scale non-conformant skinning weights so they sum to 1
|
||||
* @param recomputeBoundingBoxes use computed bounding boxes rather than the ones in the asset
|
||||
* @param ignoreBindTransform ignore skinned primitives bind transform when compute bounding boxes
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public ResourceLoader(@NonNull Engine engine, boolean normalizeSkinningWeights,
|
||||
boolean recomputeBoundingBoxes) {
|
||||
boolean recomputeBoundingBoxes, boolean ignoreBindTransform) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
|
||||
recomputeBoundingBoxes);
|
||||
recomputeBoundingBoxes, ignoreBindTransform);
|
||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +82,8 @@ public class ResourceLoader {
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyResourceLoader(mNativeObject);
|
||||
nDestroyTextureProvider(mNativeStbProvider);
|
||||
nDestroyTextureProvider(mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +181,7 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
private static native long nCreateResourceLoader(long nativeEngine,
|
||||
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes);
|
||||
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes, boolean ignoreBindTransform);
|
||||
private static native void nDestroyResourceLoader(long nativeLoader);
|
||||
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
|
||||
int remaining);
|
||||
@@ -177,4 +192,9 @@ public class ResourceLoader {
|
||||
private static native float nAsyncGetLoadProgress(long nativeLoader);
|
||||
private static native void nAsyncUpdateLoad(long nativeLoader);
|
||||
private static native void nAsyncCancelLoad(long nativeLoader);
|
||||
|
||||
private static native long nCreateStbProvider(long nativeEngine);
|
||||
private static native long nCreateKtx2Provider(long nativeEngine);
|
||||
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
|
||||
private static native void nDestroyTextureProvider(long nativeProvider);
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
}
|
||||
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label) {
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras) {
|
||||
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
|
||||
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.16.0
|
||||
VERSION_NAME=1.21.3
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#Wed Nov 17 10:40:18 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+20
-23
@@ -36,6 +36,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.URI
|
||||
import java.nio.Buffer
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
@@ -118,7 +119,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
// FXAA is pretty cheap and helps a lot
|
||||
view.antiAliasing = View.AntiAliasing.FXAA;
|
||||
view.antiAliasing = View.AntiAliasing.FXAA
|
||||
|
||||
// ambient occlusion is the cheapest effect that adds a lot of quality
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
@@ -149,12 +150,12 @@ class MainActivity : Activity() {
|
||||
val scene = modelViewer.scene
|
||||
val ibl = "default_env"
|
||||
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
|
||||
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight = KTX1Loader.createIndirectLight(engine, it)
|
||||
scene.indirectLight!!.intensity = 30_000.0f
|
||||
viewerContent.indirectLight = modelViewer.scene.indirectLight
|
||||
}
|
||||
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
|
||||
scene.skybox = KTXLoader.createSkybox(engine, it)
|
||||
scene.skybox = KTX1Loader.createSkybox(engine, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,13 +218,13 @@ class MainActivity : Activity() {
|
||||
|
||||
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
|
||||
|
||||
specularFilter.destroy();
|
||||
equirectToCubemap.destroy();
|
||||
context.destroy();
|
||||
specularFilter.destroy()
|
||||
equirectToCubemap.destroy()
|
||||
context.destroy()
|
||||
|
||||
// destroy the previous IBl
|
||||
engine.destroyIndirectLight(modelViewer.scene.indirectLight!!);
|
||||
engine.destroySkybox(modelViewer.scene.skybox!!);
|
||||
engine.destroyIndirectLight(modelViewer.scene.indirectLight!!)
|
||||
engine.destroySkybox(modelViewer.scene.skybox!!)
|
||||
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
@@ -243,7 +244,7 @@ class MainActivity : Activity() {
|
||||
val (zipStream, zipFile) = withContext(Dispatchers.IO) {
|
||||
val file = File.createTempFile("incoming", "zip", cacheDir)
|
||||
val raf = RandomAccessFile(file, "rw")
|
||||
raf.getChannel().write(message.buffer);
|
||||
raf.channel.write(message.buffer)
|
||||
message.buffer = null
|
||||
raf.seek(0)
|
||||
Pair(FileInputStream(file), file)
|
||||
@@ -296,21 +297,19 @@ class MainActivity : Activity() {
|
||||
|
||||
val gltfBuffer = pathToBufferMapping[gltfPath]!!
|
||||
|
||||
// The gltf is often not at the root level (e.g. if a folder is zipped) so
|
||||
// we need to extract its path in order to resolve the embedded uri strings.
|
||||
var gltfPrefix = gltfPath!!.substringBeforeLast('/', "")
|
||||
if (gltfPrefix.isNotEmpty()) {
|
||||
gltfPrefix += "/"
|
||||
}
|
||||
// In a zip file, the gltf file might be in the same folder as resources, or in a different
|
||||
// folder. It is crucial to test against both of these cases. In any case, the resource
|
||||
// paths are all specified relative to the location of the gltf file.
|
||||
var prefix = URI(gltfPath!!).resolve(".")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
modelViewer.loadModelGlb(gltfBuffer)
|
||||
} else {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = gltfPrefix + uri
|
||||
val path = prefix.resolve(uri).toString()
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find $path in the zip.")
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix' and base path '${gltfPath!!}'")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
@@ -343,12 +342,10 @@ class MainActivity : Activity() {
|
||||
clearStatusText()
|
||||
titlebarHint.text = message.label
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (message.label.endsWith(".zip")) {
|
||||
loadZip(message)
|
||||
} else if (message.label.endsWith(".hdr")) {
|
||||
loadHdr(message)
|
||||
} else {
|
||||
loadGlb(message)
|
||||
when {
|
||||
message.label.endsWith(".zip") -> loadZip(message)
|
||||
message.label.endsWith(".hdr") -> loadHdr(message)
|
||||
else -> loadGlb(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-32
@@ -79,8 +79,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
// Performs the rendering and schedules new frames
|
||||
private val frameScheduler = FrameCallback()
|
||||
|
||||
private var externalTextureID: Int = 0
|
||||
|
||||
@RequiresApi(30)
|
||||
class Api30Impl {
|
||||
companion object {
|
||||
@@ -103,8 +101,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
setupView()
|
||||
setupScene()
|
||||
|
||||
externalTextureID = createExternalTexture()
|
||||
|
||||
@Suppress("deprecation")
|
||||
val display = if (Build.VERSION.SDK_INT >= 30) {
|
||||
Api30Impl.getDisplay(this)
|
||||
@@ -112,7 +108,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
windowManager.defaultDisplay!!
|
||||
}
|
||||
|
||||
streamHelper = StreamHelper(engine, materialInstance, display, externalTextureID)
|
||||
streamHelper = StreamHelper(engine, materialInstance, display)
|
||||
this.title = streamHelper.getTestName()
|
||||
}
|
||||
|
||||
@@ -445,31 +441,4 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
check(EGL14.eglMakeCurrent(display, surface, surface, context)) { "Error making GL context." }
|
||||
return context
|
||||
}
|
||||
|
||||
private fun createExternalTexture(): Int {
|
||||
val textures = IntArray(1)
|
||||
GLES30.glGenTextures(1, textures, 0)
|
||||
val result = textures[0]
|
||||
|
||||
val textureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES
|
||||
GLES30.glBindTexture(textureTarget, result)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST)
|
||||
|
||||
if (!GLES30.glIsTexture(result)) {
|
||||
throw RuntimeException("OpenGL error: $result is an invalid texture.")
|
||||
}
|
||||
|
||||
val error = GLES30.glGetError()
|
||||
if (error != GLES30.GL_NO_ERROR) {
|
||||
val errorString = GLU.gluErrorString(error)
|
||||
throw RuntimeException("OpenGL error: $errorString!")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
-24
@@ -37,7 +37,6 @@ class StreamHelper(
|
||||
private val filamentEngine: Engine,
|
||||
private val filamentMaterial: MaterialInstance,
|
||||
private val display: Display,
|
||||
private val externalTextureId: Int
|
||||
) {
|
||||
/**
|
||||
* The StreamSource configures the source data for the texture.
|
||||
@@ -51,7 +50,6 @@ class StreamHelper(
|
||||
*/
|
||||
enum class StreamSource {
|
||||
CANVAS_STREAM_NATIVE, // copy-free but does not guarantee synchronization
|
||||
CANVAS_STREAM_TEXID, // synchronized but incurs a copy
|
||||
CANVAS_STREAM_ACQUIRED, // synchronized and copy-free
|
||||
}
|
||||
|
||||
@@ -127,10 +125,6 @@ class StreamHelper(
|
||||
|
||||
surface.unlockCanvasAndPost(canvas)
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
surfaceTexture!!.updateTexImage()
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
val image = imageReader!!.acquireLatestImage()
|
||||
filamentStream!!.setAcquiredImage(
|
||||
@@ -146,7 +140,7 @@ class StreamHelper(
|
||||
|
||||
fun nextTest() {
|
||||
stopTest()
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % 3]
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % StreamSource.values().size]
|
||||
startTest()
|
||||
}
|
||||
|
||||
@@ -213,23 +207,6 @@ class StreamHelper(
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
|
||||
// Create the Android surface that will hold the canvas image.
|
||||
surfaceTexture = SurfaceTexture(externalTextureId)
|
||||
surfaceTexture!!.setDefaultBufferSize(resolution.width, resolution.height)
|
||||
canvasSurface = Surface(surfaceTexture)
|
||||
|
||||
// Create the Filament Stream object that gets bound to the Texture.
|
||||
filamentStream = Stream.Builder()
|
||||
.stream(externalTextureId.toLong())
|
||||
.width(resolution.width)
|
||||
.height(resolution.height)
|
||||
.build(filamentEngine)
|
||||
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
filamentStream = Stream.Builder()
|
||||
.width(resolution.width)
|
||||
|
||||
+4
-3
@@ -281,7 +281,7 @@ class MainActivity : Activity() {
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
animator.cancel()
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
@@ -328,11 +328,11 @@ class MainActivity : Activity() {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
|
||||
displayHelper.attach(renderer, surfaceView.display);
|
||||
displayHelper.attach(renderer, surfaceView.display)
|
||||
}
|
||||
|
||||
override fun onDetachedFromSurface() {
|
||||
displayHelper.detach();
|
||||
displayHelper.detach()
|
||||
swapChain?.let {
|
||||
engine.destroySwapChain(it)
|
||||
// Required to ensure we don't return before Filament is done executing the
|
||||
@@ -353,6 +353,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun readUncompressedAsset(assetName: String): ByteBuffer {
|
||||
assets.openFd(assetName).use { fd ->
|
||||
val input = fd.createInputStream()
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
@@ -98,9 +98,9 @@ function print_matdbg_help {
|
||||
echo ""
|
||||
echo "FOR ANDROID BUILDS:"
|
||||
echo ""
|
||||
echo "1) The most reliable way to enable matdbg is to bypass Gradle and"
|
||||
echo " directly modify the appropriate two lines in the following file:"
|
||||
echo " ./android/filament-android/CMakeLists.txt"
|
||||
echo "1) For Android Studio builds, make sure to set:"
|
||||
echo " -Pcom.google.android.filament.matdbg"
|
||||
echo " option in Preferences > Build > Compiler > Command line options."
|
||||
echo ""
|
||||
echo "2) The port number is hardcoded to 8081 so you will need to do:"
|
||||
echo " adb forward tcp:8081 tcp:8081"
|
||||
@@ -156,6 +156,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
|
||||
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
|
||||
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
@@ -303,7 +304,7 @@ function build_webgl_with_target {
|
||||
}
|
||||
|
||||
function build_webgl {
|
||||
# For the host tools, supress install and always use Release.
|
||||
# For the host tools, suppress install and always use Release.
|
||||
local old_install_command=${INSTALL_COMMAND}; INSTALL_COMMAND=
|
||||
local old_issue_debug_build=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
|
||||
local old_issue_release_build=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
|
||||
@@ -402,7 +403,7 @@ function ensure_android_build {
|
||||
function build_android {
|
||||
ensure_android_build
|
||||
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -456,6 +457,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleDebug \
|
||||
:gltfio-android:assembleDebug \
|
||||
:filament-utils-android:assembleDebug
|
||||
@@ -487,8 +489,7 @@ function build_android {
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-debug.aar ../out/gltfio-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-debug.aar ../out/filament-utils-android-debug.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
@@ -505,6 +506,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleRelease \
|
||||
:gltfio-android:assembleRelease \
|
||||
:filament-utils-android:assembleRelease
|
||||
@@ -536,8 +538,7 @@ function build_android {
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-release.aar ../out/gltfio-android-release.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-release.aar ../out/filament-utils-android-release.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
@@ -600,7 +601,7 @@ function archive_ios {
|
||||
}
|
||||
|
||||
function build_ios {
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -756,6 +757,7 @@ while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
|
||||
d)
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
|
||||
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
|
||||
@@ -52,11 +52,11 @@ if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
fi
|
||||
|
||||
# Only build 1 32 bit and 1 64 bit target during presubmit to cut down build times
|
||||
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||
# Continuous builds will build everything
|
||||
ANDROID_ABIS=
|
||||
if [[ "$TARGET" == "presubmit" ]]; then
|
||||
ANDROID_ABIS="-q arm64-v8a,x86"
|
||||
ANDROID_ABIS="-q arm64-v8a"
|
||||
fi
|
||||
|
||||
# Build the Android sample-gltf-viewer APK during release.
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
setuptools==40.6.2
|
||||
wheel==0.37.1
|
||||
certifi==2021.10.8
|
||||
cffi==1.15.0
|
||||
charset-normalizer==2.0.12
|
||||
Deprecated==1.2.13
|
||||
idna==3.3
|
||||
pycparser==2.21
|
||||
PyGithub==1.55
|
||||
PyJWT==2.3.0
|
||||
PyNaCl==1.5.0
|
||||
requests==2.27.1
|
||||
urllib3==1.26.9
|
||||
wrapt==1.14.0
|
||||
@@ -11,3 +11,4 @@ tools/cmgen/test_cmgen compare
|
||||
tools/glslminifier/test_glslminifier
|
||||
libs/filameshio/test_filameshio
|
||||
libs/camutils/test_camutils
|
||||
libs/ktxreader/test_ktxreader
|
||||
|
||||
@@ -12,6 +12,25 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# requirements.txt created via:
|
||||
#
|
||||
# pip3 install virtualenv
|
||||
# python3 -m venv env
|
||||
# pip3 install PyGithub
|
||||
# pip3 install wheel
|
||||
# --all includes wheel and setuputils, which is needed for GitHub Actions
|
||||
# pip3 freeze --all > requirements.txt
|
||||
# Manually move 'setuptools' and 'wheel' lines to the beginning of the file.
|
||||
# Manually remove the 'pip' line.
|
||||
#
|
||||
# Requirements are installed in GitHub Actions via:
|
||||
# xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
# xargs must be used because the ordering of the dependencies matters (namely, setuptools).
|
||||
# sudo must be used to uninstall non-matching versions of packages.
|
||||
# pip is removed to avoid conflicts with the pre-installed pip version on Actions.
|
||||
# This technique does not work with Windows, unfortunately.
|
||||
|
||||
from github import Github
|
||||
import os, sys
|
||||
|
||||
|
||||
@@ -3,4 +3,6 @@
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
# Install ninja globally for AGP
|
||||
cp ninja /usr/local/bin
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
+11
-3
@@ -1,7 +1,15 @@
|
||||
#!/bin/bash
|
||||
if [ `uname` == "Linux" ];then
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip
|
||||
unzip -q ninja-linux.zip
|
||||
elif [ `uname` == "Darwin" ];then
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
else
|
||||
echo "Unsupported OS"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -9,7 +17,7 @@ export PATH="$PWD:$PATH"
|
||||
# npm install -g typescript
|
||||
|
||||
# Install emscripten.
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
|
||||
+53
-24
@@ -106,15 +106,16 @@ counter-increment: h6;margin-right:10px}
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthwrite" class="level3"><span class="tocNumber">4.2.19 </span>Rasterization: depthWrite</a><br>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthculling" class="level3"><span class="tocNumber">4.2.20 </span>Rasterization: depthCulling</a><br>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:doublesided" class="level3"><span class="tocNumber">4.2.21 </span>Rasterization: doubleSided</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" class="level3"><span class="tocNumber">4.2.22 </span>Lighting: shadowMultiplier</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:transparentshadow" class="level3"><span class="tocNumber">4.2.23 </span>Lighting: transparentShadow</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" class="level3"><span class="tocNumber">4.2.24 </span>Lighting: clearCoatIorChange</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" class="level3"><span class="tocNumber">4.2.25 </span>Lighting: multiBounceAmbientOcclusion</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" class="level3"><span class="tocNumber">4.2.26 </span>Lighting: specularAmbientOcclusion</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" class="level3"><span class="tocNumber">4.2.27 </span>Anti-aliasing: specularAntiAliasing</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" class="level3"><span class="tocNumber">4.2.28 </span>Anti-aliasing: specularAntiAliasingVariance</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" class="level3"><span class="tocNumber">4.2.29 </span>Anti-aliasing: specularAntiAliasingThreshold</a><br>
|
||||
<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" class="level3"><span class="tocNumber">4.2.30 </span>Shading: customSurfaceShading</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:reflections" class="level3"><span class="tocNumber">4.2.22 </span>Lighting: reflections</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" class="level3"><span class="tocNumber">4.2.23 </span>Lighting: shadowMultiplier</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:transparentshadow" class="level3"><span class="tocNumber">4.2.24 </span>Lighting: transparentShadow</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" class="level3"><span class="tocNumber">4.2.25 </span>Lighting: clearCoatIorChange</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" class="level3"><span class="tocNumber">4.2.26 </span>Lighting: multiBounceAmbientOcclusion</a><br>
|
||||
<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" class="level3"><span class="tocNumber">4.2.27 </span>Lighting: specularAmbientOcclusion</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" class="level3"><span class="tocNumber">4.2.28 </span>Anti-aliasing: specularAntiAliasing</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" class="level3"><span class="tocNumber">4.2.29 </span>Anti-aliasing: specularAntiAliasingVariance</a><br>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" class="level3"><span class="tocNumber">4.2.30 </span>Anti-aliasing: specularAntiAliasingThreshold</a><br>
|
||||
<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" class="level3"><span class="tocNumber">4.2.31 </span>Shading: customSurfaceShading</a><br>
|
||||
<a href="#materialdefinitions/vertexblock" class="level2"><span class="tocNumber">4.3 </span>Vertex block</a><br>
|
||||
<a href="#materialdefinitions/vertexblock/materialvertexinputs" class="level3"><span class="tocNumber">4.3.1 </span>Material vertex inputs</a><br>
|
||||
<a href="#materialdefinitions/fragmentblock" class="level2"><span class="tocNumber">4.4 </span>Fragment block</a><br>
|
||||
@@ -773,7 +774,7 @@ and with (right)</span></center></div></center>
|
||||
|
||||
The <code>bentNormal</code> property defines the average unoccluded direction at a point on the surface. It is
|
||||
used to improve the accuracy of indirect lighting. Bent normals can also improve the quality of
|
||||
specular ambient occlusion (see section <a href="#toc4.2.26">4.2.26</a> about
|
||||
specular ambient occlusion (see section <a href="#toc4.2.27">4.2.27</a> about
|
||||
<code>specularAmbientOcclusion</code>).
|
||||
|
||||
</p><p>
|
||||
@@ -1959,15 +1960,43 @@ and sorting issues are minimized or eliminated</span></center></div></center>
|
||||
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Enables two-sided rendering and its capability to be toggled at run time. When set to <code>true</code>,
|
||||
<code>culling</code> is automatically set to <code>none</code>; if the triangle is back-facing, the triangle's
|
||||
normal is flipped to become front-facing. When explicitly set to <code>false</code>, this allows the
|
||||
double-sidedness to be toggled at run time.
|
||||
</p></dd><dt>Description</dt><dd><p> Only available in the <code>unlit</code> shading model. If this property is enabled, the final color
|
||||
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
|
||||
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
|
||||
This is only supported with shadows from directional lights.
|
||||
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> doubleSided : <span class="hljs-literal">true</span></span>
|
||||
<span class="line"> name : <span class="hljs-string">"Invisible shadow plane"</span>,</span>
|
||||
<span class="line"> shadingModel : unlit,</span>
|
||||
<span class="line"> shadowMultiplier : <span class="hljs-literal">true</span>,</span>
|
||||
<span class="line"> blending : transparent</span>
|
||||
<span class="line">}</span>
|
||||
<span class="line"></span>
|
||||
<span class="line">fragment {</span>
|
||||
<span class="line"> void material(inout MaterialInputs material) {</span>
|
||||
<span class="line"> prepareMaterial(material);</span>
|
||||
<span class="line"> <span class="hljs-comment">// baseColor defines the color and opacity of the final shadow</span></span>
|
||||
<span class="line"> material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);</span>
|
||||
<span class="line"> }</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="lighting:shadowmultiplier"> </a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier"> </a><a class="target" name="toc4.2.22"> </a><h3>Lighting: shadowMultiplier</h3>
|
||||
<a class="target" name="lighting:reflections"> </a><a class="target" name="materialdefinitions/materialblock/lighting:reflections"> </a><a class="target" name="toc4.2.22"> </a><h3>Lighting: reflections</h3>
|
||||
<p>
|
||||
|
||||
|
||||
</p><dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
|
||||
</p></dd><dt>Value</dt><dd><p> <code>default</code> or <code>screenspace</code>. Defaults to <code>default</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Controls the source of specular reflections for this material. When this property is set to
|
||||
<code>default</code>, reflections only come image-based lights. When this property is set to
|
||||
<code>screenspace</code>, reflections come from the screen space's color buffer in addition to
|
||||
image-based lights.
|
||||
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> name : <span class="hljs-string">"Glossy metal"</span>,</span>
|
||||
<span class="line"> reflections : screenspace</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="lighting:shadowmultiplier"> </a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier"> </a><a class="target" name="toc4.2.23"> </a><h3>Lighting: shadowMultiplier</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -1994,7 +2023,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
|
||||
<span class="line"> material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);</span>
|
||||
<span class="line"> }</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="lighting:transparentshadow"> </a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow"> </a><a class="target" name="toc4.2.23"> </a><h3>Lighting: transparentShadow</h3>
|
||||
<a class="target" name="lighting:transparentshadow"> </a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow"> </a><a class="target" name="toc4.2.24"> </a><h3>Lighting: transparentShadow</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2028,7 +2057,7 @@ radius of 4. Model <a href="https://sketchfab.com/3d-models/bottle-of-water-48fd
|
||||
by <a href="https://sketchfab.com/person-x">T-Art</a>.</span></center></div></center>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="lighting:clearcoatiorchange"> </a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange"> </a><a class="target" name="toc4.2.24"> </a><h3>Lighting: clearCoatIorChange</h3>
|
||||
<a class="target" name="lighting:clearcoatiorchange"> </a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange"> </a><a class="target" name="toc4.2.25"> </a><h3>Lighting: clearCoatIorChange</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2050,7 +2079,7 @@ with <code>clearCoatIorChange</code> enabled (left) and disabled
|
||||
(right).</span></center></div></center>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="lighting:multibounceambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion"> </a><a class="target" name="toc4.2.25"> </a><h3>Lighting: multiBounceAmbientOcclusion</h3>
|
||||
<a class="target" name="lighting:multibounceambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion"> </a><a class="target" name="toc4.2.26"> </a><h3>Lighting: multiBounceAmbientOcclusion</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2079,7 +2108,7 @@ occclusion enabled (left) and disabled (right).</span></center></div></center>
|
||||
occclusion enabled and disabled.</span></center></div></center>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="lighting:specularambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion"> </a><a class="target" name="toc4.2.26"> </a><h3>Lighting: specularAmbientOcclusion</h3>
|
||||
<a class="target" name="lighting:specularambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion"> </a><a class="target" name="toc4.2.27"> </a><h3>Lighting: specularAmbientOcclusion</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2105,7 +2134,7 @@ occclusion enabled and disabled.</span></center></div></center>
|
||||
particularly visible under the hose.</span></center></div></center>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="anti-aliasing:specularantialiasing"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing"> </a><a class="target" name="toc4.2.27"> </a><h3>Anti-aliasing: specularAntiAliasing</h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasing"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing"> </a><a class="target" name="toc4.2.28"> </a><h3>Anti-aliasing: specularAntiAliasing</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2122,7 +2151,7 @@ particularly visible under the hose.</span></center></div></center>
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> specularAntiAliasing : <span class="hljs-literal">true</span></span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="toc4.2.28"> </a><h3>Anti-aliasing: specularAntiAliasingVariance</h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="toc4.2.29"> </a><h3>Anti-aliasing: specularAntiAliasingVariance</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2137,7 +2166,7 @@ particularly visible under the hose.</span></center></div></center>
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> specularAntiAliasingVariance : <span class="hljs-number">0.2</span></span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="toc4.2.29"> </a><h3>Anti-aliasing: specularAntiAliasingThreshold</h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="toc4.2.30"> </a><h3>Anti-aliasing: specularAntiAliasingThreshold</h3>
|
||||
<p>
|
||||
|
||||
|
||||
@@ -2151,7 +2180,7 @@ particularly visible under the hose.</span></center></div></center>
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> specularAntiAliasingThreshold : <span class="hljs-number">0.1</span></span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="shading:customsurfaceshading"> </a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading"> </a><a class="target" name="toc4.2.30"> </a><h3>Shading: customSurfaceShading</h3>
|
||||
<a class="target" name="shading:customsurfaceshading"> </a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading"> </a><a class="target" name="toc4.2.31"> </a><h3>Shading: customSurfaceShading</h3>
|
||||
<p>
|
||||
|
||||
|
||||
|
||||
+47
-11
@@ -1050,7 +1050,7 @@ Type
|
||||
: array of `string`
|
||||
|
||||
Value
|
||||
: Each entry must be any of `dynamicLighting`, `directionalLighting`, `shadowReceiver` or `skinning`.
|
||||
: Each entry must be any of `dynamicLighting`, `directionalLighting`, `shadowReceiver`,`skinning` or `ssr`.
|
||||
|
||||
Description
|
||||
: Used to specify a list of shader variants that the application guarantees will never be
|
||||
@@ -1068,6 +1068,7 @@ Description of the variants:
|
||||
- `skinning`, used when an object is animated using GPU skinning
|
||||
- `fog`, used when global fog is applied to the scene
|
||||
- `vsm`, used when VSM shadows are enabled and the object is a shadow receiver
|
||||
- `ssr`, used when screen-space reflections are enabled in the View
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
@@ -1278,8 +1279,9 @@ Description
|
||||
- **Screen**: blending is enabled. Effectively the opposite of the `multiply`, the content of the
|
||||
render target is brightened.
|
||||
- **Masked**: blending is disabled. This blending mode enables alpha masking. The alpha channel
|
||||
of the material's output defines whether a fragment is discarded or not. See the maskThreshold
|
||||
section for more information.
|
||||
of the material's output defines whether a fragment is discarded or not. Additionally,
|
||||
ALPHA_TO_COVERAGE is enabled for non-translucent views. See the maskThreshold section for more
|
||||
information.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
@@ -1363,8 +1365,9 @@ Value
|
||||
|
||||
Description
|
||||
: Sets the minimum alpha value a fragment must have to not be discarded when the `blending` mode
|
||||
is set to `masked`. When the blending mode is not `masked`, this value is ignored. This value
|
||||
can be used to controlled the appearance of alpha-masked objects.
|
||||
is set to `masked`. If the fragment is not discarded, its source alpha is set to 1. When the
|
||||
blending mode is not `masked`, this value is ignored. This value can be used to controlled the
|
||||
appearance of alpha-masked objects.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
@@ -1500,14 +1503,46 @@ Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: Enables two-sided rendering and its capability to be toggled at run time. When set to `true`,
|
||||
`culling` is automatically set to `none`; if the triangle is back-facing, the triangle's
|
||||
normal is flipped to become front-facing. When explicitly set to `false`, this allows the
|
||||
double-sidedness to be toggled at run time.
|
||||
: Only available in the `unlit` shading model. If this property is enabled, the final color
|
||||
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
|
||||
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
|
||||
This is only supported with shadows from directional lights.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
doubleSided : true
|
||||
name : "Invisible shadow plane",
|
||||
shadingModel : unlit,
|
||||
shadowMultiplier : true,
|
||||
blending : transparent
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
// baseColor defines the color and opacity of the final shadow
|
||||
material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Lighting: reflections
|
||||
|
||||
Type
|
||||
: `string`
|
||||
|
||||
Value
|
||||
: `default` or `screenspace`. Defaults to `default`.
|
||||
|
||||
Description
|
||||
: Controls the source of specular reflections for this material. When this property is set to
|
||||
`default`, reflections only come image-based lights. When this property is set to
|
||||
`screenspace`, reflections come from the screen space's color buffer in addition to
|
||||
image-based lights.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
name : "Glossy metal",
|
||||
reflections : screenspace
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -2134,7 +2169,7 @@ type aliases:
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getResolution()** | float4 | Resolution of the view in pixels: `width`, `height`, `1 / width`, `1 / height`
|
||||
**getResolution()** | float4 | Dimensions of the view's effective viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands. This can be used in conjunction with `getNormalizedViewportCoord()` to generate pixel coordinates.
|
||||
**getWorldCameraPosition()** | float3 | Position of the camera/eye in world space
|
||||
**getWorldOffset()** | float3 | The shift required to obtain API-level world space
|
||||
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
|
||||
@@ -2305,6 +2340,7 @@ variants:
|
||||
- `skinning`, used when an object is animated using GPU skinning or vertex morphing
|
||||
- `fog`, used when global fog is applied to the scene
|
||||
- `vsm`, used when VSM shadows are enabled and the object is a shadow receiver
|
||||
- `ssr`, used when screen-space reflections are enabled in the View
|
||||
|
||||
Example:
|
||||
```
|
||||
|
||||
+1354
-1963
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+52
-21
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -307,6 +307,7 @@ class FilamentViewer extends LitElement {
|
||||
const config = {
|
||||
normalizeSkinningWeights: true,
|
||||
recomputeBoundingBoxes: false,
|
||||
ignoreBindTransform: false,
|
||||
asyncInterval: 30
|
||||
};
|
||||
|
||||
@@ -333,7 +334,8 @@ class FilamentViewer extends LitElement {
|
||||
|
||||
const resourceLoader = new Filament.gltfio$ResourceLoader(this.engine,
|
||||
config.normalizeSkinningWeights,
|
||||
config.recomputeBoundingBoxes);
|
||||
config.recomputeBoundingBoxes,
|
||||
config.ignoreBindTransform);
|
||||
|
||||
let remaining = Object.keys(this.srcBlobResources).length;
|
||||
for (const name in this.srcBlobResources) {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_redball.js"></script>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_suzanne.js"></script>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="//unpkg.com/filament@1.15.0/filament.js"></script>
|
||||
<script src="filament.js"></script>
|
||||
<script src="//unpkg.com/gl-matrix@2.8.1"></script>
|
||||
<script src="//unpkg.com/gltumble"></script>
|
||||
<script src="tutorial_triangle.js"></script>
|
||||
|
||||
+70
-30
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -113,7 +113,7 @@ class App {
|
||||
this.view = engine.createView();
|
||||
this.view.setVignetteOptions({ midPoint: 0.8, enabled: true });
|
||||
|
||||
this.view.setBloomOptions({ stength: 0.2, enabled: true });
|
||||
this.view.setBloomOptions({ strength: 0.2, enabled: true });
|
||||
|
||||
this.view.setCamera(this.camera);
|
||||
this.view.setScene(this.scene);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20
-13
@@ -64,7 +64,7 @@
|
||||
<td align="left">Array of 16-bit or 32-bit unsigned integers consumed by the GPU.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#KtxBundle">KtxBundle</a></td>
|
||||
<td align="left"><a href="#Ktx1Bundle">Ktx1Bundle</a></td>
|
||||
<td align="left">In-memory representation of a KTX file.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -583,6 +583,11 @@
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, sampleCount, customResolve.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setScreenSpaceReflectionsOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: thickness, bias, maxDistance, stride, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setShadowOptions(instance, overrides)</strong>
|
||||
<ul>
|
||||
<li><em>instance</em> Instance of a light component obtained from <code>getInstance</code>.</li>
|
||||
@@ -662,63 +667,63 @@ as quaternions.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='KtxBundle' href='#KtxBundle'>KtxBundle</a></h2>
|
||||
<h2>class <a id='Ktx1Bundle' href='#Ktx1Bundle'>Ktx1Bundle</a></h2>
|
||||
<p>In-memory representation of a KTX file.</p>
|
||||
<ul>
|
||||
<li><strong>ktxBundle.getArrayLength()</strong>
|
||||
<li><strong>ktx1Bundle.getArrayLength()</strong>
|
||||
<ul>
|
||||
<li>Obtains length of the texture array.</li>
|
||||
<li><em>returns</em> The number of elements in the texture array</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getCompressedPixelDataType()</strong>
|
||||
<li><strong>ktx1Bundle.getCompressedPixelDataType()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#CompressedPixelDataType">CompressedPixelDataType</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getInternalFormat(srgb)</strong>
|
||||
<li><strong>ktx1Bundle.getInternalFormat(srgb)</strong>
|
||||
<ul>
|
||||
<li><em>srgb</em> boolean that forces the resulting format to SRGB if possible.</li>
|
||||
<li><em>returns</em> <a href="#Texture%24InternalFormat">Texture$InternalFormat</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getMetadata(key)</strong>
|
||||
<li><strong>ktx1Bundle.getMetadata(key)</strong>
|
||||
<ul>
|
||||
<li>Obtains arbitrary metadata from the KTX file.</li>
|
||||
<li><em>key</em> string</li>
|
||||
<li><em>returns</em> string</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getPixelDataFormat()</strong>
|
||||
<li><strong>ktx1Bundle.getPixelDataFormat()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#PixelDataFormat">PixelDataFormat</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.getPixelDataType()</strong>
|
||||
<li><strong>ktx1Bundle.getPixelDataType()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> <a href="#PixelDataType">PixelDataType</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.info()</strong>
|
||||
<li><strong>ktx1Bundle.info()</strong>
|
||||
<ul>
|
||||
<li>Obtains properties of the KTX header.</li>
|
||||
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.info()</strong>
|
||||
<li><strong>ktx1Bundle.info()</strong>
|
||||
<ul>
|
||||
<li>Obtains properties of the KTX header.</li>
|
||||
<li><em>returns</em> The <a href="#KtxInfo">KtxInfo</a> property accessor object.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxBundle.isCompressed()</strong>
|
||||
<li><strong>ktx1Bundle.isCompressed()</strong>
|
||||
<ul>
|
||||
<li><em>returns</em> boolean</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Most clients should use one of the <code>create*FromKtx</code> utility methods in the JavaScript <a href="#Engine">Engine</a>
|
||||
wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
|
||||
wrapper rather than interacting with <code>Ktx1Bundle</code> directly.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='KtxInfo' href='#KtxInfo'>KtxInfo</a></h2>
|
||||
@@ -743,7 +748,7 @@ wrapper rather than interacting with <code>KtxBundle</code> directly.</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>For example, <code>ktxbundle.info().pixelWidth</code>. See the
|
||||
<p>For example, <code>Ktx1Bundle.info().pixelWidth</code>. See the
|
||||
<a href="https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/">KTX spec</a> for the list of
|
||||
properties.</p>
|
||||
</div>
|
||||
@@ -1267,7 +1272,9 @@ This defines the following functions:</p>
|
||||
<ul>
|
||||
<li>POINTS</li>
|
||||
<li>LINES</li>
|
||||
<li>LINE_STRIP</li>
|
||||
<li>TRIANGLES</li>
|
||||
<li>TRIANGLE_STRIP</li>
|
||||
<li>NONE</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,9 @@ textures.</p>
|
||||
<a href="tutorial_triangle.html">previous tutorial</a>. Change the last script tag from <code>triangle.js</code> to <code>redball.js</code>.</p>
|
||||
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
|
||||
appropriate <a href="//github.com/google/filament/releases">Filament release</a>. You should choose the
|
||||
archive that corresponds to your development machine rather than the one for web.</p>
|
||||
archive that corresponds to your development machine rather than the one for web, and the version
|
||||
that matches the <code>unpkg.com/filament@x.x.x</code> url in the script tag of <code>redball.html</code> (you may check
|
||||
out the last available release of <a href="https://www.npmjs.com/package/filament">filament on npm</a>).</p>
|
||||
<h2>Define plastic material</h2>
|
||||
<p>The <code>matc</code> tool consumes a text file containing a high-level description of a PBR material, and
|
||||
produces a binary material package that contains shader code and associated metadata. For more
|
||||
@@ -60,12 +62,12 @@ IBL KTX contains these coefficients in its metadata.</p>
|
||||
<h2>Create JavaScript</h2>
|
||||
<p>Next, create <code>redball.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'pillars_2k'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'plastic.filamat'</span>
|
||||
|
||||
Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #408080; font-style: italic">// Create some global aliases to enums for convenience.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
|
||||
<span style="color: #008000">window</span>.VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
|
||||
<span style="color: #008000">window</span>.AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
|
||||
<span style="color: #008000">window</span>.PrimitiveType <span style="color: #666666">=</span> Filament.RenderableManager$PrimitiveType;
|
||||
@@ -73,7 +75,7 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #008000">window</span>.Fov <span style="color: #666666">=</span> Filament.Camera$Fov;
|
||||
<span style="color: #008000">window</span>.LightType <span style="color: #666666">=</span> Filament.LightManager$Type;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> canvas <span style="color: #666666">=</span> <span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(canvas);
|
||||
} );
|
||||
@@ -84,11 +86,11 @@ Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
|
||||
<span style="color: #008000; font-weight: bold">const</span> scene <span style="color: #666666">=</span> engine.createScene();
|
||||
|
||||
<span style="color: #408080; font-style: italic">// TODO: create material</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create sphere</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create lights</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create IBL</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: create skybox</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create material</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span>
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
|
||||
@@ -209,9 +211,9 @@ following (don't type this out, there's an easier way).</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> format <span style="color: #666666">=</span> Filament.PixelDataFormat.RGB;
|
||||
<span style="color: #008000; font-weight: bold">const</span> datatype <span style="color: #666666">=</span> Filament.PixelDataType.UINT_10F_11F_11F_REV;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[ibl_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(ibl_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(ibl_package);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibltex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(iblktx.info().pixelWidth)
|
||||
@@ -227,11 +229,11 @@ following (don't type this out, there's an easier way).</p>
|
||||
ibltex.setImageCube(engine, level, pixelbuffer);
|
||||
}
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Parse the spherical harmonics metadata.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> shstring <span style="color: #666666">=</span> iblktx.getMetadata(<span style="color: #BA2121">'sh'</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #BB6688">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #A45A77">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Build the IBL object and insert it into the scene.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> Filament.IndirectLight.Builder()
|
||||
.reflections(ibltex)
|
||||
.irradianceSh(<span style="color: #666666">3</span>, shfloats)
|
||||
@@ -253,7 +255,7 @@ scene.setIndirectLight(indirectLight);
|
||||
Without a skybox, the reflections on the ball are not representative of its surroundings.
|
||||
Here's one way to create a texture for the skybox:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> sky_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[sky_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.KtxBundle(sky_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(sky_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skytex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(skyktx.info().pixelWidth)
|
||||
.height(skyktx.info().pixelHeight)
|
||||
|
||||
@@ -22,25 +22,25 @@ converting <a href="https://github.com/google/filament/blob/main/assets/models/m
|
||||
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
|
||||
non-compressed variants for each texture, since not all platforms support the same compression
|
||||
formats. First copy over the PNG files from the <a href="https://github.com/google/filament/blob/main/assets/models/monkey">monkey folder</a>, then do:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
|
||||
mipgen albedo.png albedo.ktx
|
||||
mipgen --compression<span style="color: #666666">=</span>astc_fast_ldr_4x4 albedo.png albedo_astc.ktx
|
||||
mipgen --compression<span style="color: #666666">=</span>s3tc_rgb_dxt1 albedo.png albedo_s3tc_srgb.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear normal.png normal.ktx
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #BB6622; font-weight: bold">\</span>
|
||||
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #AA5D1F; font-weight: bold">\</span>
|
||||
normal.png normal_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
|
||||
mipgen --grayscale roughness.png roughness.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 roughness.png roughness_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
|
||||
mipgen --grayscale metallic.png metallic.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 metallic.png metallic_etc.ktx
|
||||
|
||||
<span style="color: #408080; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
|
||||
mipgen --grayscale ao.png ao.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
|
||||
</pre></div>
|
||||
@@ -101,7 +101,7 @@ materials, consult the official document describing the <a href="https://google.
|
||||
<p>Create a text file called <code>suzanne.html</code> and copy over the HTML that we used in the <a href="tutorial_redball.html">previous
|
||||
tutorial</a>. Change the last script tag from <code>redball.js</code> to <code>suzanne.js</code>. Next, create <code>suzanne.js</code>
|
||||
with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// TODO: declare asset URLs</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span>
|
||||
|
||||
Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>]);
|
||||
@@ -119,9 +119,9 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url, <span style="color: #008000; font-weight: bold">this</span>.matinstance);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.suzanne <span style="color: #666666">=</span> filamesh.renderable;
|
||||
|
||||
<span style="color: #408080; font-style: italic">// TODO: create sky box and IBL</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: initialize gltumble</span>
|
||||
<span style="color: #408080; font-style: italic">// TODO: fetch larger assets</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span>
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
|
||||
@@ -141,7 +141,7 @@ Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
}
|
||||
|
||||
render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: apply gltumble matrix</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
@@ -176,14 +176,14 @@ last resort. Go ahead and replace the <strong>declare asset URLs</strong> commen
|
||||
<span style="color: #008000; font-weight: bold">const</span> texture_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'etc'</span>);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'venetian_crossroads_2k'</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #BB6688; font-weight: bold">${</span>environ<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #BB6688; font-weight: bold">${</span>albedo_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #BB6688; font-weight: bold">${</span>texture_suffix<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'textured.filamat'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh_url <span style="color: #666666">=</span> <span style="color: #BA2121">'suzanne.filamesh'</span>;
|
||||
</pre></div>
|
||||
@@ -224,7 +224,7 @@ was created in the app constructor.</p>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'normal'</span>, normal, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'ao'</span>, ao, sampler);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_large_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
@@ -236,7 +236,7 @@ was created in the app constructor.</p>
|
||||
<h2>Introduce trackball rotation</h2>
|
||||
<p>Add the following script tag to your HTML file. This imports a small third-party library that
|
||||
listens for drag events and computes a rotation matrix.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gltumble"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gltumble"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
</pre></div>
|
||||
|
||||
<p>Next, replace the <strong>initialize gltumble</strong> and <strong>apply gltumble matrix</strong> comments with the following
|
||||
|
||||
@@ -16,22 +16,22 @@ subsequent code blocks.</p>
|
||||
<h2>Start your project</h2>
|
||||
<p>First, create a text file called <code>triangle.html</code> and fill it with the following HTML. This creates
|
||||
a mobile-friendly page with a full-screen canvas.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #BC7A00"><!DOCTYPE html></span>
|
||||
<<span style="color: #008000; font-weight: bold">html</span> <span style="color: #7D9029">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">"en"</span>>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #9C6500"><!DOCTYPE html></span>
|
||||
<<span style="color: #008000; font-weight: bold">html</span> <span style="color: #687822">lang</span><span style="color: #666666">=</span><span style="color: #BA2121">"en"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">head</span>>
|
||||
<<span style="color: #008000; font-weight: bold">title</span>>Filament Tutorial</<span style="color: #008000; font-weight: bold">title</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">"utf-8"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #7D9029">name</span><span style="color: #666666">=</span><span style="color: #BA2121">"viewport"</span> <span style="color: #7D9029">content</span><span style="color: #666666">=</span><span style="color: #BA2121">"width=device-width,user-scalable=no,initial-scale=1"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">style</span>>
|
||||
<span style="color: #008000; font-weight: bold">body</span> { <span style="color: #008000; font-weight: bold">margin</span>: <span style="color: #666666">0</span>; <span style="color: #008000; font-weight: bold">overflow</span>: <span style="color: #008000; font-weight: bold">hidden</span>; }
|
||||
<span style="color: #008000; font-weight: bold">canvas</span> { touch-action: <span style="color: #008000; font-weight: bold">none</span>; <span style="color: #008000; font-weight: bold">width</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; <span style="color: #008000; font-weight: bold">height</span>: <span style="color: #666666">100</span><span style="color: #B00040">%</span>; }
|
||||
</<span style="color: #008000; font-weight: bold">style</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">charset</span><span style="color: #666666">=</span><span style="color: #BA2121">"utf-8"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">meta</span> <span style="color: #687822">name</span><span style="color: #666666">=</span><span style="color: #BA2121">"viewport"</span> <span style="color: #687822">content</span><span style="color: #666666">=</span><span style="color: #BA2121">"width=device-width,user-scalable=no,initial-scale=1"</span>>
|
||||
<<span style="color: #008000; font-weight: bold">style</span>><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">body</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">margin</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">overflow</span>:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">hidden</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">canvas</span><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span>touch-action:<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">none</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">width</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">height</span>:<span style="color: #bbbbbb"> </span><span style="color: #666666">100</span><span style="color: #B00040">%</span>;<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span></<span style="color: #008000; font-weight: bold">style</span>>
|
||||
</<span style="color: #008000; font-weight: bold">head</span>>
|
||||
<<span style="color: #008000; font-weight: bold">body</span>>
|
||||
<<span style="color: #008000; font-weight: bold">canvas</span>></<span style="color: #008000; font-weight: bold">canvas</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/filament@1.15.0/filament.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gl-matrix@2.8.1"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #7D9029">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"triangle.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"filament.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"//unpkg.com/gl-matrix@2.8.1"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
<<span style="color: #008000; font-weight: bold">script</span> <span style="color: #687822">src</span><span style="color: #666666">=</span><span style="color: #BA2121">"triangle.js"</span>></<span style="color: #008000; font-weight: bold">script</span>>
|
||||
</<span style="color: #008000; font-weight: bold">body</span>>
|
||||
</<span style="color: #008000; font-weight: bold">html</span>>
|
||||
</pre></div>
|
||||
@@ -50,18 +50,18 @@ a mobile-friendly page with a full-screen canvas.</p>
|
||||
<p>Go ahead and create <code>triangle.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">class</span> App {
|
||||
<span style="color: #008000; font-weight: bold">constructor</span>() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: create entities</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
resize() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: adjust viewport and canvas</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,9 +81,9 @@ that define a PBR material. We'll learn more about material packages in the next
|
||||
<h2>Spawn a local server</h2>
|
||||
<p>Because of CORS restrictions, your web app cannot fetch the material package directly from the
|
||||
file system. One way around this is to create a temporary server using Python or node:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #408080; font-style: italic"># Python 3</span>
|
||||
python -m SimpleHTTPServer <span style="color: #408080; font-style: italic"># Python 2.7</span>
|
||||
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #408080; font-style: italic"># nodejs</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>python3 -m http.server <span style="color: #3D7B7B; font-style: italic"># Python 3</span>
|
||||
python -m SimpleHTTPServer <span style="color: #3D7B7B; font-style: italic"># Python 2.7</span>
|
||||
npx http-server -p <span style="color: #666666">8000</span> <span style="color: #3D7B7B; font-style: italic"># nodejs</span>
|
||||
</pre></div>
|
||||
|
||||
<p>To see if this works, navigate to <a href="http://localhost:8000">http://localhost:8000</a> and check if you
|
||||
@@ -185,10 +185,10 @@ view.</p>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Set up a blue-green background:</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span> [<span style="color: #666666">0.0</span>, <span style="color: #666666">0.1</span>, <span style="color: #666666">0.2</span>, <span style="color: #666666">1.0</span>], clear<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Adjust the initial viewport:</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();
|
||||
</pre></div>
|
||||
|
||||
@@ -198,14 +198,14 @@ However the canvas is still blank!</p>
|
||||
<p>Recall that our App class has a skeletal render method, which the browser calls every time it needs
|
||||
to repaint. Often this is 60 times a second.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render() {
|
||||
<span style="color: #408080; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
|
||||
code to the top of the render method.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #408080; font-style: italic">// Rotate the triangle.</span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">1000</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> transform <span style="color: #666666">=</span> mat4.fromRotation(mat4.create(), radians, [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
|
||||
@@ -213,7 +213,7 @@ code to the top of the render method.</p>
|
||||
tcm.setTransform(inst, transform);
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
|
||||
|
||||
<span style="color: #408080; font-style: italic">// Render the frame.</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
</pre></div>
|
||||
|
||||
|
||||
+56
-24
@@ -28,6 +28,7 @@ set(PUBLIC_HDRS
|
||||
include/filament/LightManager.h
|
||||
include/filament/Material.h
|
||||
include/filament/MaterialInstance.h
|
||||
include/filament/MorphTargetBuffer.h
|
||||
include/filament/Options.h
|
||||
include/filament/RenderTarget.h
|
||||
include/filament/RenderableManager.h
|
||||
@@ -51,7 +52,6 @@ set(SRCS
|
||||
src/BufferObject.cpp
|
||||
src/Camera.cpp
|
||||
src/Color.cpp
|
||||
src/ColorGrading.cpp
|
||||
src/ColorSpace.cpp
|
||||
src/Culler.cpp
|
||||
src/DFG.cpp
|
||||
@@ -63,19 +63,23 @@ set(SRCS
|
||||
src/FrameSkipper.cpp
|
||||
src/Froxelizer.cpp
|
||||
src/Frustum.cpp
|
||||
src/fsr.cpp
|
||||
src/IndexBuffer.cpp
|
||||
src/IndirectLight.cpp
|
||||
src/LightManager.cpp
|
||||
src/Material.cpp
|
||||
src/MaterialInstance.cpp
|
||||
src/MaterialParser.cpp
|
||||
src/MorphTargetBuffer.cpp
|
||||
src/PerViewUniforms.cpp
|
||||
src/PostProcessManager.cpp
|
||||
src/RenderPass.cpp
|
||||
src/RenderPrimitive.cpp
|
||||
src/RenderTarget.cpp
|
||||
src/RenderableManager.cpp
|
||||
src/Renderer.cpp
|
||||
src/RendererUtils.cpp
|
||||
src/ResourceAllocator.cpp
|
||||
src/ResourceList.cpp
|
||||
src/Scene.cpp
|
||||
src/ShadowMap.cpp
|
||||
src/ShadowMapManager.cpp
|
||||
@@ -85,22 +89,44 @@ set(SRCS
|
||||
src/SwapChain.cpp
|
||||
src/Texture.cpp
|
||||
src/ToneMapper.cpp
|
||||
src/TransformManager.cpp
|
||||
src/UniformBuffer.cpp
|
||||
src/VertexBuffer.cpp
|
||||
src/View.cpp
|
||||
src/Viewport.cpp
|
||||
src/components/CameraManager.cpp
|
||||
src/components/LightManager.cpp
|
||||
src/components/RenderableManager.cpp
|
||||
src/components/TransformManager.cpp
|
||||
src/fg2/Blackboard.cpp
|
||||
src/fg2/DependencyGraph.cpp
|
||||
src/fg2/FrameGraph.cpp
|
||||
src/fg2/FrameGraphPass.cpp
|
||||
src/fg2/FrameGraphResources.cpp
|
||||
src/fg2/FrameGraphTexture.cpp
|
||||
src/fg2/PassNode.cpp
|
||||
src/fg2/ResourceNode.cpp
|
||||
src/details/BufferObject.cpp
|
||||
src/details/Camera.cpp
|
||||
src/details/ColorGrading.cpp
|
||||
src/details/DebugRegistry.cpp
|
||||
src/details/Engine.cpp
|
||||
src/details/Fence.cpp
|
||||
src/details/IndexBuffer.cpp
|
||||
src/details/IndirectLight.cpp
|
||||
src/details/Material.cpp
|
||||
src/details/MaterialInstance.cpp
|
||||
src/details/MorphTargetBuffer.cpp
|
||||
src/details/RenderTarget.cpp
|
||||
src/details/Renderer.cpp
|
||||
src/details/Scene.cpp
|
||||
src/details/SkinningBuffer.cpp
|
||||
src/details/Skybox.cpp
|
||||
src/details/Stream.cpp
|
||||
src/details/SwapChain.cpp
|
||||
src/details/Texture.cpp
|
||||
src/details/VertexBuffer.cpp
|
||||
src/details/View.cpp
|
||||
src/fg/Blackboard.cpp
|
||||
src/fg/DependencyGraph.cpp
|
||||
src/fg/FrameGraph.cpp
|
||||
src/fg/FrameGraphPass.cpp
|
||||
src/fg/FrameGraphResources.cpp
|
||||
src/fg/FrameGraphTexture.cpp
|
||||
src/fg/PassNode.cpp
|
||||
src/fg/ResourceNode.cpp
|
||||
src/fsr.cpp
|
||||
)
|
||||
|
||||
set(PRIVATE_HDRS
|
||||
@@ -118,6 +144,7 @@ set(PRIVATE_HDRS
|
||||
src/PerViewUniforms.h
|
||||
src/PIDController.h
|
||||
src/PostProcessManager.h
|
||||
src/RendererUtils.h
|
||||
src/RenderPass.h
|
||||
src/RenderPrimitive.h
|
||||
src/ResourceAllocator.h
|
||||
@@ -140,6 +167,7 @@ set(PRIVATE_HDRS
|
||||
src/details/IndirectLight.h
|
||||
src/details/Material.h
|
||||
src/details/MaterialInstance.h
|
||||
src/details/MorphTargetBuffer.h
|
||||
src/details/RenderTarget.h
|
||||
src/details/Renderer.h
|
||||
src/details/Scene.h
|
||||
@@ -150,19 +178,19 @@ set(PRIVATE_HDRS
|
||||
src/details/Texture.h
|
||||
src/details/VertexBuffer.h
|
||||
src/details/View.h
|
||||
src/fg2/Blackboard.h
|
||||
src/fg2/FrameGraph.h
|
||||
src/fg2/FrameGraphId.h
|
||||
src/fg2/FrameGraphPass.h
|
||||
src/fg2/FrameGraphRenderPass.h
|
||||
src/fg2/FrameGraphResources.h
|
||||
src/fg2/FrameGraphTexture.h
|
||||
src/fg2/Resource.cpp
|
||||
src/fg2/details/DependencyGraph.h
|
||||
src/fg2/details/PassNode.h
|
||||
src/fg2/details/Resource.h
|
||||
src/fg2/details/ResourceNode.h
|
||||
src/fg2/details/Utilities.h
|
||||
src/fg/Blackboard.h
|
||||
src/fg/FrameGraph.h
|
||||
src/fg/FrameGraphId.h
|
||||
src/fg/FrameGraphPass.h
|
||||
src/fg/FrameGraphRenderPass.h
|
||||
src/fg/FrameGraphResources.h
|
||||
src/fg/FrameGraphTexture.h
|
||||
src/fg/Resource.cpp
|
||||
src/fg/details/DependencyGraph.h
|
||||
src/fg/details/PassNode.h
|
||||
src/fg/details/Resource.h
|
||||
src/fg/details/ResourceNode.h
|
||||
src/fg/details/Utilities.h
|
||||
src/fsr.h
|
||||
src/materials/fsr/ffx_a.h
|
||||
src/materials/fsr/ffx_fsr1.h
|
||||
@@ -202,6 +230,10 @@ set(MATERIAL_SRCS
|
||||
src/materials/separableGaussianBlur2.mat
|
||||
src/materials/separableGaussianBlur3.mat
|
||||
src/materials/separableGaussianBlur4.mat
|
||||
src/materials/separableGaussianBlur1L.mat
|
||||
src/materials/separableGaussianBlur2L.mat
|
||||
src/materials/separableGaussianBlur3L.mat
|
||||
src/materials/separableGaussianBlur4L.mat
|
||||
src/materials/antiAliasing/fxaa.mat
|
||||
src/materials/antiAliasing/taa.mat
|
||||
src/materials/vsmMipmap.mat
|
||||
|
||||
@@ -42,6 +42,7 @@ set(PRIVATE_HDRS
|
||||
include/private/backend/CircularBuffer.h
|
||||
include/private/backend/CommandBufferQueue.h
|
||||
include/private/backend/CommandStream.h
|
||||
include/private/backend/Dispatcher.h
|
||||
include/private/backend/Driver.h
|
||||
include/private/backend/DriverApi.h
|
||||
include/private/backend/DriverAPI.inc
|
||||
@@ -64,8 +65,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/gl_headers.h
|
||||
src/opengl/GLUtils.cpp
|
||||
src/opengl/GLUtils.h
|
||||
src/opengl/OpenGLBlitter.cpp
|
||||
src/opengl/OpenGLBlitter.h
|
||||
src/opengl/OpenGLContext.cpp
|
||||
src/opengl/OpenGLContext.h
|
||||
src/opengl/OpenGLDriver.cpp
|
||||
@@ -74,8 +73,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/OpenGLProgram.cpp
|
||||
src/opengl/OpenGLProgram.h
|
||||
src/opengl/OpenGLPlatform.cpp
|
||||
src/opengl/TimerQuery.cpp
|
||||
src/opengl/TimerQuery.h
|
||||
src/opengl/OpenGLTimerQuery.cpp
|
||||
src/opengl/OpenGLTimerQuery.h
|
||||
include/private/backend/OpenGLPlatform.h
|
||||
)
|
||||
if (EGL)
|
||||
@@ -88,7 +87,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
endif ()
|
||||
if (ANDROID)
|
||||
list(APPEND SRCS src/opengl/platforms/ExternalStreamManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/android/ExternalTextureManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGLAndroid.cpp)
|
||||
elseif (IOS)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaTouchGL.mm)
|
||||
@@ -395,7 +393,6 @@ if (APPLE)
|
||||
|
||||
target_link_libraries(backend_test PRIVATE
|
||||
backend
|
||||
filabridge
|
||||
getopt
|
||||
gtest
|
||||
SPIRV
|
||||
@@ -408,7 +405,6 @@ if (APPLE)
|
||||
SPIRV-Tools
|
||||
SPIRV-Tools-opt
|
||||
backend_test
|
||||
filabridge
|
||||
getopt
|
||||
gtest
|
||||
glslang
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
/**
|
||||
* Types and enums used by filament's driver.
|
||||
*
|
||||
@@ -41,22 +40,24 @@ namespace filament {
|
||||
* internal redeclaration of these types.
|
||||
* For e.g. Use Texture::Sampler instead of filament::SamplerType.
|
||||
*/
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
|
||||
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 16; // Matches the Adreno Vulkan driver.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
|
||||
static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
|
||||
"The number of buffer objects that can be attached to a VertexBuffer must be "
|
||||
"less than or equal to the maximum number of vertex attributes.");
|
||||
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 8;
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 12; // This is guaranteed by OpenGL ES.
|
||||
|
||||
/**
|
||||
* Selects which driver a particular Engine should use.
|
||||
@@ -140,9 +141,9 @@ struct Viewport {
|
||||
uint32_t width; //!< width in pixels
|
||||
uint32_t height; //!< height in pixels
|
||||
//! get the right coordinate in window space of the viewport
|
||||
int32_t right() const noexcept { return left + width; }
|
||||
int32_t right() const noexcept { return left + int32_t(width); }
|
||||
//! get the top coordinate in window space of the viewport
|
||||
int32_t top() const noexcept { return bottom + height; }
|
||||
int32_t top() const noexcept { return bottom + int32_t(height); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -158,7 +159,7 @@ struct DepthRange {
|
||||
* @see Fence, Fence::wait()
|
||||
*/
|
||||
enum class FenceStatus : int8_t {
|
||||
ERROR = -1, //!< An error occured. The Fence condition is not satisfied.
|
||||
ERROR = -1, //!< An error occurred. The Fence condition is not satisfied.
|
||||
CONDITION_SATISFIED = 0, //!< The Fence condition is satisfied.
|
||||
TIMEOUT_EXPIRED = 1, //!< wait()'s timeout expired. The Fence condition is not satisfied.
|
||||
};
|
||||
@@ -167,7 +168,7 @@ enum class FenceStatus : int8_t {
|
||||
* Status codes for sync objects
|
||||
*/
|
||||
enum class SyncStatus : int8_t {
|
||||
ERROR = -1, //!< An error occured. The Sync is not signaled.
|
||||
ERROR = -1, //!< An error occurred. The Sync is not signaled.
|
||||
SIGNALED = 0, //!< The Sync is signaled.
|
||||
NOT_SIGNALED = 1, //!< The Sync is not signaled yet
|
||||
};
|
||||
@@ -638,6 +639,10 @@ enum class TextureCubemapFace : uint8_t {
|
||||
NEGATIVE_Z = 5, //!< -z face
|
||||
};
|
||||
|
||||
inline constexpr int operator +(TextureCubemapFace rhs) noexcept {
|
||||
return int(rhs);
|
||||
}
|
||||
|
||||
//! Face offsets for all faces of a cubemap
|
||||
struct FaceOffsets {
|
||||
using size_type = size_t;
|
||||
@@ -783,7 +788,6 @@ enum class BlendFunction : uint8_t {
|
||||
//! Stream for external textures
|
||||
enum class StreamType {
|
||||
NATIVE, //!< Not synchronized but copy-free. Good for video.
|
||||
TEXTURE_ID, //!< Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26.
|
||||
ACQUIRED, //!< Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+.
|
||||
};
|
||||
|
||||
@@ -809,10 +813,10 @@ using AttributeArray = std::array<Attribute, MAX_VERTEX_ATTRIBUTE_COUNT>;
|
||||
//! Raster state descriptor
|
||||
struct RasterState {
|
||||
|
||||
using CullingMode = CullingMode;
|
||||
using DepthFunc = SamplerCompareFunc;
|
||||
using BlendEquation = BlendEquation;
|
||||
using BlendFunction = BlendFunction;
|
||||
using CullingMode = backend::CullingMode;
|
||||
using DepthFunc = backend::SamplerCompareFunc;
|
||||
using BlendEquation = backend::BlendEquation;
|
||||
using BlendFunction = backend::BlendFunction;
|
||||
|
||||
RasterState() noexcept { // NOLINT
|
||||
static_assert(sizeof(RasterState) == sizeof(uint32_t),
|
||||
@@ -900,6 +904,16 @@ enum ShaderType : uint8_t {
|
||||
};
|
||||
static constexpr size_t PIPELINE_STAGE_COUNT = 2;
|
||||
|
||||
struct ShaderStageFlags {
|
||||
bool vertex : 1;
|
||||
bool fragment : 1;
|
||||
bool hasShaderType(ShaderType type) const {
|
||||
return (vertex && type == ShaderType::VERTEX) ||
|
||||
(fragment && type == ShaderType::FRAGMENT);
|
||||
}
|
||||
};
|
||||
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { true, true };
|
||||
|
||||
/**
|
||||
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
|
||||
* can be discarded at the beginning and end of the render pass.
|
||||
@@ -948,10 +962,20 @@ struct RenderPassParams {
|
||||
* subpass. If this is zero, the render pass has only one subpass. The least significant bit
|
||||
* specifies that the first color attachment in the render target is a subpass input.
|
||||
*
|
||||
* For now only 2 subpasses are supported, so only the lower 4 bits are used, one for each color
|
||||
* attachment (see MRT::TARGET_COUNT).
|
||||
* For now only 2 subpasses are supported, so only the lower 8 bits are used, one for each color
|
||||
* attachment (see MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT).
|
||||
*/
|
||||
uint32_t subpassMask = 0;
|
||||
uint16_t subpassMask = 0;
|
||||
|
||||
/**
|
||||
* This mask makes a promise to the backend about read-only usage of the depth attachment (bit
|
||||
* 0) and the stencil attachment (bit 1). Some backends need to know if writes are disabled in
|
||||
* order to allow sampling from the depth attachment.
|
||||
*/
|
||||
uint16_t readOnlyDepthStencil = 0;
|
||||
|
||||
static constexpr uint16_t READONLY_DEPTH = 1 << 0;
|
||||
static constexpr uint16_t READONLY_STENCIL = 1 << 1;
|
||||
};
|
||||
|
||||
struct PolygonOffset {
|
||||
@@ -965,11 +989,14 @@ using FrameScheduledCallback = void(*)(PresentCallable callable, void* user);
|
||||
using FrameCompletedCallback = void(*)(void* user);
|
||||
|
||||
enum class Workaround : uint16_t {
|
||||
SPLIT_EASU
|
||||
// The EASU pass must split because shader compiler flattens early-exit branch
|
||||
SPLIT_EASU,
|
||||
// Backend allows feedback loop with ancillary buffers (depth/stencil) as long as they're read-only for
|
||||
// the whole render pass.
|
||||
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
template<> struct utils::EnableBitMaskOperators<filament::backend::TargetBufferFlags>
|
||||
: public std::true_type {};
|
||||
@@ -1006,6 +1033,7 @@ utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend:
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RasterState& rs);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RenderPassParams& b);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::Viewport& v);
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::ShaderStageFlags stageFlags);
|
||||
#endif
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_DRIVERENUMS_H
|
||||
|
||||
@@ -18,13 +18,16 @@
|
||||
#define TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#if !defined(NDEBUG)
|
||||
#include <utils/Log.h>
|
||||
#endif
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
struct HwBufferObject;
|
||||
struct HwFence;
|
||||
@@ -41,7 +44,9 @@ struct HwTimerQuery;
|
||||
struct HwVertexBuffer;
|
||||
|
||||
/*
|
||||
* A type handle to a h/w resource
|
||||
* A handle to a backend resource. HandleBase is for internal use only.
|
||||
* HandleBase *must* be a trivial for the purposes of calls, that is, it cannot have user-defined
|
||||
* copy or move constructors.
|
||||
*/
|
||||
|
||||
//! \privatesection
|
||||
@@ -53,41 +58,54 @@ public:
|
||||
|
||||
constexpr HandleBase() noexcept: object(nullid) {}
|
||||
|
||||
explicit HandleBase(HandleId id) noexcept : object(id) {
|
||||
assert_invariant(object != nullid); // usually means an uninitialized handle is used
|
||||
}
|
||||
|
||||
HandleBase(HandleBase const& rhs) noexcept = default;
|
||||
HandleBase(HandleBase&& rhs) noexcept : object(rhs.object) {
|
||||
rhs.object = nullid;
|
||||
}
|
||||
|
||||
HandleBase& operator=(HandleBase const& rhs) noexcept = default;
|
||||
HandleBase& operator=(HandleBase&& rhs) noexcept {
|
||||
std::swap(object, rhs.object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// whether this Handle is initialized
|
||||
explicit operator bool() const noexcept { return object != nullid; }
|
||||
|
||||
// clear the handle, this doesn't free associated resources
|
||||
void clear() noexcept { object = nullid; }
|
||||
|
||||
// compare handles
|
||||
bool operator==(const HandleBase& rhs) const noexcept { return object == rhs.object; }
|
||||
bool operator!=(const HandleBase& rhs) const noexcept { return object != rhs.object; }
|
||||
bool operator<(const HandleBase& rhs) const noexcept { return object < rhs.object; }
|
||||
bool operator<=(const HandleBase& rhs) const noexcept { return object <= rhs.object; }
|
||||
bool operator>(const HandleBase& rhs) const noexcept { return object > rhs.object; }
|
||||
bool operator>=(const HandleBase& rhs) const noexcept { return object >= rhs.object; }
|
||||
|
||||
// get this handle's handleId
|
||||
HandleId getId() const noexcept { return object; }
|
||||
|
||||
// initialize a handle, for internal use only.
|
||||
explicit HandleBase(HandleId id) noexcept : object(id) {
|
||||
assert_invariant(object != nullid); // usually means an uninitialized handle is used
|
||||
}
|
||||
|
||||
protected:
|
||||
HandleBase(HandleBase const& rhs) noexcept = default;
|
||||
HandleBase& operator=(HandleBase const& rhs) noexcept = default;
|
||||
|
||||
private:
|
||||
HandleId object;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
/**
|
||||
* Type-safe handle to backend resources
|
||||
* @tparam T Type of the resource
|
||||
*/
|
||||
template<typename T>
|
||||
struct Handle : public HandleBase {
|
||||
using HandleBase::HandleBase;
|
||||
|
||||
Handle() noexcept = default;
|
||||
|
||||
Handle(Handle const& rhs) noexcept = default;
|
||||
|
||||
Handle& operator=(Handle const& rhs) noexcept = default;
|
||||
|
||||
explicit Handle(HandleId id) noexcept : HandleBase(id) { }
|
||||
|
||||
// type-safe Handle cast
|
||||
template<typename B, typename = std::enable_if_t<std::is_base_of<T, B>::value> >
|
||||
Handle(Handle<B> const& base) noexcept : HandleBase(base) { } // NOLINT(hicpp-explicit-conversions)
|
||||
Handle(Handle<B> const& base) noexcept : HandleBase(base) { } // NOLINT(hicpp-explicit-conversions,google-explicit-constructor)
|
||||
|
||||
private:
|
||||
#if !defined(NDEBUG)
|
||||
@@ -112,7 +130,6 @@ using TextureHandle = Handle<HwTexture>;
|
||||
using TimerQueryHandle = Handle<HwTimerQuery>;
|
||||
using VertexBufferHandle = Handle<HwVertexBuffer>;
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
* underlying platform is returned and \p backendHint is updated
|
||||
* accordingly. Can't be nullptr.
|
||||
*
|
||||
* @return A pointer to the Plaform object.
|
||||
* @return A pointer to the Platform object.
|
||||
*
|
||||
* @see destroy
|
||||
*/
|
||||
|
||||
@@ -22,38 +22,19 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
//! \privatesection
|
||||
|
||||
class TargetBufferInfo {
|
||||
public:
|
||||
// ctor for 2D textures
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level = 0) noexcept // NOLINT(google-explicit-constructor)
|
||||
: handle(h), level(level) { }
|
||||
// ctor for cubemaps
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level, TextureCubemapFace face) noexcept
|
||||
: handle(h), level(level), face(face) { }
|
||||
// ctor for 3D textures
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level, uint16_t layer) noexcept
|
||||
: handle(h), level(level), layer(layer) { }
|
||||
|
||||
explicit TargetBufferInfo(TextureCubemapFace face) noexcept : face(face) {}
|
||||
|
||||
explicit TargetBufferInfo(uint16_t layer) noexcept : layer(layer) {}
|
||||
|
||||
struct TargetBufferInfo {
|
||||
// texture to be used as render target
|
||||
Handle<HwTexture> handle;
|
||||
|
||||
// level to be used
|
||||
uint8_t level = 0;
|
||||
union {
|
||||
// face if texture is a cubemap
|
||||
TextureCubemapFace face;
|
||||
// for 3D textures
|
||||
uint16_t layer = 0;
|
||||
};
|
||||
TargetBufferInfo() noexcept { }
|
||||
|
||||
// for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping
|
||||
uint16_t layer = 0;
|
||||
};
|
||||
|
||||
class MRT {
|
||||
@@ -96,13 +77,12 @@ public:
|
||||
}
|
||||
|
||||
// this is here for backward compatibility
|
||||
MRT(Handle<HwTexture> h, uint8_t level, uint16_t layer) noexcept
|
||||
: mInfos{{ h, level, layer }} {
|
||||
MRT(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
|
||||
: mInfos{{ handle, level, layer }} {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::TargetBufferInfo& tbi);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include <utility>
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
@@ -20,64 +18,35 @@
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
|
||||
|
||||
#include "private/backend/CircularBuffer.h"
|
||||
#include "private/backend/Dispatcher.h"
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PipelineState.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include <backend/PresentCallable.h>
|
||||
#include <backend/TargetBufferInfo.h>
|
||||
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
// FIXME: we'd like to not need this header here.
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ThreadUtils.h>
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Set to true to print every commands out on log.d. This requires RTTI and DEBUG
|
||||
// Set to true to print every command out on log.d. This requires RTTI and DEBUG
|
||||
#define DEBUG_COMMAND_STREAM false
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
class Driver;
|
||||
class CommandBase;
|
||||
|
||||
/*
|
||||
* Dispatcher is a data structure containing only function pointers.
|
||||
* Each function pointer targets code that unpacks the arguments to the driver's method and
|
||||
* calls it.
|
||||
*
|
||||
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
|
||||
* can be made before that.
|
||||
*
|
||||
* When a command is inserted into the stream, the corresponding function pointer is copied
|
||||
* directly into CommandBase from Dispatcher.
|
||||
*/
|
||||
class Dispatcher {
|
||||
public:
|
||||
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
|
||||
#include "DriverAPI.inc"
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace filament::backend {
|
||||
|
||||
class CommandBase {
|
||||
static constexpr size_t FILAMENT_OBJECT_ALIGNMENT = alignof(std::max_align_t);
|
||||
@@ -95,8 +64,10 @@ public:
|
||||
|
||||
// executes this command and returns the next one
|
||||
inline CommandBase* execute(Driver& driver) {
|
||||
// it is important to return the next command offset by output parameter instead
|
||||
// of return value -- it allows the compiler to perform the tail call optimization.
|
||||
// returning the next command by output parameter allows the compiler to perform the
|
||||
// tail-call optimization in the function called by mExecute, however that comes at
|
||||
// a cost here (writing and reading the stack at each iteration), in the end it's
|
||||
// probably better to pay the cost at just one location.
|
||||
intptr_t next;
|
||||
mExecute(driver, this, &next);
|
||||
return reinterpret_cast<CommandBase*>(reinterpret_cast<intptr_t>(this) + next);
|
||||
@@ -131,7 +102,7 @@ constexpr decltype(auto) apply(M&& m, D&& d, T&& t) {
|
||||
/*
|
||||
* CommandType<> is just a wrapper class to specialize on a pointer-to-member of Driver
|
||||
* (i.e. a method pointer to a method of Driver of a particular type -- but not the
|
||||
* method itself). We only do that so we can identify the parameters of that method.
|
||||
* method itself). We only do that, so we can identify the parameters of that method.
|
||||
* We won't call through that pointer though.
|
||||
*/
|
||||
template<typename... ARGS>
|
||||
@@ -207,7 +178,7 @@ class NoopCommand : public CommandBase {
|
||||
}
|
||||
public:
|
||||
inline constexpr explicit NoopCommand(void* next) noexcept
|
||||
: CommandBase(execute), mNext(size_t((char *)next - (char *)this)) { }
|
||||
: CommandBase(execute), mNext(intptr_t((char *)next - (char *)this)) { }
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -215,41 +186,34 @@ public:
|
||||
#if !defined(NDEBUG) || (FILAMENT_DEBUG_COMMANDS >= FILAMENT_DEBUG_COMMANDS_ENABLE)
|
||||
// For now, simply pass the method name down as a string and throw away the parameters.
|
||||
// This is good enough for certain debugging needs and we can improve this later.
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver->debugCommandBegin(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_END(methodName, sync) mDriver->debugCommandEnd(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...) mDriver.debugCommandBegin(this, sync, #methodName)
|
||||
#define DEBUG_COMMAND_END(methodName, sync) mDriver.debugCommandEnd(this, sync, #methodName)
|
||||
#else
|
||||
#define DEBUG_COMMAND_BEGIN(methodName, sync, ...)
|
||||
#define DEBUG_COMMAND_END(methodName, sync)
|
||||
#endif
|
||||
|
||||
class CommandStream {
|
||||
// Dispatcher could be a value (instead of pointer), which saves a load when writing commands
|
||||
// at the expense of a larger CommandStream object (about ~400 bytes)
|
||||
Dispatcher* mDispatcher = nullptr;
|
||||
Driver* mDriver = nullptr;
|
||||
CircularBuffer* UTILS_RESTRICT mCurrentBuffer = nullptr;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// just for debugging...
|
||||
std::thread::id mThreadId{};
|
||||
#endif
|
||||
|
||||
bool mUsePerformanceCounter = false;
|
||||
|
||||
template<typename T>
|
||||
struct AutoExecute {
|
||||
T closure;
|
||||
inline AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
|
||||
inline explicit AutoExecute(T&& closure) : closure(std::forward<T>(closure)) {}
|
||||
inline ~AutoExecute() { closure(); }
|
||||
};
|
||||
|
||||
public:
|
||||
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
|
||||
|
||||
CommandStream(CommandStream const& rhs) noexcept = delete;
|
||||
CommandStream& operator=(CommandStream const& rhs) noexcept = delete;
|
||||
|
||||
public:
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
|
||||
inline void methodName(paramsDecl) { \
|
||||
DEBUG_COMMAND_BEGIN(methodName, false, params); \
|
||||
using Cmd = COMMAND_TYPE(methodName); \
|
||||
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
|
||||
new(p) Cmd(mDispatcher->methodName##_, APPLY(std::move, params)); \
|
||||
new(p) Cmd(mDispatcher.methodName##_, APPLY(std::move, params)); \
|
||||
DEBUG_COMMAND_END(methodName, false); \
|
||||
}
|
||||
|
||||
@@ -259,16 +223,16 @@ public:
|
||||
AutoExecute callOnExit([=](){ \
|
||||
DEBUG_COMMAND_END(methodName, true); \
|
||||
}); \
|
||||
return apply(&Driver::methodName, *mDriver, std::forward_as_tuple(params)); \
|
||||
return apply(&Driver::methodName, mDriver, std::forward_as_tuple(params)); \
|
||||
}
|
||||
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
|
||||
inline RetType methodName(paramsDecl) { \
|
||||
DEBUG_COMMAND_BEGIN(methodName, false, params); \
|
||||
RetType result = mDriver->methodName##S(); \
|
||||
RetType result = mDriver.methodName##S(); \
|
||||
using Cmd = COMMAND_TYPE(methodName##R); \
|
||||
void* const p = allocateCommand(CommandBase::align(sizeof(Cmd))); \
|
||||
new(p) Cmd(mDispatcher->methodName##_, RetType(result), APPLY(std::move, params)); \
|
||||
new(p) Cmd(mDispatcher.methodName##_, RetType(result), APPLY(std::move, params)); \
|
||||
DEBUG_COMMAND_END(methodName, false); \
|
||||
return result; \
|
||||
}
|
||||
@@ -276,15 +240,12 @@ public:
|
||||
#include "DriverAPI.inc"
|
||||
|
||||
public:
|
||||
CommandStream() noexcept = default;
|
||||
CommandStream(Driver& driver, CircularBuffer& buffer) noexcept;
|
||||
|
||||
// This is for debugging only. Currently CircularBuffer can only be written from a
|
||||
// This is for debugging only. Currently, CircularBuffer can only be written from a
|
||||
// single thread. In debug builds we assert this condition.
|
||||
// Call this first in the render loop.
|
||||
inline void debugThreading() noexcept {
|
||||
#ifndef NDEBUG
|
||||
mThreadId = std::this_thread::get_id();
|
||||
mThreadId = utils::ThreadUtils::getThreadId();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -313,9 +274,22 @@ public:
|
||||
|
||||
private:
|
||||
inline void* allocateCommand(size_t size) {
|
||||
assert_invariant(mThreadId == std::this_thread::get_id());
|
||||
return mCurrentBuffer->allocate(size);
|
||||
assert_invariant(utils::ThreadUtils::isThisThread(mThreadId));
|
||||
return mCurrentBuffer.allocate(size);
|
||||
}
|
||||
|
||||
// We use a copy of Dispatcher (instead of a pointer) because this removes one dereference
|
||||
// when executing driver commands.
|
||||
Driver& UTILS_RESTRICT mDriver;
|
||||
CircularBuffer& UTILS_RESTRICT mCurrentBuffer;
|
||||
Dispatcher mDispatcher;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// just for debugging...
|
||||
std::thread::id mThreadId{};
|
||||
#endif
|
||||
|
||||
bool mUsePerformanceCounter = false;
|
||||
};
|
||||
|
||||
void* CommandStream::allocate(size_t size, size_t alignment) noexcept {
|
||||
@@ -340,7 +314,6 @@ PodType* CommandStream::allocatePod(size_t count, size_t alignment) noexcept {
|
||||
return static_cast<PodType*>(allocate(count * sizeof(PodType), alignment));
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_COMMANDSTREAM_H
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Driver;
|
||||
class CommandBase;
|
||||
|
||||
/*
|
||||
* Dispatcher is a data structure containing only function pointers.
|
||||
* Each function pointer targets code that unpacks the arguments to the driver's method and
|
||||
* calls it.
|
||||
*
|
||||
* Dispatcher's function pointers are populated during initialization and no CommandStream calls
|
||||
* can be made before that.
|
||||
*
|
||||
* When a command is inserted into the stream, the corresponding function pointer is copied
|
||||
* directly into CommandBase from Dispatcher.
|
||||
*/
|
||||
class Dispatcher {
|
||||
public:
|
||||
using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
|
||||
#define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params)
|
||||
#define DECL_DRIVER_API(methodName, paramsDecl, params) Execute methodName##_;
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) Execute methodName##_;
|
||||
|
||||
#include "DriverAPI.inc"
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif //TNT_FILAMENT_BACKEND_PRIVATE_DISPATCHER_H
|
||||
@@ -17,23 +17,14 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/CallbackHandler.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PipelineState.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
#include <backend/PresentCallable.h>
|
||||
#include <backend/TargetBufferInfo.h>
|
||||
|
||||
#include "private/backend/DriverApiForward.h"
|
||||
#include "private/backend/Program.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -49,8 +40,13 @@
|
||||
|
||||
#define FILAMENT_DEBUG_COMMANDS FILAMENT_DEBUG_COMMANDS_NONE
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
class BufferDescriptor;
|
||||
class CallbackHandler;
|
||||
class PixelBufferDescriptor;
|
||||
class Program;
|
||||
class SamplerGroup;
|
||||
|
||||
template<typename T>
|
||||
class ConcreteDispatcher;
|
||||
@@ -59,27 +55,32 @@ class CommandStream;
|
||||
|
||||
class Driver {
|
||||
public:
|
||||
static size_t getElementTypeSize(ElementType type) noexcept;
|
||||
|
||||
virtual ~Driver() noexcept;
|
||||
|
||||
static size_t getElementTypeSize(ElementType type) noexcept;
|
||||
|
||||
// called from the main thread (NOT the render-thread) at various intervals, this
|
||||
// is where the driver can execute user callbacks.
|
||||
virtual void purge() noexcept = 0;
|
||||
|
||||
virtual ShaderModel getShaderModel() const noexcept = 0;
|
||||
|
||||
virtual Dispatcher& getDispatcher() noexcept = 0;
|
||||
// Returns the dispatcher. This is only called once during initialization of the CommandStream,
|
||||
// so it doesn't matter that it's virtual.
|
||||
virtual Dispatcher getDispatcher() const noexcept = 0;
|
||||
|
||||
// called from CommandStream::execute on the render-thread
|
||||
// the fn function will execute a batch of driver commands
|
||||
// this gives the driver a chance to wrap their execution in a meaningful manner
|
||||
// the default implementation simply calls fn
|
||||
virtual void execute(std::function<void(void)> fn) noexcept;
|
||||
virtual void execute(std::function<void(void)> const& fn) noexcept;
|
||||
|
||||
// This is called on debug build, or when enabled manually on the backend thread side.
|
||||
virtual void debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
|
||||
virtual void debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept = 0;
|
||||
virtual void debugCommandBegin(CommandStream* cmds,
|
||||
bool synchronous, const char* methodName) noexcept = 0;
|
||||
|
||||
virtual void debugCommandEnd(CommandStream* cmds,
|
||||
bool synchronous, const char* methodName) noexcept = 0;
|
||||
|
||||
/*
|
||||
* Asynchronous calls here only to provide a type to CommandStream. They must be non-virtual
|
||||
@@ -101,7 +102,6 @@ public:
|
||||
#include "private/backend/DriverAPI.inc"
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user