Compare commits

..
1245 Commits
Author SHA1 Message Date
Benjamin Doherty b19a73cc50 Merge branch 'rc/1.17.0' into release 2022-01-24 12:50:22 -08:00
Benjamin Doherty a99c695932 Update RELEASE_NOTES for 1.17.0 2022-01-24 12:45:05 -08:00
Benjamin Doherty 8cd720b53a Bump version to 1.17.0 2022-01-18 13:54:40 -08:00
Benjamin Doherty 04df79e58f Merge branch 'rc/1.16.1' into release 2022-01-18 13:53:02 -08:00
Benjamin Doherty a8d72bb226 Release Filament 1.16.1 2022-01-18 13:52:08 -08:00
Benjamin Doherty a4b3717762 Update RELEASE_NOTES for 1.16.1 2022-01-18 13:48:36 -08:00
Ben Doherty bf3f7e0aef Fix, assertion with shadowReceiver = false and VSM (#5055) 2022-01-18 13:44:48 -08:00
Mathias Agopian 0fb04c576d improve structure pass performance when not used
Move the command generation of the structure pass into its execute 
block, meaning that if the structure pass is culled, the command 
generation is now skipped too.
2022-01-18 12:21:36 -08:00
Mathias Agopian caaa404d96 add basic support for Android Thermal Manager 2022-01-18 11:37:26 -08:00
daemyung jang 2fa6e6d031 Remove an useless log 2022-01-18 10:35:39 -08:00
daemyung jang 62bb25b26d Fix, potential null dereferences in OpenGLProgram
Morphing is enabled but no morph targets in some models.
2022-01-18 10:35:39 -08:00
Mathias Agopian 8d1402d37b Bring back the 3x3 filter for PCF shadows
The same can be achieved with VSM + blur=3 however, this is noticeably
slower. Also when using transparent shadows, VSM needs a much larger
blur to iron out the dithering pattern.

Fixes #5048, #5039
2022-01-14 15:08:46 -08:00
Ben Doherty afd657d6af Fix, incorrect refractions with screen-space reflections disabled (#5051) 2022-01-13 16:54:47 -08:00
Romain Guy 27a5158147 Update tone mapping operators notebook 2022-01-13 15:38:19 -08:00
Mathias Agopian dead7ab2ac Use NDK29 new (and experimental) way to access NDK functions
This uses compile time guarded calls to weak symbols, and allows us to
call NDK APIs without having to dlsym() them.
2022-01-13 15:20:26 -08:00
Mathias Agopian 352acff396 improve documentation regarding post-processing and render targets
Fixes #5015
2022-01-13 09:59:58 -08:00
Ben Doherty 00d9c6921d Add initial glossy screen-space reflections (#4946) 2022-01-12 13:59:11 -08:00
daemyung jang 6805940bbf Compute morphing on GPU (#4999) 2022-01-12 11:06:47 -08:00
Romain Guy 954f9112e4 Replace generic tonemap curve with a simpler one (#5041)
* Replace generic tonemap curve with a simpler one

This change removes the shoulder parameter which had inconsistent
behaviors. The new curve is simpler and designed to still match
by default the gray point and the contrast of ACES in a bright
surround.

* Fix build
2022-01-12 09:55:35 -08:00
hzzengxiaoqi 6465b9ade8 fix bug of GLTFIO_LITE, the macro GLTFRESOURCES_LITE_LIT_BLEND_DATA is not defined anywhere, it should be GLTFRESOURCES_LITE_LIT_FADE_DATA. This solves the issue of rendering transparent objects using GLTFIO_LITE macro, i.e. using gltfresources_lite.bin. If not change this macro, the transparent objects will be rended using LIT_OPAQUE material instead of LIT_FADE material. 2022-01-11 10:31:49 -08:00
Jared Fowler b67963176b Moving UiHelper to the constructor which allows for more composable control of the underlying views & surface 2022-01-11 08:56:42 -08:00
Ankbzpx fb1eb35ba5 Fix aabb misalignment for skinned gltf model (#4973) 2022-01-10 15:06:23 -08:00
Mathias Agopian 047543a4a6 make our ostream thread safe
ostream internals are now protected by a lock, which ensures the
internal state stays consistant, however, this won't prevent 
multiple threads to have their output ominterfering with each other,
which is no different from the stl behavior.


This fixes #4992
2022-01-10 15:04:26 -08:00
Mathias Agopian 5e0615040d refactor our ostream
The main change here is that we factorize all the interesting code in
a single function. This should result in smaller code.
2022-01-10 15:04:26 -08:00
Mathias Agopian 1ceed1519b attempt to fix compilation failure with gcc
fix #4990
2022-01-10 15:04:09 -08:00
Benjamin Doherty 1035e442ee Bump version to 1.16.1 2022-01-10 10:47:46 -08:00
Benjamin Doherty 60d3638f15 Merge branch 'rc/1.16.0' into release 2022-01-10 10:44:36 -08:00
Benjamin Doherty a1a3adf8af Release Filament 1.16.0 2022-01-10 10:43:35 -08:00
Benjamin Doherty 3e7d3c9035 Update RELEASE_NOTES for 1.16.0 2022-01-10 10:41:14 -08:00
jeanlemotan eb360be2ad Fixed cubemap update 2022-01-10 10:34:49 -08:00
Ben Doherty 620a693c11 FilamentApp: use PrtScn key to capture debug frame (#5032) 2022-01-10 10:28:34 -08:00
jeanlemotan 4511af6f9e Removed code duplication, better style. 2022-01-08 06:17:56 -08:00
jeanlemotan 214e54f2ad Make sure the width/height don't reach zero. 2022-01-08 06:17:56 -08:00
jeanlemotan 2eefbe11ae Fixed cubemap update 2022-01-08 06:17:56 -08:00
Mathias Agopian 74ea3d50c2 Make sure to object are aligned properly when allocated in the renderstream
fix #4991
2022-01-07 10:49:12 -08:00
jeanlemotan 9a8159ab04 Fixed compiler warning (int -> float conversion) 2022-01-07 10:17:04 -08:00
Ben Doherty 2f3aac29da Enable GL_ARB_shading_language_packing in vertex shaders (#5022) 2022-01-06 13:17:31 -08:00
jeanlemotan 9d7f5f593e Added line/triangle strip support (#5017)
* Added line/triangle strip support

* Added strip support for Java and JS
Changed README to indicate strip support for gltf
2022-01-06 13:07:32 -08:00
Ben Doherty 2596273a94 Avoid calling std::string(nullptr) in MockConfig.cpp (#5019) 2022-01-06 10:52:01 -08:00
Benjamin Doherty 210a8c2260 Update Renderer comment 2022-01-06 10:47:54 -08:00
Benjamin Doherty 485ac8704d Bump version to 1.16.0 2022-01-04 11:55:19 -08:00
Benjamin Doherty dc74540423 Merge branch 'rc/1.15.2' into release 2022-01-04 11:53:02 -08:00
Benjamin Doherty eaefaf8e59 Release Filament 1.15.2 2022-01-04 11:52:31 -08:00
Benjamin Doherty 96219c22db Update RELEASE_NOTES for 1.15.2 2022-01-04 11:49:50 -08:00
Romain Guy f3b7048775 Add missing JNI impl (#4959) 2022-01-04 11:43:19 -08:00
Romain Guy aaed6fb376 Fix rounding math 2022-01-04 11:43:13 -08:00
Ben Doherty 7873e6f5aa Metal: clamp readPixels width and height to texture dimensions (#4994) 2021-12-28 10:27:11 -07:00
abwood 251abf0545 Add support for the glTF extension KHR_materials_emissive_strength (#4975) 2021-12-23 01:32:45 -08:00
Mathias Agopian b5c4b30ff6 Fix a double release with Android bitmaps callbacks
The version of Texture::setBitmap() that tool an Android bitmap handled
callbacks differently and in certain case caused a "double release" of
the callback object. This didn't actually cause problems though.

We now use the same mechanism used elsewhere (i.e. JniCallback).
2021-12-15 09:18:23 -08:00
Mathias Agopian eb941a0868 Make normal skinning more efficient
With this change the cofactor matrix is partially precomputed on the 
CPU side.
2021-12-14 10:00:10 -08:00
Mathias Agopian 304ffe0049 Fix skinning calculations
it was incorrect to store bone matrices as quaternions because it is
allowed for these matrices to have a skew component.

We now store the 4x4 matrix -- which is the same amount of data as
before, however we compute the cofactor matrix in the vertex shader when
transforming normals.

fixes #4887
2021-12-14 10:00:10 -08:00
Mathias Agopian 88edbc7df8 Fix a java global reference leak
We were acquiring a reference twice by accident.

Fix #4957
2021-12-13 15:16:48 -08:00
Mathias Agopian 6fa82ea73d Fix typo when setting cubemap faces mip levels. 2021-12-13 15:16:33 -08:00
Mathias Agopian 92e7ff3de7 fix debug checks for compressed textures
Fixes #4941
2021-12-13 15:16:33 -08:00
Romain Guy 35a5d3310f Fix preprocessor test 2021-12-13 13:53:20 -07:00
Romain Guy 2739eb146a Fix rounding math 2021-12-13 10:54:31 -08:00
Romain Guy 59ccc3021f Add missing JNI impl (#4959) 2021-12-13 10:52:47 -08:00
Romain Guy 36e9fa42f4 Fix preprocessor test 2021-12-13 10:42:07 -08:00
Benjamin Doherty 9da79a1d2d Bump version to 1.15.2 2021-12-13 11:08:28 -07:00
Benjamin Doherty 595b355d1b Merge branch 'rc/1.15.1' into release 2021-12-13 11:06:45 -07:00
Benjamin Doherty 8111c50a5a Release Filament 1.15.1 2021-12-13 11:06:12 -07:00
Romain Guy 0e5e7e940c Fix typo in JNI binding 2021-12-10 08:35:16 -08:00
Ben Doherty 9f75d34bb8 Rework color history in preparation for SSR (#4932) 2021-12-08 13:35:54 -08:00
Mathias Agopian df42213daf update remote ui 2021-12-08 00:25:25 -06:00
Mathias Agopian b73caceb1f fix libibl on mobile
- the hammersley sequence was completely wrong because of a missing
  highp precision qualifier

- roughness 0 was also wrong because of divide-by-0

Fixes #4668
2021-12-08 00:17:29 -06:00
Mathias Agopian c91f28b6be fix remote UI when dropping a new .hdr ibl file
- the ibl wasn't updated in internal structures
- the previous ibl was leaked
2021-12-08 00:17:29 -06:00
Mathias Agopian 078de4e422 Add support for basic PCSS 2021-12-08 00:17:12 -06:00
Romain Guy 332d5681e6 Update dependencies 2021-12-07 09:34:28 -08:00
Benjamin Doherty 3a67d769f4 Update RELEASE_NOTES for 1.15.1 2021-12-06 16:54:28 -08:00
Romain Guy de1281dd9f Be more specific about anisotropyDirection 2021-12-06 15:37:41 -08:00
Benjamin Doherty f3849a1f57 Update web docs for 1.15.0 2021-12-06 12:59:23 -08:00
Mathias Agopian 3fd63b1b3d use the correct normal when calculating spotlight bias
`vertex_worldNormal` should never be used directly, for one thing it's
not guaranteed to be normalized.
2021-12-06 14:11:45 -06:00
Benjamin Doherty 6fb536a937 Bump version to 1.15.1 2021-12-06 11:17:37 -08:00
Benjamin Doherty bb460d78d8 Merge branch 'rc/1.15.0' into release 2021-12-06 11:14:00 -08:00
Benjamin Doherty 3a33220dad Release Filament 1.15.0 2021-12-06 11:12:58 -08:00
Mathias Agopian 09a9deafc0 Fade lights out when close to light far plane
the fade takes place over 10% of the light far distance.
2021-12-06 11:45:15 -06:00
Mathias Agopian 4de3470de5 remove 'exponent' from VsmShadowOptions
this is an internal parameter and has no reason to be user settable.
2021-12-03 14:45:59 -06:00
Romain Guy f03d654862 Update README.md 2021-12-03 09:28:02 -08:00
Mathias Agopian b8a39c2f3d disable workaround on recent adreno drivers
A workaround for the tile load/store is no longer needed on recent
version of the GLES3.x drivers on qualcomm SoC.
2021-12-03 11:25:38 -06:00
Romain Guy 291b5dcec5 Update README.md 2021-12-02 23:36:57 -08:00
Mathias Agopian 087f29c6c9 Added support for DPCF 2021-12-03 01:20:50 -06:00
Mathias Agopian aac3ac579c add global temporal noise uniform when TAA is enabled
this can be used to easily add temporal noise to "things" when
TAA is also enabled.
2021-12-03 01:20:50 -06:00
Benjamin Doherty 838835a715 Update RELEASE_NOTES for 1.15.0 2021-12-02 11:52:04 -08:00
Romain Guy c275f61aeb Add missing destroy method (#4921) 2021-12-02 08:53:55 -08:00
MasTraER f297948216 Expose Engine::destroy(SkinningBuffer*) (#4919) 2021-12-02 08:41:10 -08:00
Ben Doherty dbe1386785 Fix live wallpaper sample with Android 12+ (#4917) 2021-12-01 12:29:11 -08:00
Joel Winarske 687f4aff13 Flags to support embedded Linux (#4911)
- FILAMENT_SKIP_SDL2=ON is used to  skip dependencies of sdl2 and sdl2 CMake

- FILAMENT_LINUX_IS_MOBILE is used for Mobile build

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-12-01 08:31:06 -08:00
Romain Guy dd4853bcc5 Replace ANDROID with __ANDROID__ (#4909)
__ANDROID__ is always set by the toolchain and less likely to cause
conflicts than ANDROID. This change also removes the -DANDROID flag
we set ourselves in our toolchain CMake files since we don't need
it anymore.
2021-11-30 16:27:56 -08:00
Benjamin Doherty ffbfc13530 Fix RELEASE_NOTES 2021-11-30 15:52:17 -08:00
Ben Doherty 2aa160a98c Fix release build crash in gltf_viewer (#4908) 2021-11-30 12:29:45 -08:00
Ben Doherty 477a3a8771 Pin web docs Filament version (#4907) 2021-11-30 12:05:40 -08:00
Romain Guy 63acd53e23 Use __ANDROID__ instead of ANDROID 2021-11-30 11:15:49 -08:00
Romain Guy fcd2d0457b Workaround for a build system issue 2021-11-30 11:15:42 -08:00
Romain Guy c0e8686297 Use __ANDROID__ instead of ANDROID 2021-11-30 11:14:35 -08:00
Romain Guy 01f18caf53 Workaround for a build system issue 2021-11-30 10:05:32 -08:00
Joel Winarske 56971520a2 Fix typo and remove extraneous return
Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-11-30 11:18:57 -06:00
Joel Winarske f5e38b1198 Requested changes
- remove const

- remove egl references in wayland struct

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-11-30 11:18:57 -06:00
Joel Winarske 984ef2a089 Remove un-implemented test case
Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-11-30 11:18:57 -06:00
Joel Winarske ad960c73b6 Remove traces of Wayland EGL
Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-11-30 11:18:57 -06:00
Joel Winarske 0dcc631aa8 Backout Wayland EGL backend
Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2021-11-30 11:18:57 -06:00
Joel Winarske af9b670cfd Wayland 2021-11-30 11:18:57 -06:00
Benjamin Doherty 58fc26461b Bump version to 1.15.0 2021-11-29 14:08:28 -08:00
Benjamin Doherty fd82f6b04e Merge branch 'rc/1.14.2' into release 2021-11-29 14:07:03 -08:00
Benjamin Doherty 519ae4d143 Release Filament 1.14.2 2021-11-29 14:05:55 -08:00
Mathias Agopian 8d72869437 Fix spotlight normal bias calculation (#4844)
The calculation was completely wrong due to several typos more or less
canceling each other, that led to some misunderstanding!
2021-11-29 14:05:40 -08:00
Romain Guy 2cbacb532a Cache calls to Enum.values() (#4902)
Each call to .values() allocates a new array. Let's cache them once
and for all to avoid unncessary allocations.
2021-11-29 11:35:58 -08:00
Romain Guy 1da2bf2f7a Update WebGl demos 2021-11-29 11:29:22 -08:00
Benjamin Doherty cef3200533 Add additional RELEASE_NOTES for 1.14.2 2021-11-29 10:21:56 -08:00
Ben Doherty 634500c398 Fix, avoid divide-by-zero inside makeBone (#4889) 2021-11-24 16:29:33 -08:00
Ben Doherty 802bc7a5dc Fix, avoid divide-by-zero inside makeBone (#4889) 2021-11-24 16:28:44 -08:00
Romain Guy 8875806c5d Use locale-independent string->float conversion (#4885)
* Use locale-independent string->float conversion

strtof and friends are locale aware and won't parse decimal numbers
with a period ("12.6" for instance) in locales that use another
character for the decimal period ("," in French for instance).

This change introduces a new function called strtof_c that forces
the use of a specific locale (called "C") to make sure we always
parse floats in the desired "C" format ("12.6").

With C++17 we should be able to use std::from_chars but this API
is not implemented in clang for floats at the moment.

* Fix Linux
2021-11-23 12:32:54 -08:00
Benjamin Doherty c9df807f1f Update backend-test project with filamat dependency 2021-11-23 12:14:05 -08:00
Ben Doherty b3e294ac54 Fix Metal depth comparison initialization (#4886) 2021-11-23 12:09:43 -08:00
Ben Doherty 3feef4e84b Fix Metal depth comparison initialization (#4886) 2021-11-23 12:00:58 -08:00
Benjamin Doherty 2bf7535ad0 Update RELEASE_NOTES for 1.14.2 2021-11-22 10:16:00 -08:00
Benjamin Doherty 3315f75de9 Bump version to 1.14.2 2021-11-22 10:12:44 -08:00
Benjamin Doherty bbe7dbfa92 Merge branch 'rc/1.14.1' into release 2021-11-22 10:11:06 -08:00
Benjamin Doherty 15001524bd Release Filament 1.14.1 2021-11-22 10:10:35 -08:00
Romain Guy c1713e7501 Export activities on Android 12+ 2021-11-22 09:25:13 -08:00
Romain Guy 0181584735 Update build tools (#4866)
* Update build tools

SDK API level 31
NDK 23
Kotlin 1.6

* Preserve tool suffix for Windows
2021-11-17 13:19:45 -08:00
Ben Doherty df06e8dc41 Fix material compilation error with device vertex domain (#4865)
A recent refactor was causing the following error when the vertex domain
was set to `device`:
```
ERROR: main.vs:23: 'material' : undeclared identifier
ERROR: main.vs:23: 'materialVertex' : no matching overloaded function found
```
2021-11-17 12:04:41 -08:00
Benjamin Doherty 5697922a65 Update RELEASE_NOTES for 1.14.1 2021-11-17 12:04:26 -08:00
Ben Doherty 4da83df2b9 Fix material compilation error with device vertex domain (#4865)
A recent refactor was causing the following error when the vertex domain
was set to `device`:
```
ERROR: main.vs:23: 'material' : undeclared identifier
ERROR: main.vs:23: 'materialVertex' : no matching overloaded function found
```
2021-11-17 12:03:55 -08:00
Ben Doherty 8f156d6588 Android: re-enable VSM cascade fix (#4863) 2021-11-17 10:19:09 -08:00
Ben Doherty b0ce077ace Android: re-enable VSM cascade fix (#4863) 2021-11-17 10:14:47 -08:00
Ben Doherty 9d29d2e32c Update spirv-tools to v2021.4 (#4862) 2021-11-16 17:13:42 -08:00
Ben Doherty a29b438161 Update glslang to eb92526 (#4861) 2021-11-16 13:26:58 -08:00
Ben Doherty 50a042bb16 Metal: fix validation error when rendering to RT without depth (#4860) 2021-11-16 11:50:23 -08:00
Benjamin Doherty cec0871c11 Bump version to 1.14.1 2021-11-15 10:09:45 -08:00
Benjamin Doherty 41a809368b Merge branch 'rc/1.14.0' into release 2021-11-15 10:07:56 -08:00
Benjamin Doherty f690015a88 Release Filament 1.14.0 2021-11-15 10:06:45 -08:00
Ben Doherty 342deb5a64 speed up under ThreadSanitizer (#4842) 2021-11-12 09:52:58 -08:00
Mathias Agopian fdc480ff6e Gaussian blur is now applied only on the needed channels
The gaussian blur code was always processing 3 channels no matter the
source or destination. We now have 4 versions for all possible cases.
2021-11-11 23:35:10 -08:00
Mathias Agopian 378b7cd4dd rearrange EVSM code to make it easy to test full EVSM
We're currently only using the positive layer of EVSM which works
work small blurs and anti-aliasing. This just rearranges the code to
make it easy to test the full formulation.
2021-11-11 23:35:10 -08:00
Mathias Agopian f779fc7a0e move the shadowmap position computation inside shadow()
This is possible because, in fact, we know if we're dealing with a
spot or directional light when we invoke shadow(). So a conditional
inside it is resolved at compile time.

This will allow more flexibility in the future. Also now the shadow()
function only needs the shadow index and cascade -- which is more
future proof (e.g. if we want to handle more than one directional
shadow or spot lights with cascades).
2021-11-11 23:35:10 -08:00
Mathias Agopian fe11f495d6 simplify how we compute the shadow position
this effectively undoes a recent change, where we had a method for
spot lights and one for the directional light. instead, we can
calculate the bias at the correct Z on the caller side -- which is
needed only for spotlights.
2021-11-11 23:35:10 -08:00
Mathias Agopian 265876c849 store the texel size in world-space in the spot shadow structure 2021-11-11 23:35:10 -08:00
Mathias Agopian c9c52518c0 repair transparent shadows 2021-11-10 19:48:25 -08:00
Mathias Agopian 96c9ac6f8b fix point-lights which broke recently.
The faulty commit was:

commit 23dab0a013
Author: Mathias Agopian <mathias@google.com>
Date:   Fri Oct 29 12:03:14 2021 -0700

    Fix very narrow spotlight lighting and other minor issues
2021-11-10 15:22:38 -08:00
Ben Doherty bdeb30a847 Use workflow_dispatch instead of repository_dispatch (#4834) 2021-11-10 13:38:58 -08:00
Romain Guy ea53eb9290 Skip task incompatible with configuration caching (#4831) 2021-11-09 15:56:00 -08:00
Benjamin Doherty 05875057c9 Update RELEASE_NOTES for 1.14.0 2021-11-09 15:51:13 -08:00
Romain Guy d67210155b Skip task incompatible with configuration caching (#4831) 2021-11-09 15:01:02 -08:00
Mathias Agopian ae92c50cee more robust GL compiler error parsing 2021-11-09 14:59:50 -08:00
Mathias Agopian 43429dc0ec remove depth_main.vs from source tree 2021-11-09 12:34:19 -08:00
Mathias Agopian 04cf92a27f Remove all "Shadow Receiver Plane Depth Bias" related code
Shadow Receiver Plane Depth Bias is only needed when using large PCF
filters, which we are no longer doing. Large filter kernels are now 
supported through VSM sampling.
2021-11-09 12:31:43 -08:00
Mathias Agopian 57a57f50f6 most methods can be static in CodeGenerator 2021-11-09 12:31:28 -08:00
Mathias Agopian 5e5a75e6c5 fix bug with MASKED blending mode introduced in previous PR 2021-11-09 10:27:52 -08:00
Mathias Agopian 109c86aaf7 get rid of depth_main.vs
It's functionality is now handled in main.vs which, hopefully will be
less error prone.
2021-11-09 09:54:50 -08:00
Mathias Agopian 10e7e7727a filamat cleanup
This changes how we select the "optimized depth vertex shader", but
this shouldn't change the current behavior.

We now select the "optimized depth vertex shader" if and only if the
user code is empty. In that case, we can safely assume we can remove
all the code that's not necessary for the depth, since it is all
controlled by filament.
2021-11-09 09:54:50 -08:00
Mathias Agopian a39775050a workaround a IDE (CLion) code parsing bug
It looks like some parts of CLion don't like MaterialDomain because
it exists as an enum value
2021-11-09 09:54:50 -08:00
Benjamin Doherty 44125926d1 Disable configuration-cache 2021-11-08 17:05:34 -08:00
Benjamin Doherty 60734349de Bump version to 1.14.0 2021-11-08 11:52:50 -08:00
Benjamin Doherty fbfd5ec0ec Merge branch 'rc/1.13.0' into release 2021-11-08 11:50:19 -08:00
Benjamin Doherty 157c0264af Release Filament 1.13.0 2021-11-08 11:49:39 -08:00
Mathias Agopian 9bacfdb390 simplify shadowing code
- remove PCF "low" quality, we only use "HARD" now, when using PCF.
  Higher quality levels are achieved by using VSM.

- added a version of PCF that doesn't use a shadowSampler for future
  use.
2021-11-04 23:01:08 -07:00
Mathias Agopian f9aaf5c42e Fix normal bias for spotlights.
The normal bias is now computed correctly, this requires to compute
the z in lightspace in the shader.
Note that this would not work as well if we used LISPSM, but we'll
cross that bridge when we get there.
2021-11-04 14:56:00 -07:00
Ben Doherty a74a95cc65 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-11-04 13:28:17 -07:00
Ben Doherty 21db695e79 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-11-04 13:28:08 -07:00
Mathias Agopian cf917f1093 Add a (crude) way to have structs in our UBOs
The struct must be declared in common_type.fs, so custom
structures are not supported.
2021-11-04 12:43:50 -07:00
Ben Doherty a8d3a61c25 Enforce readPixels is called within frame (#4802) 2021-11-03 10:59:25 -07:00
Mathias Agopian 80f13a8149 fix typo in comments 2021-11-03 10:54:05 -07:00
Mathias Agopian e172f3a67f Fix java shadow biases + minor cleanups
- constant bias and normal bias default values in java didn't match
  C++ or the documentation

- stable shadows were enabled by default in java

- polygon offset biases were missing from the java API

- document and don't apply polygon offset to VSM

- remove unused code
2021-11-03 00:20:48 -07:00
Mathias Agopian c382c0a9cc Tighten spotlights near/far further
We now cull the shadow casters before computing the near/far plane
for spotlights -- we can do that because we know the light's frustum.
So only these casters that contribute to the shadow are accounted for
when calculating the near/far plane.

This PR also include more cleanup and simplifications.
2021-11-02 14:05:09 -07:00
Benjamin Doherty bc0ea16ff0 Update RELEASE_NOTES for 1.13.0 2021-11-02 13:15:53 -07:00
Mathias Agopian b2dc8aa84c Fix typo that broke the directional shadowmap 2021-11-02 13:11:44 -07:00
Mathias Agopian 78b29fe967 Fix typo that broke the directional shadowmap 2021-11-01 16:41:30 -07:00
Benjamin Doherty 9987e8b6ab Bump version to 1.13.0 2021-11-01 14:59:11 -07:00
Benjamin Doherty 0d9bdcc008 Merge branch 'rc/1.12.11' into release 2021-11-01 14:55:58 -07:00
Benjamin Doherty 81fa33abeb Release Filament 1.12.11 2021-11-01 14:55:54 -07:00
Mathias Agopian af7f87e19b make sure the near plane for spot shadows is not negative 2021-11-01 14:19:13 -07:00
Mathias Agopian 3073b03d56 Improve computation of spotlight near/far plane
Near/far plane is now computed dynamically, this significantly
improves the shadowmap depth resolution.

Quite a bit of refactoring was necessary to get all the right data 
in the right place, in particular SceneInfo is now passed around for
both directional and spot shadows.
2021-10-29 18:57:26 -07:00
Mathias Agopian 23dab0a013 Fix very narrow spotlight lighting and other minor issues
The froxel code was failing when a spotlight cone was too narrow. This
is fixed here by never using a cone smaller than 0.5 degrees during
forxelization. 

Additionally we now silently clamp the cone angles to 0.5 degrees at
the API level because, the falloff was also failing due to floating
point precision in the shader.

Finally, we clamp the inner cone upper value to the outer cone's
instead of the other way around. i.e. the outer cone defines the 
spotlight while the inner cone just controls the falloff.
2021-10-29 15:08:05 -07:00
Mathias Agopian fd68144ba2 fix depth precision with VSM
When calculating the linear depth for VSM, we were using the whole
range between 0 and the far plane, the near plane wasn't taken into
account.

This can be a problem is the light is very far, but it's near plane is
closer to the camera/scene, in this case the depth precision wasn't
used optimally.

Note that we don't hit this problem currently, because the directional
light is constructed such that its origin is at the near plane, and the
spotlights have a fixed near plane (which is a problem and will be 
fixed at a later time).
2021-10-29 12:03:41 -07:00
Mathias Agopian 51e92cd142 Fix spotlight direction and falloff
Direction and falloff were recently changed to fp16 int the shader,
which is not enough (far from it) when a spotlight is over 100m away.
2021-10-28 21:59:01 -07:00
Mathias Agopian 50f33f7196 fix some warnings and typos 2021-10-28 21:58:45 -07:00
Benjamin Doherty b5c634045e Update RELEASE_NOTES for 1.12.11 2021-10-28 16:13:50 -07:00
Ben Doherty 1f05531d53 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-10-28 16:02:23 -07:00
Benjamin Doherty 88f382f0e3 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-28 15:56:50 -07:00
Benjamin Doherty 3e59925900 Remove problematic configuration-cache setting for release build 2021-10-28 15:56:26 -07:00
Mathias Agopian 1182d30fb9 MSAA VSMs seem to now work on Qualcomm h/w
The bug that prevented them to work has been worked around, but we 
don't know when or how. The original bug still exists as demonstrated
by our standalone test apk.

For now, we reenable MSAA VSM on Adreno.
2021-10-26 16:06:20 -07:00
095179eeb3 Enabled Gradle configuration caching and rename properties (#4769)
* Fix configurationg caching problems

* Enable Gradle configuration caching

* Update BUILDING.md

* Update RELEASE_NOTES.md

Co-authored-by: Mathias Agopian <mathias@google.com>

Co-authored-by: Benjamin Doherty <bendoherty@google.com>
2021-10-26 12:47:35 -07:00
Romain Guy 69b48eaadb Fix erroenous warning 2021-10-26 12:05:49 -07:00
Timo Röhling 4031c6f0d3 Simplify devendoring (#4765)
* Perform sanity check when combining static libraries

This is a small modification that simplifies Debian packaging when one
or more vendored dependencies are replaced by system shared libraries
and no longer need to be combined with a Filament library.

* Verify vendoring before including license texts

This is another small modification to simplify Debian packaging when one
or more vendored dependencies are removed and replaced by system
libraries, so they no longer need to be considered when compiling the
license texts.
2021-10-26 11:31:35 -07:00
Mathias Agopian 7a22f7dfc5 move some VSM computations into the vertex shader 2021-10-26 11:26:21 -07:00
Mathias Agopian 728ebf5023 cleanup shadowing shader code
- remove PCF MEDIUM and HIGH quality -- these were never used in
practice, and "quality" really meant "blurriness", now we have VSM
for doing that with much more control and more efficiently.

PCF_HARD is now the default. PCF_LOW is still available at compile time
for now. It shouldn't be needed though because VSM can achieve the same.

Moved the divide-by-w of light space into the shadow() method -- which
known if it should be done or not.
2021-10-26 11:26:21 -07:00
Timo Röhling 62476d2f06 Fix compatibility with libstdc++ (#4763)
The codebase needs only a few additional standard #includes to compile
against libstdc++ on Linux; presumably those headers are implicitly
included with MSVC's and Clang's standard C++ library, but even if
libstdc++ compatibility is not a goal, it is advisable to have them
included directly.
2021-10-26 11:07:39 -07:00
Benjamin Doherty ea404f8d4f Remove problematic configuration-cache setting for release build 2021-10-26 10:09:51 -07:00
Benjamin Doherty 602a550d93 Bump version to 1.12.11 2021-10-25 12:30:37 -07:00
Benjamin Doherty 12abbe2d23 Merge branch 'rc/1.12.10' into release 2021-10-25 11:06:18 -07:00
Benjamin Doherty 5fea428243 Release Filament 1.12.10 2021-10-25 11:06:12 -07:00
Benjamin Doherty fb0ee97588 Update RELEASE_NOTES for 1.12.10 2021-10-25 11:00:06 -07:00
Ben Doherty 56ef48c9c3 Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-25 10:39:24 -07:00
Benjamin Doherty 47c3dd3dd1 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-25 10:37:52 -07:00
clayly 9a3c9ccbf3 android-samples-gradle-plugin-id (#4740) 2021-10-24 11:12:15 -07:00
Ben Doherty ef4dfcecd6 Metal: support framebuffer fetch on M1 devices (#4735) 2021-10-21 11:27:05 -07:00
Ben Doherty 5943382d23 iOS: avoid precision issues with CACurrentMediaTime (#4753) 2021-10-21 11:13:51 -07:00
Benjamin Doherty c181648bfa Bump version to 1.12.10 2021-10-20 12:15:51 -07:00
Benjamin Doherty 0cf78b3abe Merge branch 'rc/1.12.9' into release 2021-10-20 12:12:33 -07:00
Benjamin Doherty 1dcf347b87 Release Filament 1.12.9 2021-10-20 12:11:46 -07:00
Ben Doherty 47714007f7 Fix VirtualMachineEnv.cpp with older JNI versions (#4752) 2021-10-20 11:18:03 -07:00
Ben Doherty 22889a7ad9 Fix VirtualMachineEnv.cpp with older JNI versions (#4752) 2021-10-20 11:16:55 -07:00
Ben Doherty a14451d0ac Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-20 10:41:34 -07:00
Benjamin Doherty 5dfdab10b7 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-19 16:13:21 -07:00
Mathias Agopian 54277572d2 code health: cleanup FrameInfo and FrameSkipper a bit
in particular add a terminate() method to FrameSkipper instead of
destroying driver objects in the destructor -- this matches all other
objects.

also remove dependency on FEngine which wasn't needed.
2021-10-18 18:41:59 -07:00
Mathias Agopian 52f2c0e107 don't use static initialization when not needed
static init/destruction is always dangerous
2021-10-18 15:36:17 -07:00
Mathias Agopian 59abc8cc20 use NEAREST filtering for the final blit
the final blit, when used, is never upscaling, so always use the 
NEAREST filter.
2021-10-18 12:18:57 -07:00
Mathias Agopian e15796b348 Rewrite controller for dynamic resolution scaling
- move the control code out of FrameInfo and into
  View itself. FrameInfo now just gathers information about the 
  frames instead of also doing part of the control.

- the control code has been refactored into a more formal PIDController.

- a few bugs were fixed in the control loop and default parameters
  tuned. 


The control loop itself now outputs a relative scale factor instead
of an absolute one. The relative scale factor seems easier to
control and is less jittery, and doesn't have to rely on the "integral"
term of the PID.

It's possible that more tuning is needed, but the scaling is now 
more stable.
2021-10-18 10:06:44 -07:00
Mathias Agopian 1711eaa4d6 Minor improvements to DebugRegistry
- remove getProperties() we'll put it back if we need it some day

- use unordered_map because it generates less code than robin_map and
  here performance is not critical
2021-10-18 10:06:44 -07:00
Mathias Agopian acbd6a5ca8 Improve dynamic resolution scaling
- defaults to 31 history points instead of 3, this gives a much better 
  estimate of the frame rate.

- make sure the calculations work for any definition of our internal
  duration<> (it's useful to use milliseconds when dealing with
  refresh periods).

- don't round to 8 pixels if the scale factor is exactly 1

- fix a few comments and warnings
2021-10-18 10:06:44 -07:00
Romain Guy 775090fdda Re-fix tests 2021-10-15 17:30:06 -07:00
Romain Guy 0915b86927 Fix tests 2021-10-15 16:23:45 -07:00
BStringhamVRSK c10f7b01f4 Fixes normal map issues in mipgen and exposes a couple of SurfaceOrientation functions for Web
* mipgen: Linearized PNG bitmaps (such as normal maps) no longer perform gamma transform on read.

* mipgen: Using "-k normals" argument now works for all file types, not just KTX

* Web: Exposed SurfaceOrientation functions getQuatsHalf4() and getQuatsFloat()
2021-10-15 14:23:41 -07:00
Mathias Agopian 84142ac506 move platform related files into a platforms directory
this is just to improve source code readability.
2021-10-14 22:48:16 -07:00
Mathias Agopian ff190847a1 ExternalStreamManagerAndroid actually depends on GLES
Since ExternalStreamManagerAndroid depends on GLES, move it to the 
opengl directory.
2021-10-14 22:48:16 -07:00
Mathias Agopian 3ceec28189 added a way to check for adreno driver version
not used yet, but good too have.
2021-10-14 19:35:17 -07:00
Benjamin Doherty d6f2e3b8e9 Update RELEASE_NOTES for 1.12.9 2021-10-14 18:22:20 -07:00
Romain Guy 481038152f Cleanup of Android projects (#4730) 2021-10-13 18:17:12 -07:00
Rupert Rawnsley 60bd72730d ASTC texture enum missing in JNI interface 2021-10-13 10:18:54 -07:00
Benjamin Doherty df30517743 Bump version to 1.12.9 2021-10-11 11:06:43 -07:00
Benjamin Doherty 8f80643c1a Merge branch 'rc/1.12.8' into release 2021-10-11 11:02:56 -07:00
Benjamin Doherty eabfd08473 Release Filament 1.12.8 2021-10-11 11:02:30 -07:00
Mathias Agopian a66af0ac58 Minor settings cleanup
- set sensical default for gltf-viewer
- fix some warnings in ToneMapper
- fix some warnings in Settings.cpp
- minor refactor in Settings.h
2021-10-08 18:10:05 -07:00
Mathias Agopian 15187e9d99 Workaround for incorrect glInvalidateFramebuffer on Adreno
Unfortunately this bug appeared in recent drivers on some devices, it's
virtually impossible to know which device/drivers have this issue, so
the workaround is active for all Adreno GPUs.

glInvalidateFramebuffer is too aggressive and prevents loading of the
GMEM even if it's only called at the end of the render pass.
2021-10-07 20:58:34 -07:00
Mathias Agopian 681e8f8b59 Add VERBOSE log level
It is accessible through slog.v. On android it goes to the VERBOSE
log, on desktop, it's suppressed in release.
2021-10-07 20:58:34 -07:00
Mathias Agopian fbb406ca7d fix dynamic scaling internal debugging 2021-10-07 19:51:55 -07:00
Benjamin Doherty 5aea9be2fb Update RELEASE_NOTES for 1.12.8 2021-10-07 11:03:45 -07:00
Ben Doherty aacaf5055e Fix typo in View.java 2021-10-07 10:55:41 -07:00
Romain Guy a5dbddfd12 Fix release distribution (#4713)
Statically link SDL2 to make our samples (glTF Viewer, etc.) completely
standalone, and include missing resources (fonts and default environment
map for the IBL).
2021-10-07 10:11:27 -07:00
Mathias Agopian 764a0df669 Add DynamicResolution to Settings
update remote ui
2021-10-06 21:25:17 -07:00
BStringhamVRSKandRomain Guy f04864c216 Expose ColorGrading$Builder, View.setPostProcessingEnabled()/View.setAntiAliasing() JS bindings
Co-authored-by: Romain Guy <romainguy@curious-creature.com>
2021-10-06 14:21:18 -07:00
Mathias Agopian 11a1b31a4c HDR aware MSAA resolve
When supported and enabled, resolve MSAA using an HDR aware filter,
which improves anti-aliasing quality.

This is only supported with backends that support multi-sampled
framebuffer-fetch. Currently, only Metal on iOS and GLES.

Update remote ui.
2021-10-06 14:15:09 -07:00
Mathias Agopian fb86a77cf8 refactor colorgrading materials 2021-10-06 14:15:09 -07:00
Mathias Agopian d512357928 update remote ui 2021-10-06 12:45:41 -07:00
Mathias Agopian b850bc827e Fix MSAA settings ostream operator 2021-10-06 08:54:04 -07:00
Mathias Agopian 0229077293 added some missing javascript APIs 2021-10-06 08:08:18 -07:00
Mathias Agopian 23f2679bbe MoltenVk actually does support subpasses on M1
The actual problem is with the basic "blit" functionality which
is broken, and is sometimes triggered when subpasses are used.
2021-10-06 08:07:32 -07:00
Mathias Agopian e6243b3df3 better API for MSAA options 2021-10-05 22:58:16 -07:00
Mathias Agopian 375b46d866 fix an issue where we'd use the FSR scaling instead of a dumb blit
The DSR options were carried all the way to the final blit that is 
sometimes needed to impedence-match our rendering features with the
swapchain. This blit is never a scaling blit, but we were using the
FSR option, which would sometimes trigger the FSR scaling code.
2021-10-05 20:07:13 -07:00
Mathias Agopian 4577c8d57f don't use quotes with #error 2021-10-04 23:35:35 -07:00
Mathias Agopian 24d1e9c3d2 dont use ES 3.1+ APIs
FSR assumes modern OpenGL. The functions that pose problem are in fact
never used in filament, so it doesn't matter how they're implemented.
We use the HLSL version instead.
2021-10-04 23:35:35 -07:00
Mathias Agopian f7a630d614 Use a dedicated thread for dispatching callbacks
This isolates our backend thread from user code and the java VM.
2021-10-04 10:56:43 -07:00
Mathias Agopian 1c1cb11cf5 Use the new CallbackHandler in the java bindings
Java callbacks are now directly dispatched to their handler, instead
of first going through filament's opportunistic dispatch, reducing
callback latency.
2021-10-04 10:56:43 -07:00
Mathias Agopian 3ac8a6a21c Improvement to callbacks throughout filament
All APIs that take a callback as argument now also takes a 
CallbackHandler* which is a new interface used to dispatch the
callback.

CallbackHandler* can always be nullptr in which case the behavior is
unchanged. 

When CallbackHandler* is specified however, it is used to dispatch the
callback: its post() method is called from a service thread as soon
as possible (this will NEVER be the main thread), CallbackHandler::post
is then responsible for scheduling the callback onto the thread the
user desires. This is intended to make callbacks interoperate with
the platform/OS's own messaging system.
2021-10-04 10:56:43 -07:00
Mathias Agopian c524c39867 Fix JNI bindings for depth of field options 2021-10-04 10:56:43 -07:00
Benjamin Doherty ad02e483d0 Bump version to 1.12.8 2021-10-04 10:26:57 -07:00
Benjamin Doherty f463d53036 Merge branch 'rc/1.12.7' into release 2021-10-04 10:21:42 -07:00
Benjamin Doherty e203edc12a Release Filament 1.12.7 2021-10-04 10:21:10 -07:00
Benjamin Doherty b8d4408524 Update RELEASE_NOTES for 1.12.7 2021-10-04 10:18:56 -07:00
Mathias Agopian 5447baab00 rework Vulkan image layout transitions
The main issue that gets fixed here are:

- VK_IMAGE_LAYOUT_UNDEFINED cannot be used if the image content is to 
be preserved after the transition. Unfortunately, there is more than a 
few places in the VK backend where we use VK_IMAGE_LAYOUT_UNDEFINED on
images that are later used as sources.

- accessing an image memory from the host is only supported if the the 
layout is PREINITIALIZED or GENERAL. However, images in the staging
pool were transitioned to other layouts and put back into the pool,
later they would be mapped/memcpy'ed into. Instead we now always use
the GENERAL layout and never change it.

- images that where in the pool where transitioned using the miplevel
of the texture we were copying into, however this didn't make sense
because images from the pool don't have mip levels.


As part of these fixes, we also refactor imageLayoutTranstion(),
because there was two copies of this function, one specific to texture
and another one more generic. We now always use the more generic one,
with a new helper for textures.


Note: didn't fix "readPixels" which has at least problem (1), because
it's a tricky implementation, and it requires more toughts.
2021-10-01 13:20:21 -07:00
Mathias Agopian 904989f7f4 improve user callbacks latency
A new Engine::pumpMessageQueues() method can be used to trigger all
pending user callbacks right away. This can help reducing latency
of certain callbacks such as picking queries.
This is typically called once before calculating the next frame's
parameters (e.g. object positions or appearance that may depend on a 
callback result).

Fix some comments and documentation.
2021-09-30 16:55:17 -07:00
Romain Guy 4846ccd86d Use the more common EOTF/OETF acronyms (#4691)
Nothing wrong with EOCF/OECF but the "T" version is more common and readers will
therefore be more likely to be more familiar with it.
2021-09-30 14:44:46 -07:00
Ben Doherty 0fd1c3182e Add script to check that public headers can compile independently (#4675) 2021-09-29 13:47:47 -07:00
Mathias Agopian 7d80052dae Implement picking functionality
This is a pixel accurate implementation of picking. Picking queries
can be created on view, and upon completion a user provided callback
is called with the Entity of the renderable at the queried coordinates
in the viewport.

Picking queries typically have 1 or 2 frame of latency and may impact
performance on some drivers.

It is mostly intended for use by editors, or when latency is not a major
concern. This api should not be used for dragging/moving objects, it is
intended for initial picking only.

Picking is implemented in the structure pass.

The depth buffer value is retrieved and the fragment coordinate is
reconstructed and passed to PickingQueryResult. This can be used in
turn to calculate the view and/or world space position.
2021-09-29 13:02:05 -07:00
Mathias Agopian b71ee48477 vulkan: add some format to data reshaper
This is just a minimal change to get the R_INTEGER format to work.

- if src/dst types are identical, just copy (this avoids a mul and a div)
- add R,RG and INTEGER types
2021-09-29 13:02:05 -07:00
Ben Doherty 7a285dc55a Metal: support integer formats with readPixels (#4682) 2021-09-29 12:30:02 -07:00
Mathias Agopian a0f3a4d9bb new helpers for setting {Pixel}BufferDescriptor callbacks
There a just new inline helpers to more easily use lambdas, functors and 
method callbacks with {Pixel}BufferDescriptor.

A BufferDescriptor can be constructed like this:

auto bd = BufferDescriptor::make(buffer, size, [](void* b, size_t s){ });

or

auto bd = BufferDescriptor::make(buffer, size, &Foo::bar, *foo);
2021-09-28 15:26:10 -07:00
Mathias Agopian 304090d39f fix readPixels vertical offset in vk backend
vulkan expected a vertical offset from the top, but the api is in
gl convention with the offset from the bottom.
2021-09-28 14:02:26 -07:00
Benjamin Doherty fef70be848 Bump version to 1.12.7 2021-09-27 11:15:58 -07:00
Benjamin Doherty bdb12d9b24 Merge branch 'rc/1.12.6' into release 2021-09-27 11:12:42 -07:00
Benjamin Doherty 510f51d934 Release Filament 1.12.6 2021-09-27 11:12:08 -07:00
Ben Doherty 47c9fd67e2 Fix, missing call to setTransparencyMode (#4674) 2021-09-24 13:35:54 -07:00
Ben Doherty 43ad283a83 Fix, missing call to setTransparencyMode (#4674) 2021-09-24 13:32:49 -07:00
Benjamin Doherty 1f403fdae0 Revert "fix a race in jobsystem"
This reverts commit 2feb0ad325.
2021-09-24 11:33:14 -07:00
Benjamin Doherty 2e4936afc4 Revert "fix a race in jobsystem"
This reverts commit 2feb0ad325.
2021-09-24 11:24:44 -07:00
Benjamin Doherty 891ffabd11 Update RELEASE_NOTES for 1.12.6 2021-09-23 17:25:25 -07:00
Ben Doherty e2c19498b4 Metal: don't call createTextureViewWithsSwizzle directly (#4662) 2021-09-23 11:28:04 -07:00
Ben Doherty c32630b265 Fix MetalBlitter crash when shader contains warnings (#4663) 2021-09-23 11:27:56 -07:00
Ben Doherty 1a3cee9da9 Metal: don't call createTextureViewWithsSwizzle directly (#4662) 2021-09-23 11:27:07 -07:00
Ben Doherty 3acfd6fc78 Fix MetalBlitter crash when shader contains warnings (#4663) 2021-09-23 11:26:50 -07:00
Alexey Pelykh bf21e78d02 Podspec: include headers in nested directories (#4658) 2021-09-22 16:48:12 -07:00
Alexey Pelykh 83a9bb3a6f Podspec: include headers in nested directories (#4658) 2021-09-22 11:57:23 -07:00
Mathias Agopian 0744876327 improve how the structure pass commands are generated
the code generating the commands for the structure pass (called DEPTH)
in the code was different that from the color. This made sense, but 
isn't great from an architectural standpoint.
Moreover, the special filtering flags DEPTH_FILTER_*_OBJECTS were
useless because part of their functionality was handled in the DEPTH
code directly.

Instead, we now generate the DEPTH commands the same way than we do for
COLOR, but we honor the DEPTH_FILTER_*_OBJECTS flags properly.
2021-09-20 21:25:10 -07:00
Romain Guy 8b92519113 Emissive needs to be applied after shadowing (#4653)
By definition, an emissive surface won't be affected by shadowing
since it's its own light source.
2021-09-20 11:25:26 -07:00
Benjamin Doherty 525d4e08a3 Bump version to 1.12.6 2021-09-20 10:17:18 -07:00
Benjamin Doherty 2e9bf6d694 Merge branch 'rc/1.12.5' into release 2021-09-20 10:14:37 -07:00
Benjamin Doherty 1980107925 Release Filament 1.12.5 2021-09-20 10:14:01 -07:00
Benjamin Doherty e845f01d85 Update RELEASE_NOTES for 1.12.5 2021-09-20 10:10:56 -07:00
Romain Guy 409a84be1f Update release notes 2021-09-17 14:53:46 -07:00
Romain Guy b2fef7988e Use twoPassesTwoSides when doubleSided is true in gltfio (#4635)
This should help Filament properly support more glTF assets with
transparency, and should make Filament behave more like other
renderers such as three.js.
2021-09-17 14:52:47 -07:00
Mathias Agopian 82623c8fd4 IBLPrefilter relied on finalizer which could cause crashes
The finalizer can't be used to dispose of filament resource, because
it runs on its own thread.

Added a destroy() method to all IBLPrefilter related classes that must
be called once the object is no longer needed.

note: Resources will be freed eventually anyways when the Engine itself is
destroyed.


fixes #4633
2021-09-17 14:34:31 -07:00
Mathias Agopian 552a3ab103 Fix timer queries in Vulkan backend
The timestamps are given in "ticks", not in nanoseconds, like our
API expects.

Fixes #4588
2021-09-16 21:03:03 -07:00
Mathias Agopian 52c376a8a7 Fix filament-utils-android 'lite' flavor
Fixes #4601
2021-09-16 14:16:51 -07:00
Romain Guy dd3b7ca65c Update coroutines in samples to match libraries 2021-09-15 18:01:39 -07:00
Mathias Agopian 9776a38d48 run the lod bias transform only from the material() node 2021-09-15 17:19:40 -07:00
Mathias Agopian ceeccde92c Implement lod bias for user materials
A lod bias can be applied to textures when dynamic resolution is
enabled. A proper lod bias is calculated and applied for quality levels
HIGH and ULTRA.

Lod Bias is implemented in glslang, which mean it's ignored when
glslang is not used, which currently happens with OpenGL backends with
optimization turned off (which includes filament LITE). This may be
fixed in the future.
2021-09-15 17:19:40 -07:00
Romain Guy 1a8550e8e0 Call getMaterial() to avoid getting an NPE 2021-09-15 08:31:04 -07:00
Mathias Agopian 2feb0ad325 fix a race in jobsystem
We were decrementing activeJobCount after removing the job from the
queue, which could cause other threads in the pool to preempt us before
the decrement, causing them to spin forever trying to get a non-existant
job, until the decrement actually happened.

Now we always decrement first and fix-up the count if we couldn't get
a job from the queues. The race is inverted, and doesn't cause threads
to spin a long time.
2021-09-14 16:05:30 -07:00
Ben Doherty 7f2c9c2326 Fix, specify BGRA color ordering for iOS OpenGL single-plane external images (#4600) 2021-09-13 12:31:26 -07:00
Romain Guy 9e5f4be85d Update cgltf to version 1.11 (#4612) 2021-09-13 12:29:38 -07:00
Ben Doherty b5874af40b Use more sensible defaults for spot light inner outer cone angles (#4607) 2021-09-13 12:27:53 -07:00
Benjamin Doherty bef48be7b4 Bump version to 1.12.5 2021-09-13 10:47:09 -07:00
Benjamin Doherty b54fdc9e6e Merge branch 'rc/1.12.4' into release 2021-09-13 10:43:06 -07:00
Benjamin Doherty cc70b827a8 Release Filament 1.12.4 2021-09-13 10:42:35 -07:00
Benjamin Doherty cedbf2e30b Update RELEASE_NOTES for 1.12.4 2021-09-13 10:40:55 -07:00
Mathias Agopian 9ff195ce19 don't run the component manager gc in a job each
the gc usually runs for a very short amount of time, so the jobsystem
overhead is very significant compared to the actual work.

additionally this works around a scheduling issue that happens sometimes
on some devices where a thread could be "runnable but not running" for
many milliseconds.
2021-09-10 15:49:22 -07:00
Romain Guy 8e7aaaa662 Update dependencies and expose Filament as API in gltfio/utils (#4605) 2021-09-10 12:35:19 -07:00
Romain Guy 77a744b20b Update RELEASE_NOTES.md 2021-09-09 10:07:29 -07:00
Romain Guy 51fd1ef645 Update README.md 2021-09-09 10:06:26 -07:00
Benjamin Doherty 592f8d1b0d Bump version to 1.12.4 2021-09-08 11:05:44 -07:00
Benjamin Doherty 29612a684e Merge branch 'rc/1.12.3' into release 2021-09-08 11:03:53 -07:00
Benjamin Doherty 3500cc693d Update RELEASE_NOTES for 1.12.3 2021-09-08 11:03:24 -07:00
Benjamin Doherty 807b9882c5 Release Filament 1.12.3 2021-09-08 11:02:45 -07:00
Mathias Agopian b2920a68fb Only apply EASU split workaround if needed. 2021-09-07 20:09:35 -07:00
Mathias Agopian f4ef283908 workaround FSR low performance on some GPUs
On some GPU such as Adreno, the shader compiler flattens the early
exit condition, which becomes useless. We work around this by using a
two pass version of the algorithm using the depth buffer for
skipping "fast" fragments that have already been rendered.
This improves performance significantly, e.g. from 5ms to 1.3ms on
Pixel4.

Currently this mode is always enabled, which hurst performance on GPUs
that don't have this problem. This will be remediated later.
2021-09-07 20:09:35 -07:00
Mathias Agopian 09a38f4e43 use FSR upscaling for all quality levels above LOW
Now that FSR scaling is cheap enough on mobile, we use it for quality
levels MEDIUM to ULTRA.

MEDIUM and HIGH use the mobile optimized version, which has a slightly
lower quality, ULTRA uses the original version.

Additionally the RCAS sharpening pass can always be disabled by setting
the sharpen value to 0.
2021-09-07 20:09:35 -07:00
Mathias Agopian 04acd1885a fix typo where not all requested draw buffers would be cleared
we were not handling drawbuffers 4 to 7.
2021-09-07 20:08:11 -07:00
Mathias Agopian d9fde833b4 Fix integration bug in FSR mobile
We used the "float" code with the "half" texture coords, turns out FSR
uses slightly different code for both.
We're now using the "half" code (using mediump float).
2021-09-07 14:42:24 -07:00
Romain Guy 378ba4e1df Fix crash when duplicating material instances (#4596) 2021-09-07 09:59:52 -07:00
Mathias Agopian 4522ce342b don't use integer approximations on mobile
these approximations don't work in mediump and int/float bitcasting
is not well supported on mobile (can be slow).

This fixes RCAS on Mali.
2021-09-04 15:26:46 -07:00
Mathias Agopian 04402ed412 compute all texture coordinates in highp
Currently we do this only in the _mobile version
2021-09-03 09:46:40 -07:00
Mathias Agopian dc3cf5df49 rename ffx_fsr1_mobile.h to .fs 2021-09-03 09:46:40 -07:00
Mathias Agopian 9261769c5a all texture coordinates must be highp 2021-09-03 09:46:40 -07:00
Mathias Agopian f5e74f8d5a use textureFetchOffset instead of textureLodOffset
the idea here is that it allows us to not have to pass an additional
NEAREST sampler, because texelFetch.
2021-09-03 09:46:40 -07:00
Mathias Agopian e87c140255 gltfio: generate tangents if requested by the material
fixes #4565
2021-09-03 09:43:55 -07:00
Mathias Agopian 00d36110d5 Integrate optimized EASU.
filament cannot use fp16, so we make the necessary changes for the
float version. Note that we are using mediump float, which ends up
using 16 bits floats anyways.

This provides 78% reduction in execution time (i.e. 4.6x performance 
improvement). We see the EASU go from 4.2ms to 0.9ms.
The quality is slightly impacted.
2021-09-02 10:51:42 -07:00
Mathias Agopian c11364b89f AMD FidelityFX FSR1 EASU optimization for mobile
See https://atyuwen.github.io/posts/optimizing-fsr/

This is the unmodified optimized file.
2021-09-02 10:51:42 -07:00
Mathias Agopian 89f8b8663c store configuration as vec4 instead of uvec4
this avoids having to use the conversion functions
2021-09-02 10:51:42 -07:00
Mathias Agopian 6734cdd923 Fix textureGather() emulation 2021-09-02 10:51:42 -07:00
Romain Guy 3bf4ff78d9 Temporary fix for glTF assets with rough transmission (#4580) 2021-09-01 17:51:31 -07:00
Ben Doherty b52cef2fd0 Support linear filtering in MetalBlitter (#4571) 2021-09-01 13:14:49 -07:00
Mathias Agopian 66747e69c5 More cleanup in preparation of dynamic resolution improvements
- added viewport parameter to FSR
- cleanup ssao parameters for linearizing the depth
- added some sliders to simpleviewer
2021-09-01 11:29:33 -07:00
Romain Guy 4085336db5 Cleanup integration 2021-09-01 08:14:11 -07:00
Romain Guy c666a79d12 Cleanup notebook 2021-08-31 19:52:56 -07:00
Romain Guy 22a464f76f Update notebook 2021-08-31 19:47:46 -07:00
Romain Guy 60e88a6069 Add Mathematica notebook for Rec.709 to LMSR matrix 2021-08-31 19:29:10 -07:00
Mathias Agopian ff3a9a46cc Fix resizing issue when MSAA is active
Non sampleable buffers (Renderbuffers) are always rounded to 32 pixels
currently and on the backend side this buffer can end up being cached
as a sidecar buffer for MSAA. When it is created, it needs to be created
with the size of the texture it represents, not the size of the FBO,
which might be smaller.
2021-08-31 16:56:43 -07:00
Mathias Agopian 8c53ad0906 code simplification
We already have 'pAttachementTexture', as it is
passed as argument.
2021-08-31 16:56:43 -07:00
Mathias Agopian 93cc32f34d Fix texture swizzle when cache is deactivated for debugging 2021-08-31 15:58:24 -07:00
Romain Guy dd764d2c3f Update comments 2021-08-31 10:33:49 -07:00
Romain Guy 5a7ae8f1c7 Fix comments 2021-08-31 09:28:37 -07:00
Romain Guy 4ed5085422 Replace ad-hoc scale factor with more reasoned one (#4566) 2021-08-31 08:57:12 -07:00
Romain Guy 0e574f3fce Add night adaptation control to ColorGrading (#4559)
In low-light conditions, peak luminance sensitivity of the eye shifts
toward the blue end of the visible spectrum. This effect called the
Purkinje effect occurs during the transition from photopic (cone-based)
vision to scotopic (rod-based) vision. Because the rods and cones use the
same neural pathways, a color shift is introduced as the rods take over to
improve low-light perception.

This function aims to (somewhat) replicate this color shift and peak
luminance sensitivity increase to more faithfully reproduce scenes in
low-light conditions as they would be perceived by a human observer
(as opposed to an artificial observer such as a camera sensor).

The night adaptation can be controlled using a 0..1 factor for artistic
reasons: `ColorGrading::Builder::nightAdaptation()`.
2021-08-30 17:19:56 -07:00
Romain Guy dcfc27857f Update WebGL demos (#4564) 2021-08-30 12:45:02 -07:00
Benjamin Doherty e6d5807399 Bump version to 1.12.3 2021-08-30 11:46:51 -07:00
Benjamin Doherty fa2553251f Merge branch 'rc/1.12.2' into release 2021-08-30 11:44:00 -07:00
Benjamin Doherty b04c398202 Update RELEASE_NOTES for 1.12.2 2021-08-30 11:43:20 -07:00
Benjamin Doherty fe8e1d0734 Release Filament 1.12.2 2021-08-30 11:42:07 -07:00
Benjamin Doherty 7387718852 Update RELEASE_NOTES for 1.12.2 2021-08-30 11:41:52 -07:00
Ben Doherty a503a6209a Fix regression with clipSpaceTransform (#4552) 2021-08-26 14:14:58 -07:00
Ben Doherty 9f5d6e79da Fix regression with clipSpaceTransform (#4552) 2021-08-26 14:14:23 -07:00
Ben Doherty ce3e5f74e8 Fix Metal STREAM buffers (#4543) 2021-08-25 09:48:34 -07:00
Ben Doherty 9b06ab6084 Fix Metal STREAM buffers (#4543) 2021-08-25 09:48:07 -07:00
Ben Doherty f37112358e Fix missing bookkeeping in bindUniformBufferRange (#4538) 2021-08-24 09:51:40 -07:00
Ben Doherty 76d4fc08f1 Fix missing bookkeeping in bindUniformBufferRange (#4538) 2021-08-24 09:51:05 -07:00
Mathias Agopian 90548a148b Add FFX FSR as a dynamic resolution setting 2021-08-23 18:10:02 -07:00
Mathias Agopian 270bbe4218 FidelityFX-FSR initial commit 2021-08-23 18:10:02 -07:00
Mathias Agopian 3f26c8b893 Move definitions of operator<< overload in their own cpp
also always include these definitions on debug builds
2021-08-23 15:23:56 -07:00
Benjamin Doherty f368b14621 Bump version to 1.12.2 2021-08-23 12:41:33 -07:00
Benjamin Doherty 6960b1148a Merge branch 'rc/1.12.1' into release 2021-08-23 12:39:38 -07:00
Benjamin Doherty 9cea332f61 Update RELEASE_NOTES for 1.12.1 2021-08-23 12:38:47 -07:00
Benjamin Doherty 93ce14659a Release Filament 1.12.1 2021-08-23 12:37:59 -07:00
Benjamin Doherty 2d49b36b3e Fix stack-use-after-scope error 2021-08-23 10:46:39 -07:00
Benjamin Doherty 3cc23aac25 Update RELEASE_NOTES for 1.12.1 2021-08-23 10:45:59 -07:00
Romain Guy ab9d132964 Use wide gamut color grading and gamut mapping (#4524)
* Use wide gamut color grading and gamut mapping

This change introduces a new API on ColorGrading to enable or disable gamut mapping at will. This feature is currently off by default and while useful and recommended, it isn't cheap and we need to figure out what we want our defaults to be especially on mobile targets.

Gamut mapping can be combined with luminance scaling to properly control hue skews.

* Small cleanup

* More precise Rec.2020 conversion
2021-08-20 15:40:45 -07:00
Benjamin Doherty 11dc8740f2 Fix stack-use-after-scope error 2021-08-20 15:40:06 -07:00
Mathias Agopian b30e4f9a4b enable GL_ARB_shading_language_packing on GL 4.1
might fix #4515
2021-08-20 15:02:23 -07:00
Ben Doherty 4b797cff88 Windows: fix incorrect CRT flags with Visual Studio generators (#4516) 2021-08-20 10:56:41 -07:00
Ben Doherty 22afc3a93b Metal: support efficient BufferUsage::STREAM usage (#4525) 2021-08-20 10:51:30 -07:00
Ben Doherty 8aba6f0dcd BlueGL: hide GL symbols on Windows (#4523) 2021-08-20 10:34:52 -07:00
Mathias Agopian 97cee30383 Increase the number of spot shadows to 14 (from 6)
Adresses #4473
2021-08-19 23:15:21 -07:00
Ben Doherty 7f4832706b Metal: skip loop when unbinding uniform buffer objects (#4509) 2021-08-19 10:40:01 -07:00
Philip Rideout 5f16fe45b1 Java gltfio: fix use-after-free error in shutdown.
Fixes #4517.
2021-08-18 12:42:39 -07:00
Ben Doherty 8c8e0ce8a3 Metal: implement texture swizzling for external textures (#4514) 2021-08-18 10:57:50 -07:00
Ben Doherty 1b9dea5b75 Windows: fix incorrect CRT flags with Visual Studio generators (#4516) 2021-08-18 10:51:46 -07:00
Mathias Agopian 7ed073ec3f more cleanup: remove unused code, hardcoded types...
- don't use a separate array for "reversedWindingOrder"
  it's just one bit of data and we had 7 bits left in the Visibility structure.

- use Culler::result_type instead of hardcoded value everywhere

- other minor cleanups
2021-08-17 17:30:33 -07:00
Mathias Agopian e2c5bb025b Small ShadowMapManager refactoring
The main changes are:
- shadowmap command generation is now done in the framegraph pass 
  itself, which allows it to be culled should the pass be culled.
- CameraInfo is created only once instead of twice / shadowmap. 
  It's not super heavy but also not cheap, as several matrices are 
  computed.
- simplified code.
2021-08-17 10:54:01 -07:00
Mathias Agopian a86077e9fe Break dependency of ShadowMap over View 2021-08-17 10:54:01 -07:00
Mathias Agopian cd903b412f move some private headers out of src/details
src/details now only has the private headers of public types/classes.
Private/implementation classes have their header next to them under src.

This makes things more consistant.
2021-08-16 16:50:35 -07:00
Mathias Agopian dd914066f3 more cleanup
The main change here is that PostProcessManager doesn't need to depend
on View.h anymore.

Renamed some variables, fixed more include guards.
2021-08-16 16:50:35 -07:00
Ben Doherty 7af07a1c0f Fix CSM glitch with ground plane (#4487) 2021-08-13 16:31:43 -07:00
Mathias Agopian b980d0a7fd Encapsulate all the code managing the per-view uniforms
This used to reside in View and it is now its own class. The reality is
that "per view" UBO is a bit of a misnomer -- currently we indeed have
one per View, but that's not required and in fact, in the future we might
want to have a separate one for shadow maps for instance.

A better name would be "per camera". Currently it is dynamically updated 
when rendering the View and shadow maps. In the future this probably need
to be separated.
2021-08-12 16:55:34 -07:00
Mathias Agopian 5f10ab56bc move all view Options struct to Options.h
View now uses aliases to these top level structs
2021-08-12 16:55:34 -07:00
Mathias Agopian 383da5f661 cleanup include guards of our private headers 2021-08-12 16:55:12 -07:00
Mathias Agopian 8f0591c9a6 cleanup include guards of our public headers
e.g.: the guard for `FooBar.h` should look like:

  TNT_FILAMENT_FOOBAR_H
  TNT_FILAMENT_BACKEND_FOOBAR_H
  TNT_UTILS_FOOBAR_H
2021-08-12 16:55:12 -07:00
Ben Doherty afb0ceac57 Bump minimum macOS support to 10.15 (#4478) 2021-08-11 16:31:03 -07:00
Ben Doherty fc2660eb39 Metal: support format conversions for texture array and cubemap loads (#4485) 2021-08-11 14:54:58 -07:00
Mathias Agopian 1b8f4b97dd Minor camera code and comments cleanup 2021-08-11 14:35:38 -07:00
Mathias Agopian 3671469046 compute projection inverse in double precision
also concatenate transforms used for rendering using double precision
intermediates.
2021-08-11 14:35:38 -07:00
Mathias Agopian 53d4fa3095 fix assert for ortho projection 2021-08-11 14:35:38 -07:00
Mathias Agopian 94999e55e1 make sure SSAO works with ortho projections 2021-08-11 14:35:38 -07:00
Ben Doherty ba9415b514 Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:31:03 -07:00
Ben Doherty fe1c1736cd Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:30:11 -07:00
Benjamin Doherty abb6ae304c Metal: fix debug text spacing 2021-08-09 20:56:38 -07:00
Mathias Agopian 885a69710e fix typo causing ShadowOptions::shadowFar to not work properly 2021-08-09 16:56:16 -07:00
Benjamin Doherty 4058ef5f09 Bump version to 1.12.1 2021-08-09 12:06:47 -07:00
Benjamin Doherty d25ca01624 Merge branch 'rc/1.12.0' into release 2021-08-09 12:03:33 -07:00
Benjamin Doherty e7bebcdea9 Update RELEASE_NOTES for 1.12.0 2021-08-09 12:02:51 -07:00
Benjamin Doherty 5ef234153d Release Filament 1.12.0 2021-08-09 12:02:13 -07:00
Benjamin Doherty d96f87dbbf Update RELEASE_NOTES for 1.12.0 2021-08-09 12:01:46 -07:00
Mathias Agopian bbee5599f1 Fix froxelization (computation of z slice)
We need to take into account our new clip space.

This broke recently with #4440.
2021-08-08 23:26:26 -07:00
Mathias Agopian a4212d5ace Fix VERTEX_DOMAIN_DEVICE world space
this fixes the skybox's fog.

this broke recently with #4440
2021-08-06 15:18:41 -07:00
Mathias Agopian 6d0e719e06 fix display of active shader in matdbg
the database of variant was stored in hex, but the list of active
variant was sent in decimal
2021-08-06 14:00:27 -07:00
Mathias Agopian 3fa9b08a52 don't do a hashmap lookup while iterating the hashmap 2021-08-06 14:00:27 -07:00
Mathias Agopian 4b1a451804 fix VariantList type
There was a confusion on utils::bitset<> API, it specifies the number
of words to use, not then number of bits in the set.
VariantList was sized to store 8192 bits instead of 128.
2021-08-06 13:56:58 -07:00
Mathias Agopian f9d7d60f7d fix contact shadows on mobile
We were missing a few "highp" math.
2021-08-06 09:49:29 -07:00
Ben Doherty aaf9d95411 Metal: support blitting 3D textures (#4460) 2021-08-06 09:37:29 -07:00
Mathias Agopian 90d1ebefae double precision translation for model/view matrices
model/view matrices on Camera now store their translation as double
double precision. This allows filament to handle a very large world
space (thousands of kilometers).
2021-08-05 23:13:33 -07:00
Mathias Agopian a7e4a759e9 double-precision accurate translation
Augment the TransformManager so it can maintain the 4th column as
double precision; we accomplish this by storing an extra float3 per matrix.
It's calculated as `doubleTranslation - float3{doubleTranslation}`.

We also add methods to set and get a transform as mat4, internally only
the 4th column is kept as double precision.

Finally when we calculate the worldTransform, we take this extra data into
account, but only for calculating the new 4th column, so the extra work
is small.
2021-08-05 23:13:33 -07:00
Mathias Agopian 283992088f fix contact-shadow ray iteration
this broke recently with #4440
2021-08-05 19:10:59 -07:00
Romain Guy 75c9ee5982 Slight tweak to the generic tone mapper (#4461)
The new default values match almost exactly the filmic tone mapper which
is itself a close approximation of ACES. This result in a slightly more
contrasty and pleasing image out of the box.
2021-08-05 18:39:35 -07:00
Romain Guy 4d88ff116c Improve image_viewer compatibility (#4459)
- Images with an alpha channel are now properly supported. Blending is implemented directly in the image material by blending against the known opaque background color.
- Non-EXR/HDR images were not applying the proper transfer function and were therefore displayed incorrectly.
2021-08-05 16:27:19 -07:00
Mathias Agopian cf3cc37392 use glClear instead of glInvalidateFrambuffer on desktop
glInvalidateFramebuffer is not available before GL4.3.
2021-08-05 12:59:33 -07:00
Romain Guy f804c9e346 Switch white balance to CAT16 and add gamut mapping code (#4457) 2021-08-05 12:44:49 -07:00
Ben Doherty 8a2e31023f Attempt to fix TSAN failure in ColorGrading.cpp (#4447) 2021-08-05 11:54:07 -07:00
Ben Doherty 4e33e9c3d1 Attempt to fix TSAN failure in ColorGrading.cpp (#4447) 2021-08-05 11:53:35 -07:00
Mathias Agopian 18ac9fd0cc fix TAA reprojection
It broke with #4440
2021-08-05 09:46:14 -07:00
Romain Guy d0f28a48a8 Fix formatting 2021-08-04 18:57:11 -07:00
Romain Guy 706780e3a6 Speed up EXR encoding/decoding (#4446) 2021-08-04 12:39:57 -07:00
Mathias Agopian b5f9c66503 model/view matrices on Camera now use double precision
This PR only changes the API, internal storage and computation are 
still done in float, but this paves the way to double precision 
transforms.
2021-08-03 18:41:48 -07:00
Romain Guy 41f34b8d55 Properly address the color grading LUT (#4443)
* Properly address the color grading LUT

With this change we properly sample from the texel centers when we should, thus avoiding a bias toward the low values. This was particularly problematic in the darks, resulting in darker results than they should have been.

* Save 3 scalar muls
2021-08-03 16:42:44 -07:00
Mathias Agopian 04731b937a views with custom render target should be blendable
We made this wrong assumption that views with a custom rendertarget
are never blended, but it's not true -- e.g. two views can use the
same rendertarget.

Fixes #4430
May impact #2802
2021-08-03 15:42:02 -07:00
Mathias AgopianandBen Doherty 7278e5b5ba Use a clip space that matches our screen space for the z axis (#4440)
* Use a clip space that matches our screen space for the z axis

We now set the projection matrix so that the clip space for the z
axis follows the inverted DX convention, i.e.: z_clip between 1 (near)
and 0 (far), which matches our screen space.

Note that the actual clip space in the GPU can revert to the "inverted
GL convention", i.e.: z_clip between -1 and 1, if the clip_control
extension is not present. In that case the precision benefits are 
mostly lost.

Also note that there shouldn't be any user facing changes. 
The projection matrix at the API level, still follows the GL convention.

Also, currently, the VERTEX_DOMAIN_DEVICE for materials also keeps
the GL convention (this is corrected in the vertex shader).


The gist of this change is to move the "reversed DX" mapping from the
vertex shader to the projection matrix.

* Update shaders/src/getters.vs

Co-authored-by: Ben Doherty <bendoherty@google.com>

Co-authored-by: Ben Doherty <bendoherty@google.com>
2021-08-03 14:37:58 -07:00
Benjamin Doherty 891184bc77 Remove outdated TODO
We already set the correct store action for attachments.
2021-08-03 12:23:46 -07:00
Romain Guy 3d51f9ab23 Tag SDL2 windows as sRGB (#4439) 2021-08-03 11:55:18 -07:00
Benjamin Doherty 1ea8e171d9 Bump version to 1.12.0 2021-08-03 11:18:56 -07:00
Benjamin Doherty e2be3dd0ac Merge branch 'rc/1.11.2' into release 2021-08-03 11:15:19 -07:00
Benjamin Doherty 35c0092b84 Update RELEASE_NOTES for 1.11.2 2021-08-03 11:14:31 -07:00
Benjamin Doherty d249f70750 Release Filament 1.11.2 2021-08-03 11:11:24 -07:00
Mathias Agopian 0dc25cd2a8 Camera::get*ProjectionMatrix should return the value set by the user
Camera::getProjectionMatrix and Camera::getCullingProjectionMatrix used
to return the projection matrix modified by scaling and shift, instead
they should return the value set by the user, especially when
setCustomProjection() is used.
2021-08-02 22:43:21 -07:00
Romain Guy 1c51164e7b Fix inverse tone mapping issues (#4437)
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
2021-08-02 20:54:44 -07:00
Romain Guy 91b5cc4bea Fix inverse tone mapping issues (#4437)
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
2021-08-02 18:53:35 -07:00
Benjamin Doherty f190f03530 Update RELEASE_NOTES for 1.11.2 2021-08-02 11:17:42 -07:00
jeanlemotan af6f19e390 Fixed compiler warning 2021-08-02 10:34:37 -07:00
Ben Doherty 47446e6cfd Include needed headers in DataReshaper.h (#4423) 2021-08-02 10:15:01 -07:00
Romain Guy 8fada7d6c7 Fix specular AO for the sheen and clear coat layers (#4424)
* Fix specular AO for the sheen and clear coat layers

We used a single specular AO term for the sheen and clear coat layers,
computed for the base layer. This was creating occlusion that was way
too strong when the roughness from the top layers was very different from
the roughness of the base layer. The effect was particularly obvious
on clear coat materials (car paint for instance).

With this change we can also remove the "grazing angle fade" artistic
hack that was previously introduced to combat this effect.

* Safer code
2021-07-31 22:36:46 -07:00
Mathias Agopian 8a81486f5d Implement light channels
Currently there are 8 light channels, both renderables and lights can
be associated to one or several light channel, lighting occurs when
at least one channel is active on both the light and the renderable.

Fixes #4275
2021-07-30 18:54:32 -07:00
Mathias Agopian e483699fba pack booleans together in PerRenderableUib
This frees two uint32 + 30 bits.
2021-07-30 18:54:32 -07:00
Mathias Agopian ae40a12f54 inject unpackHalf2x16 if needed
unpackHalf2x16 is only needed on OpenGL 4.1 or less.
2021-07-30 18:54:32 -07:00
Mathias Agopian 73d4279f00 optimize the Light UBO for space
We use fp16 for most values (e.g.: direction, color), which 
ultimately frees a vec4 (Currently unused) and a few other bits.
2021-07-30 18:54:32 -07:00
Mathias Agopian a0e2f722f6 cached sidecar renderbuffer must honor MS count
When we associate a sidecar renderbuffer (for MSRTT emulation) to a 
texture, the msaa count comes from the rendertarget -- if this texture
is later used with a rendertarget with a different MS count, it should
still work -- in this case we have to reallocate the sidecar buffer.
2021-07-30 18:52:53 -07:00
Romain Guy 5c0da86e04 Fade specular AO from bent normals at grazing angles (#4411)
This helps prevent over-darkening but it's an artistic hack.
We need to check how we compute the bent normals as it seems we
find occlusion where there is no occlusion. The effect is
particularly visible on clear coat materials like a car's body.
2021-07-30 16:02:12 -07:00
Ben Doherty 055fc7cbc1 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-30 14:09:07 -07:00
Ben Doherty 37d8f96927 Metal: support Apple GPU pixel formats on M1 Macs (#4422) 2021-07-30 14:07:15 -07:00
Mathias Agopian e9e3ce78ca Fix a possible out of bound access on the GPU
When calculating the froxel z slice, a depth buffer value of exactly
1 (i.e. far plane) would map to after the last slice, this value
must be clamped.

made the code more readable, hopefully.

Fixes #4388
2021-07-30 14:06:58 -07:00
Romain Guy 2dadad1e87 Upgrade AGP (#4402)
* Upgrade AGP

* Request Java 11 to build Android artifacts with AGP 7.0

* Add distribution

* Use a cheaper method to pick Java 11
2021-07-28 15:43:03 -07:00
Ben Doherty 9073fc3dc3 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-28 10:49:37 -07:00
Alexey Pelykh 8c36e6d95f MaterialKey: expose constrainMaterial to Android (#4398) 2021-07-28 09:58:41 -07:00
Alexey Pelykh 2b6d99f5e7 Fix nCreateMaterialInstance in UbershaderLoader: JNI_ABORT does not propagate changes (#4396) 2021-07-28 08:35:34 -07:00
Mathias Agopian 6f29358cb6 Tweak SSAO sampling parameters to improve quality 2021-07-27 21:54:54 -07:00
Mathias Agopian 4e9dcb45ea Implement SSAO bent normals
We now have an option for evaluating the bent normals from SSAO.
This is used to improve specular AO.
Currently these bent normals are not used for diffuse lighting because
they're "flat" (face normals), which is too distracting.

The bent normal buffer is stored in the SSAO texture, in a separate
layer. This is the first post processing effect that uses 2D array
in order to limit our sampler usage.

This CL also changes how we handle SPECULAR_AO_BENT_NORMALS when
material bent normals are not available: we're now using the "Cones"
algorithm with the regular normal, instead of Lagarde's approximation.
2021-07-27 21:54:54 -07:00
Mathias Agopian 282b6f72c1 split SSAO code into multiple files
- depthUtils.fs and geometry.fs are actually completely generic
  at this point, and could be moved out of the SSAO folder.

- saoImpl and ssctImpl are just a way to be able make several versions
  of the SAO material easily (which will be needed soon)
2021-07-27 21:54:54 -07:00
Mathias Agopian cd48be5265 SSAO is now generated in a 2D array 2021-07-27 21:54:54 -07:00
Ben Doherty 3cba26a4c5 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-27 19:54:51 -07:00
Ben Doherty dd2119268b Metal: avoid std::vector in a few places (#4394) 2021-07-27 16:33:40 -07:00
Romain Guy 5e51ff78d9 Add KHR_material_volume support to MaterialProvider (#4391)
* Add KHR_material_volume support to MaterialProvider

* Fix typo
2021-07-27 14:56:50 -07:00
Alexey Pelykh 6bf27c7356 Fix NoSuchMethod exception (#4390) 2021-07-27 12:20:41 -07:00
Ben Doherty 3abd4fdf09 Cache Metal MSAA sidecar textures in MetalTexture (#4387) 2021-07-27 11:05:07 -07:00
Ben Doherty 2409dc9bc4 Expose Engine::flush (#4385) 2021-07-26 15:09:14 -07:00
Ben Doherty 432434e7e9 Expose Engine::flush (#4385) 2021-07-26 15:08:35 -07:00
Benjamin Doherty 6586c8d70b Bump version to 1.11.2 2021-07-26 12:50:29 -07:00
Benjamin Doherty ac0c94da69 Merge branch 'rc/1.11.1' into release 2021-07-26 12:48:36 -07:00
Benjamin Doherty ba68ea89cd Update RELEASE_NOTES for 1.11.1 2021-07-26 12:12:49 -07:00
Benjamin Doherty 26661375ae Release Filament 1.11.1 2021-07-26 12:11:44 -07:00
Ben Doherty d19d6a72b0 Expose Engine::flush (#4385) 2021-07-26 12:10:19 -07:00
Benjamin Doherty c81b5d98ef Update RELEASE_NOTES for 1.11.1 2021-07-26 10:05:41 -07:00
Mathias Agopian f45b7626eb make blit() of all backend more similar
This all started because the gl backend version of blit() didn't
handle color attachments other than COLOR0 *AND* would actually
corrupt the destination attachments other than COLOR0 if present. 
This is due to how very stateful the gl API is.

Since this is a case we're not running into currently, the GL backend will
now assert in that case.

Updated the Vulkan and Metal backends to also reject blits where
color buffers other than COLOR0 are requested.

Ultimately, we need to change entirely our backend blit API so it 
is less GL centric.
2021-07-23 14:10:04 -07:00
Ben Doherty 2aa21e2a43 Support float3 post-process outputs with Metal (#4376) 2021-07-22 15:12:29 -07:00
Mathias Agopian ad876b91e7 cleanup colorGradingAsSubpass shader
It was confusing how it reused the input as a temporary variable.
2021-07-22 13:51:32 -07:00
Mathias Agopian 73514f6c91 Make sure SpinLock cannot be used by accident on ARMv7
Fixes: #4371
2021-07-22 13:51:12 -07:00
Mathias Agopian 385a05d197 don't use Vulkan subpasses on Apple M1
It looks like they are not working, at least with the current version
of the drivers and/or MoltenVK. It is not impossible that we have a
bug in how we set the subpasses as well. This will need more investigation
later.
2021-07-22 12:06:31 -07:00
Mathias Agopian 306f6e1ca3 fix some broken samples and add -a option
- disable material optimizations in debug builds
- add backend selection
- generate materials for all backends
2021-07-21 18:09:52 -07:00
Mathias Agopian 756866675f fix an issue where a sampler could fail to be updated
SamplerGroup was comparing texture handles to decide if a texture needed
to be updated, however, texture handles are (quickly) recycled and
therefore can't be used for that purpose. e.g. if a texture is destroyed,
its handle could be reused quickly by another texture, if that texture 
is now set on the SamplerGroup, it will ignore it, thinking it's not
different.
2021-07-21 14:46:44 -07:00
Philip Rideout 41baa7bcf0 gltfio: fix AssetLoader leak, remove unwanted destructor.
This fixes two bugs that combined in a way that prevented a double-free
error.

The destructor of the impl class for AssetLoader was never called, which
was sort of good, because it should not destroy the material provider.
The asset loader was never meant to have ownership over the provider.
2021-07-21 14:33:23 -07:00
Mathias Agopian 694204d54a fix an issue where a sampler could fail to be updated
SamplerGroup was comparing texture handles to decide if a texture needed
to be updated, however, texture handles are (quickly) recycled and
therefore can't be used for that purpose. e.g. if a texture is destroyed,
its handle could be reused quickly by another texture, if that texture 
is now set on the SamplerGroup, it will ignore it, thinking it's not
different.
2021-07-21 14:32:59 -07:00
Ben Doherty 85bc1c1758 Fix reshaped image uploads with buffer padding or offsets (#4362) 2021-07-21 12:49:50 -07:00
Ben Doherty 0c9cb72e53 Add more resource libraries to attempt to fix Windows build (#4360) 2021-07-21 12:10:10 -07:00
Mathias Agopian d113c0f01f fix a build warning 2021-07-21 11:35:38 -07:00
Mathias Agopian 98b8871f34 Change back default AO's bilateral blur edge to 5cm
Experimenting more with this, it seems better to be too blurry than
not enough for AO. The 5cm default seems to work better with more
scenes.
2021-07-21 11:19:44 -07:00
Ben Doherty 7cb16afcb5 Metal: take buffer usage into account (#4358) 2021-07-21 11:07:03 -07:00
Philip Rideout 1a79e5463f matdbg: build+link filamat if necessary. 2021-07-21 10:49:13 -07:00
Philip Rideout fd444b2fd0 matdbg: call GLSLTools init / shutdown. 2021-07-21 10:49:13 -07:00
Philip Rideout 15db005dc6 ShaderReplacer: add note about package ownership. 2021-07-21 10:49:13 -07:00
Philip Rideout a26b05bbbb matdbg: add support for editing Vulkan GLSL 2021-07-21 10:49:13 -07:00
Philip Rideout 12b9ee46b9 matdbg: add UI for language selection. 2021-07-21 10:49:13 -07:00
Philip Rideout ce1eb83a0e matdbg: update Monaco editor. 2021-07-21 10:49:13 -07:00
Philip Rideout 27529730ca matdbg: fix bug in selectMaterial(). 2021-07-21 10:49:13 -07:00
Philip Rideout 7b398c01f6 matdbg: support multiple simultaneous clients.
Previously, if you accidentally had two matdbg tabs open in Chrome, the
web app would hang. This fixes two bugs that prevented multiple
simultaneous clients:

1) The websocket handler broadcasted edit events to only the most
   recent connection.

2) The number of server threads was only 2, but the actual web app
   requires at least 2 threads for each instance, due to the
   externally linked CSS file.
2021-07-21 10:48:43 -07:00
Philip Rideout cdb0bb9490 Vulkan: move sidecar ownership to VulkanTexture. 2021-07-21 10:47:57 -07:00
Mathias Agopian ee82f76846 Take byteOffset into account when updating a buffer. 2021-07-21 10:47:08 -07:00
Ben Doherty b77a23ff9d Remove BufferUsage flag from createVertexBuffer (#4352) 2021-07-21 10:04:57 -07:00
Ben Doherty 0d8cdab4e4 Metal: correctly handle byte offsets for updateIndexBuffer and updateBufferObject (#4349) 2021-07-20 21:03:00 -07:00
Romain Guy 67b53d0115 Optimize matrix multiplications to avoid allocations (#4350)
The previous code was a lot cleaner but caused 1+N (where N is
the dimension of the matrix) on each multiply.
2021-07-20 17:51:10 -07:00
Ben Doherty c3291d0137 Attempt to fix failing Windows CI (#4347) 2021-07-20 15:02:58 -07:00
Ben Doherty 7f2ebd25bc Update glslang's tnt/CMakeLists.txt (#4348) 2021-07-20 15:02:22 -07:00
Mathias Agopian fc32fa3a78 Improve s3tc_srgb detection on desktop
Fixes #4336
2021-07-19 23:22:12 -07:00
Mathias Agopian a3cf2ee61a Add bilateral threshold in SSAO options.
This can have a dramatic effect on SSAO and needs 
to be adjusted based on the scene's scale/units.

The default value used to be about 6cm, and has 
been changed to 5mm.
2021-07-19 18:26:19 -07:00
Mathias Agopian cc287386aa associate sidecar MS buffer to its texture instead of RenderTarget
this allows the sidecar buffer to have the same lifetime than the
texture it represents, and therefore participate to the caching of
that texture.

Fixes #4338
2021-07-19 18:26:00 -07:00
Romain Guy 9ea1dbad93 Update AGP and Kotlin versions 2021-07-19 17:29:50 -07:00
Romain Guy 4a849c7caf Update RELEASE_NOTES.md 2021-07-19 17:22:27 -07:00
Romain Guy a77a9ade29 New tone mapper API (#4330)
* WIP New tone mapper API

* Implement tone mapper constructors and destructors

* Add new genertic tone mapper

* Make the generic tone mapper available in our sample UIs

* Fix warnings and crashes

* Fix generic tone mapper and graph mappers in the UI

* Add Java APIs for ToneMapper

* Implement copy/move operators for GenericToneMapper
2021-07-19 17:19:53 -07:00
Ben Doherty 090d23434c Metal: use private instead of memoryless textures for MSAA (#4333) 2021-07-19 11:21:07 -07:00
Ben Doherty 83850c8201 Metal: Use an intermediate texture to avoid setting UsageRenderTarget on all textures (#4334) 2021-07-19 11:20:31 -07:00
Benjamin Doherty ebcd4925f7 Bump version to 1.11.1 2021-07-19 10:24:01 -07:00
Benjamin Doherty 13bed4fdf9 Merge branch 'rc/1.11.0' into release 2021-07-19 10:20:29 -07:00
Benjamin Doherty d306bfe147 Update RELEASE_NOTES for 1.11.0 2021-07-19 10:19:32 -07:00
Benjamin Doherty adfc4a5b0c Release Filament 1.11.0 2021-07-19 10:18:37 -07:00
Benjamin Doherty 1dae5c6b6c Update RELEASE_NOTES for 1.11.0 2021-07-19 10:18:07 -07:00
Philip Rideout 6b249bde4b Enable debug info in materials in debug builds.
This lets you see highly readable GLSL when transpiling the generated
SPIRV back to GLSL, with the original variable names preserved.

For now this is only useful when using `matinfo`, but it will soon be
useful in `matdbg` too.
2021-07-16 10:32:42 -07:00
Benjamin Doherty 1036759f39 Remove os_release in MetalDriver
os_release is only needed (and available) when ARC is turned off.
2021-07-15 19:09:13 -07:00
Ben Doherty 302c07048c Switch Metal driver to use HandleAllocator (#4326) 2021-07-15 16:56:19 -07:00
Ben Doherty 2686b0bbac Allow iOS gltf-viewer to load models from documents directory (#4327) 2021-07-15 16:42:59 -07:00
Mathias Agopian cece128bb9 Update bug_report.md 2021-07-15 16:35:57 -07:00
Mathias Agopian 3e5471d32a Implement sharing of bones for skinning
The API now allows to create a standalone SkinningBuffer containing
Bones for skinning. This SkinningBuffer can even be very large and
contain bone data for several renderables.

New APIs on RenderableManager allow to switch to skinning buffer mode
and to set the SkinningBuffer (and window into it) to use.


Fixes #3238
2021-07-15 16:29:26 -07:00
Romain Guy 272f786f35 Fix build warning 2021-07-15 14:05:38 -07:00
Romain Guy 0dd04f6e73 Update README.md 2021-07-15 09:23:56 -07:00
Romain Guy a5221fc816 Update BUILDING.md 2021-07-15 09:21:36 -07:00
Romain Guy 29f6616cee Update BUILDING.md 2021-07-15 09:19:50 -07:00
Romain Guy 0d08402004 Fix test_settings 2021-07-14 23:04:39 -07:00
Romain Guy 64c2ab7048 Generalize luminance scaling in color grading (#4321)
* Generalize luminance scaling in color grading

Previously the luminance scaling step was tied to a specific tone
mapping operator, called "EVILS" in the API. This was however
somewhat misleading as EVILS really is a color handling system
that's independent of what we call tone mapping.

This change splits the luminance scaling step from the tone mapping
step, allowing the use of luminance scaling (the LICH part of EVILS)
with any tone mapping operator.

As a result, the operator known as EVILS is currently mapped to the
linear operator and renamed to "RESERVED" until it is replaced by
a proper — configurable — operator.

* Update release notes

* Fix web build
2021-07-14 22:18:07 -07:00
Philip Rideout 26a54ba86a Consolidate definitions of VariantList. 2021-07-14 16:37:53 -07:00
Philip Rideout 32b3f16573 matdbg: fix active variant list, update README. 2021-07-14 16:37:53 -07:00
Romain Guy 4080a0a5d5 Small cleanup and improvements in ColorGrading (#4320)
Saturation and vibrance were using the wrong luminance weights,
and this change switches EVILS to HK weighted luminance weights
to give better results.
2021-07-14 16:23:55 -07:00
Mathias Agopian 17d67f2a39 get rid of the GPUBuffer class which was used in one place only 2021-07-14 11:45:00 -07:00
Philip Rideout 9c20efd235 Parameterize HandleAllocator and use it in VulkanDriver. (#4309)
* Parameterize HandleAllocator and use it in VulkanDriver.

* Provide macros for HandleAllocator instantiations.
2021-07-14 10:16:54 -07:00
Romain Guy b46833680d Simplify image loading now that Metal can reshape textures (#4315) 2021-07-14 09:42:41 -07:00
Mathias Agopian 4bcd862c0e fix a case where blended views + dynamic scaling didn't work
What was happening is that we were doing two blits at the end of the
frame instead of one, those blits are setup so that they only work
when the destination is the an imported target (it doesn't have to be
this way, but currently that's the only case we should have). Because
of the 2nd blit, the first one's destination would not be the
imported target and it would fail.

The real problem is that we shouldn't be doing two blits, just one
is enough. That was happening because the logic to decide if we 
needed the last blit was flawed.


Fixes #4306
2021-07-13 21:07:12 -07:00
Mathias Agopian c414ba9b2f Remove HwUniformBuffer and replace with HwBufferObject 2021-07-13 17:33:22 -07:00
Mathias Agopian 27a070c8f9 Remove some dependency on HwUniformBuffer 2021-07-13 17:33:22 -07:00
Mathias Agopian c8aea02d7d Use correct access and pipeline flags 2021-07-13 17:33:22 -07:00
Mathias Agopian 46ff9a433c don't store context/stagepool in each VulkanBuffer
This reduces the size of VulkanBuffer by 16 bytes, instead we just
pass those objects when needed.
2021-07-13 17:33:22 -07:00
Mathias Agopian c135b4aa19 don't use heap allocation for VulkanBuffer 2021-07-13 17:33:22 -07:00
Mathias Agopian 89d5f4a418 HwBufferObject can now be a uniform buffer 2021-07-13 17:33:22 -07:00
Mathias Agopian 003fe86ffb Add a BufferUsage parameter to HwBufferObject 2021-07-13 17:33:22 -07:00
Mathias Agopian 94c250a241 don't use a heap allocation for MetalBufferObject 2021-07-13 17:33:22 -07:00
Philip Rideout f1a69c8c36 Prep for using new handle allocator in Vulkan. (#4307)
Previously we were zero filling the data blob used to store all Vulkan
handles. This occured in VulkanDriver::alloc_handle().

There were several places that depended on the zero fill. These
have now been fixed up so that the handle can be constructed in a
more natural way.

Also: remove the OPENGL specific constant from HandleAllocator. This
breaks in non-CMake build systems (e.g. Bazel) that do not provide the
constant at a global level.
2021-07-13 16:37:28 -07:00
Mathias Agopian 2bd8faaef5 Improve HandleAllocator API
We now have:

  allocate<> which just allocates the handle's memory
  construct<> which constructs the handle allocated with allocate<>

  allocateAndConstruct<> which allocates AND constructs the handle
  destroyAndConstruct<> which destroys and constructs a handle in place

Normally you'd use allocate/construct but with synchronous calls, it
might be necessary to have an initialized handle immediately.
2021-07-13 16:32:17 -07:00
Ben Doherty 94a25452e8 Refactor Metal texture uploads (#4238)
Previously, Metal was never performing any texture conversions during upload. For example, `iblprefilter` loads `FLOAT` image data into the `R11F_G11_B10F` texture format. This PR fixes the issue, refactors the upload pipeline, and adds a new backend test for coverage.
2021-07-13 15:12:02 -07:00
Romain Guy 505cb39e1c Improvements to image_viewer (#4305)
Image loading errors are handled more gracefully by showing a
background color.

Added UI to set the background color.

Replaced fragment discards with solid background color.
2021-07-13 11:24:13 -07:00
Romain Guy 127dd8f675 Add new sample app: image_viewer (#4301)
* Add new sample app: image_viewer

This app shows how to load and visualize images. It's also useful to work
on color grading and other post-processing effects by just loading an HDR
or EXR image as a reference.

This change also adds a new exposure setting to the color grading LUT.

* Fix comments and build

* Fix Metal

* Use high precision for the UV coordinates

* Fix refactoring issue
2021-07-13 10:07:42 -07:00
Ian Brown fc5837b1b6 default to openGL when windows does not support VULKAN 2021-07-12 23:01:34 -07:00
Mathias Agopian 46e3d10e62 remove unneeded namespace qualifications 2021-07-12 18:03:47 -07:00
Ben Doherty 64c5dc63ab Audit usage of UTILS_PUBLIC and fix bluegl linking warning (#3988) 2021-07-12 17:09:13 -07:00
Romain Guy 31adb1213e Make white balance faster in ColorGrading 2021-07-12 12:18:53 -07:00
Benjamin Doherty 8e6663e4b0 Bump version to 1.11.0 2021-07-12 10:49:43 -07:00
Benjamin Doherty ba804444b8 Merge branch 'rc/1.10.7' into release 2021-07-12 10:47:12 -07:00
Benjamin Doherty 0344de57e9 Update RELEASE_NOTES for 1.10.7 2021-07-12 10:46:34 -07:00
Benjamin Doherty 750252b297 Release Filament 1.10.7 2021-07-12 10:45:43 -07:00
Benjamin Doherty 58cfb85004 Update RELEASE_NOTES for 1.10.7 2021-07-12 10:45:24 -07:00
Mathias Agopian ab46481b45 Fix colorgrading as subpass
We were inserting the colorgrading subpass command between the
refracted and blended objects, instead of after all of them.

Another bad side effect of this was to trigger the refraction pass for
no reason.
2021-07-12 10:35:01 -07:00
Mathias Agopian 4296782399 don't crash when refraction pass is empty 2021-07-12 09:53:37 -07:00
Romain Guy 4f28734042 Add support for KHR_materials_volume (#4291)
* Add support for KHR_materials_volume

* Add ubershader support for KHR_materials_volume

* Update readmes

* User highp on anything that affects UVs

* Add missing precision qualifiers

* Fix transmission
2021-07-09 20:50:27 -07:00
Philip RideoutandRomain Guy 4289c03ce5 gltfio: fix precision in KHR_texture_transform (#4290)
* gltfio: fix precision in KHR_texture_transform

Fixes #4253.

* Update to the new order of parameters

Co-authored-by: Romain Guy <romainguy@curious-creature.com>
2021-07-09 17:55:10 -07:00
Romain Guy bdbc85773c Improve parameter API to be more consistent with sampler parameters (#4292) 2021-07-09 17:51:12 -07:00
Philip Rideout 0a2fa36d5a API CHANGE: honor user-defined precision, rename SamplerPrecision. (#4287)
* API CHANGE: honor user-defined precision, rename SamplerPrecision.

matc now honors 'precision' on non-samplers in mat files, and
the filamat API now allows clients to specify precision for
non-samplers.

This involved flattening a union that is internal to filamat.

* MaterialBuilder: Add Java bindings for precision.
2021-07-09 17:32:08 -07:00
Mathias Agopian 0c244bc2ac Fix colorgrading as subpass
We were inserting the colorgrading subpass command between the
refracted and blended objects, instead of after all of them.

Another bad side effect of this was to trigger the refraction pass for
no reason.
2021-07-09 16:41:55 -07:00
Ben Doherty 67a49e5770 Add signposts to Metal backend (#4289) 2021-07-09 15:47:16 -07:00
Benjamin Doherty a98395bee7 Add back pointer 2021-07-09 15:04:27 -07:00
Benjamin Doherty 26c9732b4e Fix, MSVC's std::sort fails on Zip2Iterator 2021-07-09 15:04:27 -07:00
Mathias Agopian 62787de97b Don't store Handle<> debug state inline
We use a hashmap instead, which won't change the behavior of the
HandleAllocator (due to the increased size of the handles) between
debug and release modes.
2021-07-09 15:04:10 -07:00
Mathias Agopian 830c379958 reduce size of HwIndexBuffer
this limits the index count to 27 bits
2021-07-09 15:04:10 -07:00
Mathias Agopian 1a24de8735 cleanup handle size comments 2021-07-09 15:04:10 -07:00
Philip Rideout 121489f2af Work around Qualcomm issue with point lights. (#4278)
Fixes #3602.
2021-07-09 12:52:23 -07:00
Mathias Agopian 0e7295a469 fix a warning in release 2021-07-09 11:35:11 -07:00
Mathias Agopian 602b3d0796 Sort and discard lights early
We always may need to discard lights because we have a limited 
number we can use in the shader. We now do this earlier, in particular
before we set up the shadowmaps.

Because we also have a limited (smaller) number of shadowmap, this 
allows us to automatically select the ones that are closer to the 
camera, which gives better results.
2021-07-09 11:26:56 -07:00
Mathias Agopian fda06fe8a0 fix a few easy "fixmes" and "todos" 2021-07-09 10:25:22 -07:00
Philip Rideout 92628ade8e Remote UI: auto load last loaded model. (#4277)
The most recently loaded model is now automatically re-loaded if you
re-start the sampler-gltf-viewer app.

Super useful in my case for `rgb-lights.glb` :)
2021-07-09 08:46:58 -07:00
Romain Guy b399d64024 Update README.md 2021-07-08 20:46:34 -07:00
Mathias Agopian a8e8c04c7b Skip lighting/shadowing when possible
We can skip lighting in the areas fully shadowed, we can also skip
shadowing outside the radius of punctual lights.
2021-07-08 16:37:06 -07:00
Romain Guy 313b9944fd When IOR=1.0, there should be no transmission roughness (#4276)
* When IOR=1.0, there should be no transmission roughness

See https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/TransmissionRoughnessTest
for details.

* Use a smoothsteph instead

* Don't modify roughness twice
2021-07-08 16:08:55 -07:00
Romain Guy 5a61d28eee Add Java bindings for transparent shadow (#4272)
* Add Java bindings for transparent shadow

* Fix JNI binding typo

* Fix typo
2021-07-08 12:50:18 -07:00
Ben Doherty 4eb0937d21 matc: log error when input material definition is empty (#4273) 2021-07-08 11:34:46 -07:00
Romain Guy a082e94235 Update RELEASE_NOTES.md 2021-07-08 10:32:39 -07:00
Romain Guy 9bd3684893 Add support for transparent shadows (#3298)
* Add support for transparent shadows

This solution uses an 8x8 Bayer matrix. We could find a better
noise. We also need better filtering of the shadow maps. A PCF
is barely enough and VSM fails without blurring.

* Use a fixed Bayer matrix, fix pre-caching of depth shaders

* Use gradient noise instead of fixed bayer pattern

* Update docs
2021-07-08 10:31:52 -07:00
Philip Rideout 0cd9fd9ad9 sample-gltf-viewer: fix remote control of IndirectLight. (#4267) 2021-07-07 20:41:12 -07:00
Mathias Agopian efcc690f42 update remote ui 2021-07-07 17:45:58 -07:00
Mathias Agopian 1ed1a5efb6 Allow MSAA when post-processing is disabled
There was no good reason not allow this.
Fixes #2533
2021-07-07 17:19:57 -07:00
Mathias Agopian 2d7de6ecc0 enable up to 6 spot shadows
This is a trivial change since we moved the lightspace computation
in the fragment shader. The limitation to 6 is due to how we're storing
the culling result.
2021-07-07 17:19:42 -07:00
Romain Guy 4a1edc4281 Add gltf_viewer and material_sandbox to release archives (#4264) 2021-07-07 17:19:12 -07:00
Romain Guy d6b32e5923 Remove support for Java/desktop builds (#4263)
* Remove support for Java/desktop builds

These builds are never tested nor used on our end. We cannot
guarantee their proper support. It should also be possible
for an app to handle this itself.

* Remove Tungsten since it cannot be compiled anymore
2021-07-07 17:18:58 -07:00
Philip Rideout 105ae8abb6 Update prebuilt MoltenVK to 1.2.182. (#4260) 2021-07-07 17:16:44 -07:00
Philip Rideout 1f33dad675 Update glslang. (#4258) 2021-07-07 15:27:18 -07:00
Mathias Agopian 90ee59512b don't crash when refraction pass is empty 2021-07-07 14:28:48 -07:00
Romain Guy 7f2a189641 Update docs 2021-07-07 13:50:37 -07:00
Romain Guy 1ab59ca35a Update to the latest version of Markdeep for local use (#4257) 2021-07-07 13:49:38 -07:00
Philip Rideout 5c0826963e Update spirv-tools. (#4255) 2021-07-07 13:28:59 -07:00
Mathias Agopian 7555fe6196 enforce CLAMP_TO_EDGE for external textures
Fixes #2978
2021-07-07 13:28:21 -07:00
Mathias Agopian 1dbb9c7ded HandleArena now can deal with running out of space
When HandleArena is full, we now revert to a slower system-heap
based mechanism. The problem is logged once. This allows the
system to continue to run.
2021-07-07 12:07:25 -07:00
Mathias Agopian ac798c1350 moved HandleAllocator outside of the OpenGL backend
This means it can easily be used by our other backend.

HandleAllocator uses 3 pool (which currently can't be configured),
and is very efficient in terms of memory overhead and handle to
pointer conversion.

A Handle<> is just an offset into a large heap managed by the 3 pools.
2021-07-07 12:07:25 -07:00
Philip Rideout 00682bd911 Add simple ReadPixels performance test. (#4248)
* Add simple ReadPixels performance test.

This simply lets the gtest framework report the total test time, which
includes startup and teardown.  However we perform 100 runs of the
render+readback code to reduce the run-to-run variance. For 100 runs of
a 2000x2000 buffer, I see the following results on my mac:

- Vulkan: 1881 ms
- Metal: 1625 ms
- OpenGL: 978 ms

The test can be built & invoked like this:

```
./build.sh release backend_test_mac && \
    ./out/cmake-release/filament/backend/backend_test_mac -a opengl --gtest_filter="*ReadPixelsPerformance"
```

See also issue #4246.

* ReadPixels test: minor refactor.
2021-07-07 12:00:04 -07:00
Benjamin Doherty ef375a7103 Bump version to 1.10.7 2021-07-07 11:02:30 -07:00
Benjamin Doherty fd258b7765 Merge branch 'rc/1.10.6' into release 2021-07-07 10:59:12 -07:00
Benjamin Doherty ceced43e93 Update RELEASE_NOTES for 1.10.6 2021-07-07 10:58:31 -07:00
Benjamin Doherty 55fdc47e66 Release Filament 1.10.6 2021-07-07 10:57:56 -07:00
Benjamin Doherty 147de8d372 Update RELEASE_NOTES for 1.10.6 2021-07-07 10:57:25 -07:00
Philip Rideout eb2a1928b6 ShadowMapManager: fix MSAN use-of-uninitialized-value.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
2021-07-07 10:51:18 -07:00
Philip Rideout 53a92451e6 ShadowMapManager: fix MSAN use-of-uninitialized-value.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
2021-07-07 07:51:28 -07:00
Mathias Agopian 77016f34a5 More simplifications of the ShadowMapManager code
- the ShadowMap cache is now inline and doesn't use unique_ptr<>

- reduced the size of ShadowMap significantly, it used some temporary
  storage as member, but now that we have many of those, we shouldn't
  do that.

- removed some duplication of fields

- fixed some headers inclusion
2021-07-02 10:08:09 -07:00
Mathias Agopian 19db911d46 Use a custom command to handle color-grading subpass
This is cleaner and what custom commands are for.
2021-07-02 10:08:09 -07:00
Mathias Agopian 46a88c7ed8 Rework RenderPass allocations
Instead of managing a GrowingSlice<> more or less shared between
several RenderPass, RenderPass now works directly with an Arena which
owns the commands. We do this so RenderPass can be copiable, which is
useful for creating a RenderPass from a "template" RenderPass
(usually empty, but with some scene parameters set).

RenderPass is now a lot more self contained.

Execution of the commands is now done with a RenderPass::Execcutor
which can be obtained from a RenderPass.

This change led to some code clean-up as well.

We also had to improve Arena<> to be able to take a custom Area.
2021-07-02 10:08:09 -07:00
Philip Rideout ca3b841974 gltfio: Add fast path for native material providers. 2021-07-01 16:11:55 -07:00
Philip Rideout e9ff2157bc gltfio: Cache the JNI field ids for MaterialKey. 2021-07-01 16:11:55 -07:00
Philip Rideout d270c42109 gltfio: Allow Java / Kotlin clients to customize MaterialProvider.
This adds some significant JNI glue in order to make the Java API for
gltfio materials much more consistent with C++, and create feature
parity between the two languages.

The motivation is to allow Java clients to provide their own
ubershader-based solution or filamat-based solution.

- The `MaterialProvider` Java class is now an interface.
- The `UbershaderLoader` Java class is now a concrete implementation.
- Users can now write their own provider class using Java / Kotlin.

To streamline the amount of JNI work that occurs at run time, the
MaterialProvider Java interface uses ints in a couple spots instead
of enums. This sacrafices some readability for Java clients who wish
to write their own provider, but makes the JNI much simpler.

This replaces #3975.
2021-07-01 16:11:55 -07:00
Philip Rideout f4558fee1d Update remote UI. 2021-06-30 09:44:05 -07:00
Philip Rideout 86461663d8 Settings UI: LightManager ShadowOptions now affect all lights. 2021-06-30 09:42:00 -07:00
Mathias Agopian fcca62ec6a spotlight light-space position moved to the fragment shader
We have a limited number of interpolants, and 2 were used for spotlights,
but this is a fairly uncommon case, so we move the calculation to the
fragment shader. A side effect of this is that we are not limited to 
two spot-light anymore from the shader's point of view.

This essentially adds a vector transform per fragment, but on the other
hand, it removes communication between the vertex and fragment shader,
as well as interpolation of the position.
2021-06-29 17:19:43 -07:00
Mathias Agopian f6dde81a16 workaround drivers that don't implement textureSize() properly
On some qualcomm drivers, textureSize() with a level != 0 aborts the
pixel shader.
2021-06-29 10:12:38 -07:00
Romain Guy d77e66d1e8 Update README.md 2021-06-28 23:08:33 -07:00
Mathias Agopian 702f906d49 PCF shadows need some math in highp
mediump is not enough for sampling positions.
2021-06-28 16:29:36 -07:00
xjdkc 2f257b54e7 fix the bug of not mapping depth24 to depth32 on iOS platform when stencil is enabled 2021-06-28 15:54:03 -07:00
Mathias Agopian c1b9e47a90 fix virtual near/far shadow hint for lispsm
the virtual near/far plane used by lispsm wasn't computed correctly,
which would sometimes result to incorrect "optimization" of the
lispsm range.
2021-06-28 15:28:33 -07:00
Mathias Agopian a93e10308c specify sample count for vsm's depth buffer
This basically expresses the fact that we won't need an "auto-resolve",
indeed the temporary depth buffer is always discarded. In the GLES
backend, this is likely (if MSRTT is supported) to take a less
complicated code path.

Improve some comments.
2021-06-28 15:28:33 -07:00
Mathias Agopian 204fc0359c Fix out of bounds access in java bindings
Fixes #4154
2021-06-28 15:28:12 -07:00
Philip Rideout eb483281dc Update remote control web app. 2021-06-28 15:10:50 -07:00
Philip Rideout b841709729 gltf_viewer: make auto-scale into a UI setting. 2021-06-28 15:08:59 -07:00
Benjamin Doherty 35b033102f Bump version to 1.10.6 2021-06-28 12:07:58 -07:00
Benjamin Doherty 7bc65421a9 Merge branch 'rc/1.10.5' into release 2021-06-28 12:04:31 -07:00
Benjamin Doherty 736514cf37 Update RELEASE_NOTES for 1.10.5 2021-06-28 12:04:27 -07:00
Benjamin Doherty 6307fb3563 Update RELEASE_NOTES for 1.10.5 2021-06-28 12:03:59 -07:00
Benjamin Doherty 35b3542b2e Release Filament 1.10.5 2021-06-28 12:03:22 -07:00
Mathias Agopian db0158dae8 fix webgl build
we need to select opengl on webgl.
2021-06-28 08:27:46 -07:00
Philip Rideout 0fa5ca9a6a Fix 'Last Updated' in the Vulkan document. 2021-06-26 10:30:15 -07:00
Mathias Agopian 36285f2ca5 Increase OpenGL backend handle arena to 4 MiB 2021-06-25 19:04:20 -07:00
Mathias Agopian 9e19a1aca4 The gaussian blur running sum must be in highp
This is to acomodate hdr and evsm blurring.
2021-06-25 17:44:40 -07:00
Mathias Agopian 19c7949cc4 update remote ui 2021-06-25 17:32:19 -07:00
Mathias Agopian 36d7f6ff94 Fix more issues with VSM settings for the remote UI 2021-06-25 16:55:13 -07:00
Mathias Agopian e7b90f9c12 update remote ui 2021-06-25 15:18:33 -07:00
Mathias Agopian 8bd499c60c fix webgl build
we need to select opengl on webgl.
2021-06-25 14:03:57 -07:00
Mathias Agopian 0d61d47f28 update remote ui 2021-06-25 13:21:23 -07:00
Mathias Agopian 4b5dc5b3af Fix VSM mipmap generation
- the clear color was broken since we switched dot EVSM
- use the scissor instead of the viewport, it makes it easier to compute
  the uv-scale.
- the min/max lod level wasn't reset properly
- also clamp the minimum shadowmap size to 8, and document it.
2021-06-25 12:12:37 -07:00
Mathias Agopian 61bf472426 VSM blur is now specified as a width in pixels
This is a lot more intuitive than using the standard deviation.
2021-06-25 12:12:37 -07:00
Mathias Agopian ef6199a792 Improve shadow generation code
We make better use of the framegraph, by using a pass per shadowmap,
instead of generating all shadowmaps in a single framegraph pass.
This allows us to use less temporary memory when blurring, but also
simplifies the code.
2021-06-25 12:12:37 -07:00
Mathias Agopian 7bd0b45a2b Implement blurring of VSM shadow maps
This is still somewhat work-in-progress, but good enough to be useful.

Some caveats:
- large blurs don't work well with cascades
- the implementation uses more memory than it could
2021-06-25 12:12:37 -07:00
Philip Rideout eb0c346969 gltfio: remove hacky RTTI from MaterialProvider.
We want anybody to write their own class that descends from
MaterialProvider, so it doesn't make sense to have an enum of
concrete types.
2021-06-24 15:24:13 -07:00
Philip Rideout bf2938f345 PostProcessManager: call setMinMaxLevels for DoF.
Depth of field now works on Vulkan, wooot!  This is also required for
OpenGL, for Intel drivers.
2021-06-24 13:22:47 -07:00
Philip Rideout c7e4116154 gltfio: introduce support for extras strings.
This allows clients to obtain the extras strings for the asset and
for individual nodes.  Note that extras for buffer views, accessors, etc
are not supported, although C++ clients can access the raw cgltf data
directly if they need to.
2021-06-24 10:41:40 -07:00
Philip Rideout db521e0e5e gltfio: add getAsset to FilamentInstance. 2021-06-24 10:41:26 -07:00
Philip Rideout a219629ead Fix vsm options serialization. 2021-06-24 10:03:13 -07:00
Mathias Agopian ba10393f48 Rework a bit UniformBuffer and friends
Filament uses a handful of known UBO, the code for creating their
interface block is not needed in filament (via filabridge), so
reorganize things so that we can move that code to filamat.

On the other hand, filament needs the C structure corresponding to
the UBO, to find the fields offset and ubo size and name.

We now have a UibStructs.h in filabridge which only defines C struct
with a static name for the interface block's.

This should slightly reduce the size of filament proper.

We also now have a new helper TypedUniformBuffer<> which simply holds
one of these structs (or an array), and allows to set the fields
directly and more naturally from C++. std140 alignment is now left to
the caller, when going through that class.
2021-06-24 09:58:06 -07:00
Philip Rideout 091e399d0f Vulkan: ensure sample count is supported. 2021-06-24 09:06:10 -07:00
Mathias Agopian 5de6779d72 VSM improvements and fixes
- use EVSM (exponential VSM), helps a lot with light bleeding
- don't apply shadow biases with VSM
- improve VSM user settings: added more controls, expose to java
- minor code cleanups:
   - rename some structures
   - remove unused parameters
   - remove unused uniforms
2021-06-23 18:08:57 -07:00
Mathias Agopian 4b3a983b23 Handle shadow receivers w/ VSM more robustly
VSM requires shadow receivers to be in the shadowmap, instead of
handling this in the shadow mapping code, we're handling it in 
FScene::prepare(), which guarantees it'll ripple everywhere it needs to.
2021-06-23 18:08:57 -07:00
Ben Doherty 1b53e78ea7 Metal, ensure sample counts are supported by device (#4185) 2021-06-23 14:34:33 -07:00
Philip Rideout ef08323b25 Vulkan: fix swizzle support.
When creating a texture with a swizzle, the swizzle should be applied to
the image view only when sampling from that texture.  When a swizzled
texture is used as a render target attachment, the image view should not
have any swizzle applied.
2021-06-23 12:03:11 -07:00
Philip Rideout 24c6917267 Fix Android build. 2021-06-23 09:42:57 -07:00
Mathias Agopian 9ab25fa19e Fix a crash where flare is on but starburst off 2021-06-23 08:33:25 -07:00
Philip Rideout d5f785ff41 matc and Vulkan: apply smol-v to raw programs. 2021-06-23 08:27:26 -07:00
Philip Rideout f2a8e2aef7 Vulkan: add support for depth resolves.
The DepthResolve test now passes with Vulkan, although DoF still
triggers validation errors, which I'll look into next.
2021-06-23 08:27:26 -07:00
Philip Rideout 7bdd1fe096 FCV: emphasize trivial default construction in the note. 2021-06-23 08:26:19 -07:00
Philip Rideout f677eef422 FixedCapacityVector: add note about default construction. 2021-06-23 08:26:19 -07:00
Romain Guy 70f3824b14 Update README.md 2021-06-22 20:57:15 -07:00
Mathias Agopian 11b980832c fix ground plane's bounding box 2021-06-22 17:01:42 -07:00
Benjamin Doherty e706695ed1 Bump version to 1.10.5 2021-06-21 11:18:26 -07:00
Benjamin Doherty e8877ffe2d Merge branch 'rc/1.10.4' into release 2021-06-21 11:16:10 -07:00
Benjamin Doherty 300e853646 Update RELEASE_NOTES for 1.10.4 2021-06-21 11:15:44 -07:00
Benjamin Doherty a403279fa6 Release Filament 1.10.4 2021-06-21 11:14:58 -07:00
Benjamin Doherty 1fd5d9dae6 Update RELEASE_NOTES for 1.10.4 2021-06-21 11:14:35 -07:00
Philip Rideout 8f6f831d5b Add missing #include. 2021-06-21 09:11:04 -07:00
Philip Rideout 599077b54c Use FixedCapacityVector in backend::Program. 2021-06-18 13:31:01 -07:00
Ben Doherty 9b7414b60c Fix, set mBackend to resolved backend in FilamentApp.cpp (#4160) 2021-06-17 18:00:40 -06:00
Philip Rideout 78430858fe gltfio: do not set clear coat in GLTFIO_LITE config.
This avoids an assertion in debug builds. We will document this behavior
much more thoroughly in a subsequent PR.

Fixes #4143.
2021-06-17 14:44:05 -07:00
Mathias Agopian fe8528a963 Backend::DEFAULT now selects a backend most suited for the platform (#4155)
- OpenGL ES on Android
- Metal on MacOS/iOS
- Vulkan everywhere else (Linux/Windows)

The main change here is that OpenGL is no longer the default on
desktop.

Most of our samples have a `-a` option that can be use to specify the
desired backend.
2021-06-17 14:42:29 -07:00
Mathias Agopian f365cb965b fix a potential memory corruption when using more than 4 render targets
The array size in the GL structure didn't match the number of supported
render targets.
2021-06-17 14:40:48 -07:00
Romain Guy 2b38cf4c65 Include ProGuard rules in our AARs (#4158) 2021-06-17 14:29:55 -07:00
Philip Rideout 2e9080a179 Fix issues in test_FeedbackLoops and VulkanDriver.
1) Add a missing destroyTexture to the test, which I believe fixed
the Metal assert that I was seeing, as well as some Vulkan validation
warnings.

2) Add a flushAndWait() utility to BackendTest, which is useful for
diagnostics.

3) Fix a layout validation issue in VulkanSwapChain for empty render
passes.
2021-06-17 11:29:39 -07:00
Mathias Agopian 0a50ee989e fix a possible crash when bloom is enabled
This reworks how we compute the bloom buffer size. The main changes are:

- The BloomOptions.resolution is changed to height instead of minor axis.
  This keeps a consistant look of the bloom regardless of the viewport.

- The anamorphism setting now dilates the bloom rather than to compress
  it (in the other direction), which maintains the same amount of bloom.
  However, the resolution decreases meaning that the user might need to
  adjust resolution and/or levels.

- limit the resolution do 2048 which is gles minspec.
2021-06-17 10:17:31 -07:00
Mathias Agopian c9c9103ede disable skybox/clear optimization
We were disabling the color pass render target clear when a skybox
was present. This optimization doesn't work when the viewport is not
full. Currently there is no way to know that, so we disable this 
optimization for now. Performance loss is not expected to be significant
if present at all.
2021-06-16 16:20:15 -07:00
Mathias Agopian 1ce9e96490 fix automatic clearing of rendertargets
We were automatically clearing the color pass render target when
the view was translucent -- the idea was that when it gets blended at
the end it wouldn't override the content of the render target.

Unfortunately, this doesn't work when the rendertarget is imported,
because in that case, it's not actually blended, we're just rendering
into it directly. The clear would then erase the previous content.

This is fixed by moving the clearing decision in the execute closure and
piggy-backing on the computed discard flag. Discard means clear.
The discard flag will be set for newly created buffers and not for an
imported target that needs to keep its content.
2021-06-16 16:20:15 -07:00
Mathias Agopian 1f9c802e10 Fix imported target discard and clear flags
An imported target shouldn't specify the discardStart flags, those
are calculated from the graph. However, it needs to specify "keep" flags,
to take into account constaints that the graph cannot see (due to the fact
that it's imported into the graph). i.e. the imported target may have
content that needs to be preserved.

An imported target can specify a clear color and clear flags that will
override the flags from the logical Descriptor -- this is a way to
delay the swapchain clear to when we're actually rendering into it
(which usually happens in the very last pass).
2021-06-16 16:20:15 -07:00
Mathias Agopian c6fda8385a fix opaque blit with imported render targets
When the source of a blit refers to an imported render target,
we can't create a HwRenderTarget from it because the resource
is not a real texture and doesn't have a HwTexture.
However, it can be converted back to the HwRenderTarget it
represents, using the FrameGraph's declareRenderPass API.
It's a slightly strange usage of this API, but not technically
wrong.

This is the main fix for bug #4085
2021-06-16 16:20:15 -07:00
Mathias Agopian d0664bc119 add post-processing option to gltf-viewer 2021-06-16 16:20:15 -07:00
Philip Rideout e7ed85ec94 Update WebGL tutorials. 2021-06-16 14:24:47 -07:00
Philip Rideout 5d1d4ff4d6 Update web site with latest WebGL artifacts. 2021-06-16 14:17:12 -07:00
Philip Rideout 57040ebb22 Fix and refactor support for S3TC + SRGB. 2021-06-16 14:08:51 -07:00
Philip Rideout 03b018e7f3 Repair FeedbackLoops test. 2021-06-16 14:07:49 -07:00
Romain GuyandPhilip Rideout 04ada346b0 Materials can now provide custom lighting/shading (#4142)
* Materials can now provide custom lighting/shading

When a material uses the "lit" shading model, customSurfaceShading can
be enabled to replace Filament's lighting implementation. When this
feature is enabled, the material *must* provide the following function
in the fragment shader block:

    vec3 surfaceShading(
            const MaterialInputs materialInputs,
            const ShadingData shadingData,
            const LightData lightData
    ) {
        return vec3(1.0); // custom lighting here
    }

Please refer to the docs in Materials.html for more information about
this feature and the different values provided by the data structures
passed to the function.

* Update docs

* Update docs/Materials.md.html

Co-authored-by: Philip Rideout <philiprideout@gmail.com>

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2021-06-16 09:53:58 -07:00
Philip Rideout f53c7723fb Vulkan: fix ReadPixels regression, refactor VMA inclusion. 2021-06-15 18:07:01 -07:00
Ben Doherty cd48089318 filament-utils-android: fix string literal conversions (#4137) 2021-06-15 16:19:32 -06:00
Ben Doherty 0a6a74c78c filament-utils-android: fix string literal conversions (#4137) 2021-06-15 11:00:31 -06:00
Philip Rideout b40982d579 Vulkan: repair headless swap chains.
I broke this when migrating to FixedCapacityVector.
2021-06-15 08:23:04 -07:00
Philip Rideout 2605633e1e Upgrade vkmemalloc. 2021-06-14 12:58:14 -07:00
Benjamin Doherty 6379ab22c9 Bump version to 1.10.4 2021-06-14 11:06:42 -06:00
Benjamin Doherty 0bf02b75d5 Merge branch 'rc/1.10.3' into release 2021-06-14 11:04:25 -06:00
Benjamin Doherty 2f7e873137 Update RELEASE_NOTES for 1.10.3 2021-06-14 11:03:54 -06:00
Benjamin Doherty bb9e23519d Release Filament 1.10.3 2021-06-14 11:03:11 -06:00
Benjamin Doherty c4259b5598 Update RELEASE_NOTES for 1.10.3 2021-06-14 11:02:45 -06:00
Philip Rideout acfae2882d Vulkan: Use custom VMA pools to speed up Mali.
This makes the car load in 3 seconds instead of 30 seconds on Mali.

On devices that have bufferImageGranularity set to 1 in the
VkPhysicalDeviceLimits caps structure, we observe that vmaCreateBuffer
can be two orders of magnitude faster than with devices that have a
higher value for their bufferImageGranularity.

According to the Vulkan spec, the bufferImageGranularity aligment
constraint needs to be honored only when linear and non-linear resources
live next to each other in memory.  Since all VkBuffer objects are
linear, we can allocate them all from the same pool and ignore the
alignment constraint.
2021-06-11 14:48:29 -07:00
Philip Rideout 180eb61620 Vulkan: Fix uninitialized vector contents. 2021-06-11 10:40:04 -07:00
Philip Rideout a92bb87cd8 Vulkan refactoring. 2021-06-11 09:18:18 -07:00
Philip Rideout 2c967b821b Minor Vulkan cleanup. 2021-06-11 08:48:07 -07:00
Philip Rideout abe9a9731d Vulkan: use FixedCapacityVector in one more spot. 2021-06-11 08:24:54 -07:00
Philip Rideout 2837a48001 Vulkan: Use FixedCapacityVector in lots of places. 2021-06-10 14:41:03 -07:00
Philip Rideout 4aef84342d gltfio: Cache the dummy buffer to optimize load time.
This greatly improves the load time on some Mali devices. On one device,
loading the car model went from 85 seconds to 35 seconds.
2021-06-10 14:40:47 -07:00
Philip Rideout 9be6153875 Refactoring: simplify VulkanDisposer. 2021-06-10 13:49:37 -07:00
Philip Rideout 444640afb7 Refactoring: decouple VulkanBuffer and VulkanDisposer. 2021-06-10 13:49:37 -07:00
Philip Rideout 122908587b Fix build break. 2021-06-10 09:53:54 -07:00
Philip Rideout c1654537e2 Vulkan: use debug_utils for custom labels.
VK debug markers do not show up in an AGI system trace, but we can sneak
them in by using debug_utils to assign labels to VkFramebuffer.

Note that the debug_utils extension is enabled only when launching your
app from AGI.
2021-06-10 09:32:10 -07:00
Philip Rideout 984a172cec Enable EXT_debug_utils on Android. 2021-06-10 09:32:10 -07:00
Mathias Agopian ee2767875c Fix FixedCapacityVector::reserve()
We were initializing the new data with the default
Actor by accident.
2021-06-09 17:07:34 -07:00
Philip Rideout fa0a41e62e sample-gltf-viewer: log the load time (useful for large models)
More precisely, this logs the time that the Filament backend takes
to process all the commands that were issued in the gltfio synchronous
loading phase, which mostly consists of creating and populating vertex
buffers.

This can be quite slow for vertex-heavy (CAD-style) models, and seems to
vary by several orders of magnitude from device to device on Vulkan.
2021-06-09 13:40:16 -07:00
Philip Rideout edaf718281 Vulkan: fix storeOp for depth attachment.
This gets rid of the "GMEM Store Depth / Stencil" bars seen with AGI.
2021-06-08 14:34:31 -07:00
Philip Rideout 7cd5963d3a Adjust VK_MAX_COMMAND_BUFFERS to prevent a 5 ms stall.
This constant was previously set to 3 because of triple buffering, which
does not account for the fact that Filament may issue multiple commit()
calls during a single frame.

This new number was determined via experimentation.

On a Pixel 4, this reduces a 4.5 ms gap in "GPU Queue 0" to 420 us.
2021-06-08 14:34:23 -07:00
Philip Rideout 60f5512c5f JS bindings: remove bogus stride argument.
Fixes #4106.
2021-06-08 14:23:41 -07:00
Ben Doherty 6b3c1179bc Include sample-gltf-viewer with Android releases (#4099) 2021-06-08 10:41:48 -07:00
Ben Doherty d1b9a1b996 Include sample-gltf-viewer with Android releases (#4099) 2021-06-08 10:32:49 -07:00
Mathias Agopian 1bd91e7e94 JobSystem: simplify callback code
we can use the lambda syntax instead of a static method.
2021-06-08 09:47:16 -07:00
Mathias Agopian 5e2f73c74e JobSystem: reduce parallel_for overhead
We reuse the current job for the right side instead of spawning a new
job, which has overhead. This also cuts in half the number of times we
need to copy the user functor.
2021-06-08 09:47:16 -07:00
Mathias Agopian 4a269e37c5 Don't use very small jobs when using parallel_for
The overhead of the jobsystem / job is about 50-100us, so we should
try to use jobs about an order of magnitude bigger -- which is actually
quite rare.

In particular the culling is so efficient that we'd need to process
10000 or more primitives for the jobsystem to be of any help, so for
now we never use the jobsystem for culling.
2021-06-08 09:47:16 -07:00
Mathias Agopian 3eceaf20a2 JobSystem: set thread pool count to ncores - 2
We need to reserve at least a code for the user and another one for the
backend thread.
2021-06-08 09:47:16 -07:00
Mathias Agopian bbc4f4f21d JobSystem: remove the DONT_SIGNAL flag
A side effect of this flag was that we had to always use notify_all
when starting a job, instead of notify_one -- in practice, we found
experimentally that more calls to notify_one is cheaper than fewer
calls to notify_all.
2021-06-08 09:47:16 -07:00
Mathias Agopian c5ef1d6252 JobSystem: signal condition with lock held
This seems to improve parallelism on multicores and at least on
Android, doesn't seem to impact performance.
2021-06-08 09:47:16 -07:00
Philip Rideout a4280881d5 Fix BindingType in TypeScript definitions.
Fixes #4102.
2021-06-08 09:14:22 -07:00
Philip Rideout 8ef4c54712 Upgrade emsdk to 2.0.23 2021-06-08 08:36:32 -07:00
Philip Rideout 5ebc8c3e1a Ensure FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB is available.
If your build system does not provide a definition for this macro, then
you cannot compile CommandBufferQueue.cpp.

Since Allocators.h provides a backup value, it needs to be included.
2021-06-08 08:09:51 -07:00
Philip Rideout c1a0e61e8e Fix FixedCapacityVector destructor.
std::allocator::deallocate() expects the same value that was given
during allocate().

Interestingly, this bug did not manifest any issues (even with ASAN) on
some platforms.
2021-06-07 15:56:33 -07:00
Philip Rideout cbcb3e95c6 Fix FixedCapacityVector destructor.
std::allocator::deallocate() expects the same value that was given
during allocate().

Interestingly, this bug did not manifest any issues (even with ASAN) on
some platforms.
2021-06-07 15:56:02 -07:00
Benjamin Doherty fc06298ed4 Bump version to 1.10.3 2021-06-07 11:22:04 -07:00
Benjamin Doherty 4ca87b188c Merge branch 'rc/1.10.2' into release 2021-06-07 11:19:51 -07:00
Benjamin Doherty f1f60c3e0d Turn off warnings as errors for spirv-tools 2021-06-07 11:18:56 -07:00
Benjamin Doherty 76d21b56af Update RELEASE_NOTES for 1.10.2 2021-06-07 11:18:09 -07:00
Benjamin Doherty 02a8cffb18 Update RELEASE_NOTES for 1.10.2 2021-06-07 11:15:22 -07:00
Benjamin Doherty d53f7ecd6a Release Filament 1.10.2 2021-06-07 11:14:43 -07:00
Philip Rideout e297f65d8c getLight() should initialize all fields.
Fixes #4014.
2021-06-03 18:29:05 -07:00
Mathias Agopian 5356f65040 use "debug" namespace for system properties
"filament.perfcounters" is renamed to "debug.filament.perfcounters", 
because otherwise it can't be set by users on recent Android 
versions.
2021-06-03 17:13:52 -07:00
Mathias Agopian 5056abc357 Systrace now uses the official ATrace API
Use the official systrace API when available.
2021-06-02 18:28:39 -07:00
Philip Rideout 46029acd14 VulkanPipelineCache: fix padding with MSVC. 2021-06-02 17:51:54 -07:00
Philip Rideout 28e414c9a5 VulkanPipelineCache: stop using Vk structs for state tracking. 2021-06-02 17:51:54 -07:00
Philip Rideout 29c036d826 VulkanPipelineCache: do not hash uninitialized data.
This fixes an issue caught by a memory sanitizer, whereby padding in the
cache key structure was being consumed by a hashing function. In
practice this oversight was fairly harmless, but this change makes the
code more safe and predictable.
2021-06-02 17:51:54 -07:00
Philip Rideout 831a6d9480 gltfio: fix crash with non-triangles.
Fixes the "triangle count is zero" assertion with the big car model.

We do have nominal support for points and lines, but we should not
attempt to compute tangents for these.

As a reminder, glTF also supports loops, strips, and fans; this is the
only way in which Filament is non-conformant.
2021-06-02 16:47:14 -07:00
Mathias Agopian fb2a95470a bring some improvements to logging from a reverted change
- cleanup Log header file
- lazy initialization of the log buffer
- aggressively resize down the log buffer
2021-06-02 16:40:58 -07:00
Mathias Agopian 4d73583f86 Better systrace logging and small improvements to JobSystem
Tweak how we signal/wakeup threads so we get better parallelism 
on Android.
2021-06-02 16:40:40 -07:00
Mathias Agopian 9a24c4001f Flush the CommandStream in a few strategic places
The CommandStream hold backend commands, but it has a limited size.
With some large models, we can run out of space especially during
initialization.

We can combat this by flushing the command stream regularly. With this
change, we do this every 128 renderable creation.

We also flush the CommandStream just before generating the draw
commands for the frame.

If the buffer is not sized correctly (currently at compile time), this
could cause stalls, which will be logged in DEBUG builds.
2021-06-02 12:16:45 -07:00
Mathias Agopian 4c9ae9dd91 use c++ thread_local now that it's supported on Android
there are cases where thread_local still doesn't work well, but
we're not using those cases.
2021-06-02 12:12:09 -07:00
Mathias Agopian 384d6921f6 add system property to override the backend selection
On Android, set `debug.filament.backend` to the desired backend:
0: default
1: gl/gles
2: vulkan
3: metal
4: noop

example:
   `adb shell setprop debug.filament.backend 2`

This will affect all filament apps on the device.

This sets the backed as if it was set from the public API.
2021-06-02 12:11:51 -07:00
Benjamin Doherty 0ab0e50a4f Turn off warnings as errors for spirv-tools 2021-06-02 11:16:42 -07:00
Benjamin Doherty e0a8284fcf Update filament-specific-changes.patch 2021-06-02 10:58:44 -07:00
Benjamin Doherty eafbf699a2 Turn off warnings as errors for spirv-tools 2021-06-02 10:58:44 -07:00
James Walker 4d3f10477a fix macOS main thread checker warnings with OpenGL (#4011)
* fix runtime warnings about certain NSView methods being called off the main thread

* address code style issues

* fix code style and threading concerns

* Remove unneeded __strong qualifiers, put __weak after the star as recommended by Apple, convert weak to strong before testing for nil to avoid a race

* convert tabs to spaces
2021-06-01 16:35:23 -07:00
Mathias Agopian 9a83805f19 build.sh -C option entirely cleans the android/ directory
All (and only) git-ignored files under android/ are deleted.

This is to prevent a recurring problem where "clean" builds were not
actually clean in some cases.
2021-06-01 14:10:08 -07:00
Mathias Agopian 6fcc2b579d fix LightManager::getFalloff
fixes #4043
2021-06-01 14:09:08 -07:00
Mathias Agopian e04a3d7d3a AttachmentPoint in java and c++ mismatch
fixes #4055
2021-06-01 14:08:51 -07:00
Benjamin Doherty 34f4c06a5c Bump version to 1.10.2 2021-06-01 11:17:32 -07:00
Benjamin Doherty 6de36f1e53 Merge branch 'rc/1.10.1' into release 2021-06-01 11:15:49 -07:00
Benjamin Doherty be61ea2dc8 Update RELEASE_NOTES for 1.10.1 2021-06-01 11:14:29 -07:00
Benjamin Doherty c594d6a07e Release Filament 1.10.1 2021-06-01 11:13:41 -07:00
Benjamin Doherty 2a9a3b1ac2 Update RELEASE_NOTES for 1.10.1 2021-06-01 11:13:04 -07:00
Mathias Agopian ee7feff9cc Revert "improve logs and tls support"
This reverts commit cc6201b0db.

On Android the loggers are not always initialized when several .so are
used, leading to crashes. It's not completely clear what is exactly 
happening.
2021-06-01 10:21:10 -07:00
Philip Rideout 02ce911405 Vk: Fix some synchronization validation warnings.
This fixes most of the warnings that are emitted by the relatively new
SYNCHRONIZATION_VALIDATION feature that LunarG provides.

This commit does not fix a warning that is emitted when SSAO is enabled,
when we sample from the currently bound depth attachment. This one is
tricky to fix.
2021-06-01 08:01:55 -07:00
Mathias Agopian f12ee8f54c unit test for FixedCapacityVector 2021-05-28 09:16:18 -07:00
Mathias Agopian 81a98c6769 panic in release builds when command stream is corrupted
the CommandStream is limited in size and can get corrupted if
that size (default 1 MiB) is exceeded. We used to catch this
only on Debug builds, but this is too serious and unrecoverable, so
it must be caught in Release builds too.

At the point of detection the stream is corrupted, which can cause
the backend to get in an unknown state. But worse, program execution
could end up anywhere because the stream contains function pointers.
2021-05-28 09:16:02 -07:00
Mathias Agopian e3f626934f fix sstream::c_str() when the buffer is first created (#4050) 2021-05-27 22:04:42 -07:00
Romain Guy 94ff2ea6b1 Add support for KHR_materials_specular to glTF (#4046)
* Add support for KHR_materials_specular to glTF

* Add support for IOR to ubershaders

* Update release notes

* Remove unused variable, fix comment
2021-05-27 17:33:24 -07:00
Mathias Agopian cc6201b0db improve logs and tls support
- libutil's slog, cout, cerr, cwarn and cinfo were not thread safe
  at all.

- they are now thread_local

- for that reason the log buffer (which now exists per thread) is not
  allocated until it's needed and is aggressively shrunk.

- removed our thread_local emulation which was incomplete.

- don't expose LogStream publicly.
2021-05-27 15:54:19 -07:00
Mathias Agopian d079df9ce5 make use of FixedCapacityVector in various places 2021-05-27 15:53:53 -07:00
Mathias Agopian 6a2c944bbd A fixed capacity vector.
This is (almost) drop-in replacement for std::vector, the main
difference is that FixedCapacityVector has a fixed (at runtime)
capacity, which makes it a lot more efficient and small for operations
like push_back();

The capacity can be set (and re-set) as usual with reserve(),
but exceeding the capacity when adding items will throw.
The capacity is also set when creating the vector with a size.

In addition a FixedCapacityVector<> instance is only 16 bytes instead
of 24 for std::vector<>.

The aim here is to reduce code bloat.
2021-05-27 15:53:53 -07:00
Mathias Agopian 266fea5e6c replace all size_t with uint32_t in the backend API
this helps save a lot of space in the CommandStream, it especially
matters with scenes with a lot of draw calls.
2021-05-27 15:53:31 -07:00
Mathias Agopian 6da3f85362 RenderPass.cpp got mistakenly renamed, fix that. 2021-05-27 15:53:09 -07:00
Philip Rideout 1d58892fed Vk: repair validation on Android. 2021-05-27 15:18:28 -07:00
Philip Rideout ff1b6d28a8 Vk: fix handling of instance extensions. 2021-05-27 11:27:01 -07:00
Ben Doherty ff935e05f2 image: Respect sRGB option for compressed formats (#4039) 2021-05-26 20:37:58 -07:00
Mathias Agopian d378f5e4bb repair CommandStream logging 2021-05-26 20:33:47 -07:00
Philip Rideout 44eee6550c Vk: emit best practices warnings when validation is enabled. 2021-05-26 15:48:33 -07:00
Philip Rideout 260b8fb672 VulkanCommands: add diagnostics. 2021-05-26 15:48:33 -07:00
Mathias Agopian 2f240acc43 increase max job count to 16384 from 4096
the cost is only 2 bytes per job.
2021-05-26 12:18:05 -07:00
Mathias Agopian 189b528b3d improve handle creation in opengl backend
- we issue better logs when the allocation fails
- the pool selection is now performed at compile time
2021-05-26 12:17:50 -07:00
Philip Rideout 2b265d54a1 VulkanSwapChain: simplify and repair swap chain resizing.
Newer versions of MoltenVK seem to behave similarly to Android,
so there's no need to separate codepaths. I tested this by not only
resizing the window, but also dragging between displays with different
pixel ratios, and rotating on Android with & without `orientation` in
`configChanges`. I also tried our headless unit tests.
2021-05-26 10:34:39 -07:00
Philip Rideout c61d67301f sample-gltf-viewer: fix lifetime cycle for RemoteServer.
The sample would crash when removing `orientation` from `configChanges`
and rotating the device, because the old RemoteServer would still be
alive when creating the second one, so the WebSocket port would be
unavailable.
2021-05-26 09:22:08 -07:00
Philip Rideout 5f3d8096f3 Vulkan: big refactor of VulkanSwapChain.
This has no behavioral changes, it's mostly just moving code around,
except that VulkanDriver::createSwapChain() is simpler now, and some
of the logic in beginRenderPass() makes more sense too.

This removes the useless `VulkanSurfaceContext` structure by moving
its data directly into `VulkanSwapChain`. Also created a new cpp file
just for the swap chain wrapper, which makes `VulkanContext` much less
unwieldy.
2021-05-25 20:04:08 -07:00
Alexey PelykhandFabian Rueckert 6e5b05d0b5 KTXLoader.getSphericalHarmonics
Co-authored-by: Fabian Rueckert <fabi.rueckert@gmail.com>
2021-05-25 20:02:19 -07:00
Benjamin Doherty 6bbae681ef Fix HelloCocoaPods iOS sample 2021-05-25 17:19:52 -07:00
Philip Rideout 097fac4cca Add support for drag-and-drop HDR.
This adds Java bindings for IBLPrefilterContext and uses them
in `sample-gltf-viewer`.
2021-05-25 12:46:52 -07:00
Philip Rideout 97515b0d7d Vulkan: minimize calls to vkCmdSetScissor. 2021-05-25 12:28:52 -07:00
Philip Rideout 3500101816 Repair live WebGL demos.
Fixes #4027.
2021-05-25 12:22:05 -07:00
Romain Guy 1cebf51672 Update README.md 2021-05-24 16:08:42 -07:00
Mathias Agopian 3b59dff577 fix some build warnings 2021-05-24 13:25:11 -07:00
Mathias Agopian cd01ad06fd update SPIRV-CROSS to latest
SHA: ff61890722a91e97c44940494be5b6eed0d5ff5b
2021-05-24 13:24:54 -07:00
Benjamin Doherty 84b73a3770 Bump version to 1.10.1 2021-05-24 10:52:02 -07:00
Benjamin Doherty 662a10e273 Merge branch 'rc/1.10.0' into release 2021-05-24 10:49:10 -07:00
Benjamin Doherty 331332fab0 Update RELEASE_NOTES for 1.10.0 2021-05-24 10:48:45 -07:00
Benjamin Doherty f3572876a1 Release Filament 1.10.0 2021-05-24 10:48:03 -07:00
Benjamin Doherty ecce02502e Update RELEASE_NOTES for 1.10.0 2021-05-24 10:47:39 -07:00
Ben Doherty c827004821 Add getPlatform API to Engine, move functionality into MetalPlatform (#4007)
This change allows access to the Engine's underlying Platform object. This is useful for Metal clients to access a new method on MetalPlatform, createAndEnqueueCommandBuffer.
2021-05-24 10:36:56 -07:00
Mathias Agopian 786eee4eb9 Fix a crash when using custom rendertargets
This was introduced recently.

Fix #3962
2021-05-24 09:53:54 -07:00
Mathias Agopian 92d2de5279 fix MRTs >= COLOR4 in the GL backend
These would be ignored.
2021-05-24 09:53:05 -07:00
Ben Doherty f4070f3fb5 Fix Automation test_settings (#4009) 2021-05-24 09:10:25 -07:00
Alexey Pelykh 856a6567a1 LightManager: cone angles API (#3979) 2021-05-22 22:04:50 -07:00
Mathias Agopian 363edb1427 added MaterialInstance::duplicate(...)
It's now possible to duplicate a MaterialInstance.
2021-05-21 22:57:28 -07:00
Mathias Agopian c209232950 a way to keep the content of custom RenderTarget attachments (#4008)
* a way to keep the content of custom RenderTarget attachments

Until now, all attachments of RenderTarget beyond COLOR0 were discarded
after rendering.

With this change, attachment whose texture has the SAMPLEABLE usage
bit set will be kept.

Fixes #3962
2021-05-21 22:54:52 -07:00
Ben Doherty 3f9120b129 Fix focusDistance warning in gltf_viewer (#4005) 2021-05-21 15:31:46 -07:00
Philip Rideout d17875aea1 ImGuiHelper: fix support for custom images.
The texture binding in the material instance needs to be restored to the
glyph atlas when a custom image is not in use.
2021-05-21 12:49:37 -07:00
Philip Rideout b1f0f905e5 HDRLoader: use HDRDecoder, not stb. 2021-05-21 12:36:43 -07:00
Philip Rideout c71c7c70d4 imageio: split HDRDecoder into its own file 2021-05-21 12:36:43 -07:00
Philip Rideout 613ae56cc1 Add HDRLoader for JVM clients.
This adds support for decoding HDR files, dropping them into the remote
web page, and sending them over the wire.  However the decoded results
are not yet passed into IBLPrefilterContext, that will be subsequent
PR.

Rename KtxLoader to KTXLoader.

The remote UI has been tweaked a bit, so that it shows a more helpful
message when disconnected.
2021-05-21 12:36:43 -07:00
Philip Rideout 6607002939 ImGuiHelper: fix support for custom images.
The texture binding in the material instance needs to be restored to the
glyph atlas when a custom image is not in use.
2021-05-21 11:49:14 -07:00
Philip Rideout 2e40bb46e7 Fix minor typos. 2021-05-21 11:34:08 -07:00
Philip Rideout b8897a68f9 matc: detect missing end brace.
matc was failing to report certain kinds of syntax errors and would
read out-of-bounds memory.

This change casuses the flare material to fail.
2021-05-21 09:20:33 -07:00
Philip Rideout 720288c420 JNI Cleanup: Remove useless constructors, publicize RenderTarget.
(1)
The C++ RenderTarget API might be used by an external Android library
such as filament-utils-android and therefore needs to be in the map
file.

(2)
Texture, Skybox, and IndirectLight each had two "nativeObject"
constructors which exist for the benefit of filament-utils-android,
but each of these classes only need one nativeObject constructor.
2021-05-20 15:18:34 -07:00
Romain Guy 97651a0ff4 Use CIE 2006 10-deg CMFs instead of CIE 1931 2021-05-19 12:42:41 -07:00
Ben Doherty 84efd4871e API CHANGE: remove some Camera, Engine, and View deprecated APIs (#3965) 2021-05-19 12:02:13 -07:00
Philip Rideout 3125c44ce1 Vulkan: change depth layout to permit feedback loops.
Vulkan does not permit the GENERAL layout when the depth buffer that is
currently being used for depth testing is also sampled from.

This (finally) fixes the last validation error that we were silencing,
which would occur only when SSAO was enabled.
2021-05-18 16:38:42 -07:00
Philip Rideout d909b38d57 Vulkan: enable the maintenance extensions if available.
This prevents potentially bogus validation messages from arising.
2021-05-18 16:36:12 -07:00
Ben Doherty 5572ef8574 API CHANGE: remove some Camera, Engine, and View deprecated APIs (#3965) 2021-05-18 16:02:49 -07:00
Philip Rideout 3c4192bd0e matc: detect missing end brace.
matc was failing to report certain kinds of syntax errors and would
read out-of-bounds memory.

This change casuses the flare material to fail.
2021-05-18 10:58:15 -07:00
Philip Rideout 3fc9dc3684 Repair build when FILAMENT_VULKAN_VERBOSE is enabled. 2021-05-17 18:13:51 -07:00
Benjamin Doherty 85ea5a6b70 Bump version to 1.10.0 2021-05-17 11:00:42 -07:00
Benjamin Doherty 77891acb92 Merge branch 'rc/1.9.25' into release 2021-05-17 10:57:30 -07:00
Benjamin Doherty a06e01a196 Update RELEASE_NOTES for 1.9.25 2021-05-17 10:57:02 -07:00
Benjamin Doherty 034b6892f4 Release Filament 1.9.25 2021-05-17 10:55:58 -07:00
Benjamin Doherty 74fe102035 Update RELEASE_NOTES for 1.9.25 2021-05-17 10:54:38 -07:00
Philip Rideout 25cc554925 WASM: fix "Missing field" error for lensFlare. 2021-05-17 10:06:56 -07:00
Ben Doherty bd8ea711fd Add a FILAMENT_SUPPORTS_OPENGL CMake option (#3966) 2021-05-15 14:40:06 -07:00
Mathias Agopian c1347e55cb add java API for Texture::Builder::import()
deprecate Stream::stream(intptr_t).

This method was needed for ARCore back in the days, but there is now a
zero-copy way to achieve the same thing. This API shouldn't be used anymore.
2021-05-14 17:26:30 -07:00
Philip Rideout afbd6e6606 gltfio: fix morphing bugs uncovered by MorphStressTest.
The code that determined the "base slot" (i.e. the buffer object index
for the first morphed attribute) was very fragile and buggy.
MorphHelper now simply looks up the slot index in a stored mapping,
rather than trying to mimic the AssetLoader to determine the base slot.

Until now, most of the models we tested against only morphed the
position attribute, and never had a large set of target weights that
could be non-zero in a given time slice.
2021-05-14 17:05:27 -07:00
Mathias Agopian d6c5cb7778 workaround a shader compiler bug on qualcomm h/w 2021-05-14 16:58:40 -07:00
Mathias Agopian 43d47745dd API CHANGE: remove deprecated populateTangentQuaternions 2021-05-14 13:35:25 -07:00
Mathias Agopian f0d99070e4 Use a UBO instead of a texture for froxels data structure
MATERIAL BREAKAGE: this change breaks materials

In order to use one less sampler, we now use a UBO instead of a texture
to store the "froxel records". Currently this UBO is limited to 16KiB
vs. 64KiB before with the texture.

We also handle running out of record space better, by using a predefined
record that has all the lights in the scene. This way the scene will be
rendered properly, albeit at a potentially large performance cost.
2021-05-14 11:20:24 -07:00
Alexey Pelykh 6a49d67c6c Allow using specific NDK version, for CI don't use latest but required (#3950)
* Allow using specific NDK version, for CI don't use latest but required

* Default to highest available NDK version within same major release sequence

* Refactor NDK version selection
2021-05-14 11:06:31 -07:00
Philip Rideout 6b7c1b21cb VulkanPipelineCache: fix unbound pipeline error. 2021-05-13 23:33:06 -07:00
Philip Rideout b7d1b4ca1a VulkanPipelineCache: create dummy sampler. 2021-05-13 23:13:49 -07:00
Philip Rideout 8a04d5761b Fix validation on Windows. 2021-05-13 18:25:47 -07:00
Benjamin Doherty 8d8729be8e Remote UI: update viewer with new URL input 2021-05-13 16:46:26 -07:00
Ben Doherty d4325de47d Add URL input to Filament Remote Viewer (#3955) 2021-05-13 16:27:46 -07:00
Philip Rideout e29c76465b Minor improvement to Vulkan robustness. 2021-05-13 13:16:57 -07:00
Philip Rideout a220407aef Vulkan: Fix bistro, implement descriptor pool growth. 2021-05-13 12:28:12 -07:00
Philip Rideout 4df214003e Revert accidental Vulkan diagnostic commit.
This reverts commit 59a6758fce.
2021-05-13 08:56:48 -07:00
Philip Rideout 182250b9c0 VulkanPipelineCache: minor cleanup. 2021-05-13 08:34:02 -07:00
Philip Rideout 59a6758fce DO NOT COMMIT 2021-05-13 08:33:57 -07:00
Philip Rideout 73aa996444 VulkanPipelineCache: add a descriptor set arena.
This fixes the "descriptor set fragmentation" error that we would see on
Mali.

The pipeline cache now maintains an arena of descriptors that can be
re-used. We call this an "arena" to avoid confusion with
VkDescriptorPool.

Descriptors are returned to the arena only when they are not in use
by any pending command buffer. This allows them to be mutated safely
without worrying about synchronization.
2021-05-12 16:48:59 -07:00
Ben Doherty d787a521b5 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:16:30 -07:00
Ben Doherty 46e52c71e1 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:15:49 -07:00
Ben Doherty 08769ec35e Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:15:10 -07:00
Philip Rideout 3aa18eafb3 VulkanPipelineCache: refactor and simplify.
The API of the pipeline cache is now easier to use. Internally, it now
maintains separate pipeline and descriptor bindings for each command
buffer, since that's how Vulkan works.
2021-05-11 12:46:48 -07:00
Philip Rideout 8d4a0e5aa9 Vulkan: fix uninitialized cmd buffer handle. 2021-05-11 11:03:17 -07:00
Ben Doherty e8183d09c2 Fix MissingRequiredAttributes backend test with Metal (#3943) 2021-05-11 10:49:47 -07:00
Philip Rideout 5f1da1dfc0 VulkanDriver: Misc cleanup.
This cleanup is being done in preperation for a new descriptor set
strategy.
2021-05-10 18:26:12 -07:00
Philip Rideout 1dad27a172 Repair WebGL and fix potential INVALID_OPERATION.
We should take care not to call glVertexAttribPointer when there is
no bound ARRAY_BUFFER (i.e. when its binding is zero).

This fixes the black screen seen with some WebGL samples after
the recent memory leak fix related to the new BufferObject API.
2021-05-10 13:38:56 -07:00
Philip Rideout c1c5776439 Serialization: enforce correctness for bool.
If expecting a bool and receiving anything other than true or false,
this is invalid and should fail. This change triggered a unit test
failure which uncovered several actual problems.
2021-05-10 13:27:41 -07:00
Mathias Agopian da418fc7f2 fix another serialization bug 2021-05-10 12:15:52 -07:00
Philip Rideout fcaae825b7 Repair WebGL and fix potential INVALID_OPERATION.
We should take care not to call glVertexAttribPointer when there is
no bound ARRAY_BUFFER (i.e. when its binding is zero).

This fixes the black screen seen with some WebGL samples after
the recent memory leak fix related to the new BufferObject API.
2021-05-10 12:13:00 -07:00
Philip Rideout f5ee074674 Remote UI: fix lensFlare serialization. 2021-05-10 12:11:25 -07:00
Mathias Agopian 0c787b94b8 update remote ui 2021-05-10 11:22:55 -07:00
Philip Rideout 02f5f07db0 WASM: fix "Missing field" error for lensFlare. 2021-05-10 09:28:48 -07:00
Philip Rideout a97591a193 Fix minor logic warning. 2021-05-10 08:36:34 -07:00
Benjamin Doherty 60d230b380 Bump version to 1.9.25 2021-05-07 21:42:48 -07:00
Benjamin Doherty d7cb38e706 Merge branch 'rc/1.9.24' into release 2021-05-07 21:39:17 -07:00
Benjamin Doherty 80485bf520 Update RELEASE_NOTES for 1.9.24 2021-05-07 21:38:43 -07:00
Benjamin Doherty ce00cca6ee Update RELEASE_NOTES for 1.9.24 2021-05-07 21:36:49 -07:00
Benjamin Doherty 401bd8ce73 Bump version to 1.9.24 2021-05-07 21:35:30 -07:00
Mathias Agopian c23a7343d4 update remote ui 2021-05-07 16:57:05 -07:00
Romain Guy 75a24ee41f Update RELEASE_NOTES.md 2021-05-07 16:51:17 -07:00
Mathias Agopian 7e9a69df64 fix lens flare Settings writer 2021-05-07 16:18:52 -07:00
Mathias Agopian 12bf8d9659 DoF: don't use hole filling for the background
It did improve the look of the blur on far way geometry in some case,
but overall it hurts a lot more.
The case that falls appart is when everything is in the background layer
but there is a large depth difference anyways.
This creates a halo around edges.

Fixes #3221
2021-05-07 16:18:34 -07:00
Mathias Agopian d1c8d42bd2 update remote ui 2021-05-07 15:19:15 -07:00
Mathias Agopian c0fe2d1c09 new screen space lens flare effect
- this PR also improves bloom slightly


Note: for now this is not available on WebGL due to complications
in the bloom pass.
2021-05-07 13:20:16 -07:00
Philip Rideout 812f0d577b VulkanTexture: support format conversion via vkCmdBlitImage. 2021-05-07 12:46:37 -07:00
Philip Rideout 4a25ba1111 Minor VulkanTexture simplification. 2021-05-07 12:46:37 -07:00
Philip Rideout 0b4f3f76fc Vulkan: enable the mutableComparisonSamplers feature. 2021-05-07 11:09:17 -07:00
Philip Rideout e7e19a88e6 Add missing files to BlueVK. 2021-05-07 09:22:23 -07:00
Philip Rideout 4295eaa311 Vulkan refactor 2 of 2 (Binder => PipelineCache) 2021-05-06 18:47:19 -07:00
Philip Rideout 43e78f7a93 Vulkan refactor 1 of 2 (VulkanTexture and VulkanConstants) 2021-05-06 18:47:19 -07:00
Philip Rideout d627d57bad Second memory leak fix. (#3906)
Fixes #3888.
2021-05-06 14:25:46 -07:00
Philip Rideout 0a305a710a VulkanCommands now stalls when absolutely necessary. 2021-05-06 14:24:42 -07:00
Ben Doherty ef45d695d0 metal: Query max color render targets (#3895) 2021-05-06 11:33:49 -07:00
Philip Rideout ac50cb69f7 Vulkan: fix blit and readPixels for cubemaps. (#3903) 2021-05-06 11:16:28 -07:00
Philip RideoutandBen Doherty 9fc6e398c6 BackendTest: add blit cubemap test. (#3901)
* BackendTest: add blit cubemap test.

This test is similar to manual mipmap generation for cubemaps and
can uncover issues that are provked by libiblprefilter. It simply
dumps out a PNG that can be manually inspected.

Also, this test does not do makeCurrent / commit and is therefore
similar to renderStandaloneView.

* Update filament/backend/test/test_Blit.cpp

Co-authored-by: Ben Doherty <bendoherty@google.com>

Co-authored-by: Ben Doherty <bendoherty@google.com>
2021-05-06 10:38:55 -07:00
Ben Doherty e06b948343 Use 16 bit format for VSM (#3899) 2021-05-06 10:33:11 -07:00
Philip Rideout 28ca9df5a0 Second memory leak fix. (#3906)
Fixes #3888.
2021-05-06 10:15:20 -07:00
Romain Guy c66915209e Update our build to the latest and greatest (#3902)
The new requirements are as follow:
- CMake 3.19
- Ninja 1.10
- Android Studio 4.2
- Android NDK 22.1
- Gradle 7.0
- Kotlin 1.5
2021-05-06 10:13:10 -07:00
Philip Rideout cb4ffe39f4 Fix build break. 2021-05-05 15:00:59 -07:00
Philip Rideout e07f91ce8b Vulkan: use more aggressive barriers (Mali). 2021-05-05 14:22:29 -07:00
Philip Rideout 03fcbfea62 Regenerate BlueVK and update MoltenVK binaries. (#3897)
LunarG just released a new SDK so we're updating everything.
2021-05-05 14:15:52 -07:00
Philip Rideout f9d05a879a Vulkan: add a barrier after each render pass. (#3898)
The need for this barrier is fairly obvious, so it is surprising that
its absence has not caused problems on any platform except Mali.
2021-05-05 14:11:36 -07:00
Philip Rideout 8ffc776f1c Fix horrible memory leak in the GL driver. (#3894)
This leak was introduced in the following PR on April 7.
https://github.com/google/filament/pull/3775

The guilty party has been contacted and properly admonished for his
transgression.

This was tested by adding the following code after applyAnimation in
gltf_viewer.cpp

        static int nframes = 0;
        if (!gpath.empty() && nframes++ > 100) {
            static int count = 0;
            printf("reloading %d\n", count++);
            nframes = 0;
            app.resourceLoader->asyncCancelLoad();
            app.resourceLoader->evictResourceData();
            app.viewer->removeAsset();
            app.assetLoader->destroyAsset(app.asset);
            loadAsset(gpath, app);
            loadResources(gpath, app);
        }
2021-05-04 18:22:08 -07:00
Philip Rideout 7a8dd52c4c Fix horrible memory leak in the GL driver. (#3894)
This leak was introduced in the following PR on April 7.
https://github.com/google/filament/pull/3775

The guilty party has been contacted and properly admonished for his
transgression.

This was tested by adding the following code after applyAnimation in
gltf_viewer.cpp

        static int nframes = 0;
        if (!gpath.empty() && nframes++ > 100) {
            static int count = 0;
            printf("reloading %d\n", count++);
            nframes = 0;
            app.resourceLoader->asyncCancelLoad();
            app.resourceLoader->evictResourceData();
            app.viewer->removeAsset();
            app.assetLoader->destroyAsset(app.asset);
            loadAsset(gpath, app);
            loadResources(gpath, app);
        }
2021-05-04 17:50:46 -07:00
Mathias Agopian ef48cad322 cleanup bloom
- remove areFeedbackLoopsSupported from backend API, since this is only
  a problem on WebGL

- binary only include either the regular or webgl version of the bloom
  code, never both, which should save some binary size

- bloom pass is now called outside of the colorGrading pass, which is
  cleaner and makes it available for other pass, should they need it
  (not the case right now).

- always pass ColorGradingConfig to all color grading related methods,
  instead of individual parameters

- very minor optimization in bloom shader
2021-05-04 17:25:45 -07:00
Ben Doherty c39d692757 ios: Don't evict gltfio materials between asset loads (#3893) 2021-05-04 16:33:10 -07:00
Ben Doherty 4c1d8f310a Fix Filament remote file upload (#3891) 2021-05-04 14:52:42 -07:00
Mathias Agopian 1e1542fe16 ipbprefilter: simplify cpu side
- move kernel weight computation to the gpu side as a small cost, in
order to simplify the CPU side and reduce the binary size.

- skip samples with a weight of 0, which is a completely coherent 
check.

- fix a typo in move ctor
2021-05-04 13:12:39 -07:00
Mathias Agopian 647ac34c8c improve Texture::generateMipmap fallback
We now handle SAMPLER_2D_ARRAY, but SAMPLER_3D is still unsupported.
2021-05-04 10:53:27 -07:00
Mathias Agopian ea34691625 Support a maximum of 8 render buffers (from 4)
We chose 8 renderbuffer because it seems to be commonly supported
on mobile gpu and is more than 6 which is needed for generating
cubemaps. 4 was the minimum guaranteed by ES3.0.

The main changes here are:
- TargetBufferFlags is now a uint32_t instead of uint8_t
- The number of render buffer supported by filament and supported by
  the hardware can now be different. Applications/users now must
  query this value if more than 4 is needed.
- added a backend query (used gl terminology)


This is a redo of a previous attempt. There was an issue in the GL
backend that caused MRT to fail on some devices.
2021-05-04 10:53:07 -07:00
Philip Rideout 4557255ce1 Vulkan: fix initial image layout for cubemaps. (#3885) 2021-05-04 09:45:15 -07:00
Philip Rideout 4cb951461b Vulkan: enable anisotropic filtering if supported. (#3884) 2021-05-04 09:43:52 -07:00
Philip Rideout 750dcbb9d8 Vulkan: fix image view type for render target attachments. (#3883)
When rendering into a single cubemap face, we should use
VK_IMAGE_VIEW_TYPE_2D rather than VK_IMAGE_VIEW_TYPE_CUBE.
2021-05-04 09:41:54 -07:00
Romain Guy 459f70f7b4 Update docs 2021-05-03 17:55:32 -07:00
Mathias Agopian 61748fa7dc improve opengl backend program failure logs 2021-05-03 15:10:14 -07:00
Benjamin Doherty be032b52c1 Bump version to 1.9.24 2021-05-03 10:42:19 -07:00
Benjamin Doherty 4388e81e5f Merge branch 'rc/1.9.23' into release 2021-05-03 10:40:49 -07:00
Benjamin Doherty a36d432b88 Update RELEASE_NOTES for 1.9.23 2021-05-03 10:40:15 -07:00
Benjamin Doherty b3f43eea13 Release Filament 1.9.23 2021-05-03 10:39:26 -07:00
Benjamin Doherty 71a185d139 Update RELEASE_NOTES for 1.9.23 2021-05-03 10:38:59 -07:00
James Walker df3c7e2c1c Improve documentation formatting
* Improve doxygen formatting of docs for Renderer::readPixels

* slight tweaks
2021-05-03 09:28:27 -07:00
Philip Rideout cbc4c75a7e Vulkan: fix logic in Disposer, simplify StagePool. 2021-05-01 19:55:17 -07:00
Mathias Agopian e068d8b698 ssao: fix a typo in the accurate normal reconstruction 2021-04-30 17:15:27 -07:00
Mathias Agopian 06e9a3d31f ssao: high quality upsampling didn't work when low pass was disabled 2021-04-30 17:15:27 -07:00
Philip Rideout e5ac49f86d Vulkan: big refactor for command buffer management. (#3875)
This removes a lot of caveats that we had in the Vulkan backend. Many
driver API calls were unsupported due to a lack of command buffer, but
in the new scheme, a command buffer can *always* be made available,
and there's no weird separate "work and swap chain command buffers".

Here's how various driver API entry points now map into Vulkan actions:

```
makeCurrent => Acquire Swap Chain.
beginFrame => Do nothing.
endFrame => Submit command buffer and create a new one.
commit => Submit commit buffer again if necessary, Present Swap Chain.
```

This handles both copyFrame (which does not do beginFrame / endFrame)
and renderStandaloneView (which does not do makeCurrent / commit).
2021-04-30 15:31:24 -07:00
Ben Doherty 7fdc63b6ae Fix incorrect units documented for getIntensity (#3870) 2021-04-30 10:09:52 -07:00
Ben Doherty 808abdb6d7 Fix memory leak inside utils::details::SafeString (#3871) 2021-04-29 14:42:07 -07:00
Ben Doherty 037982a0ef Add gltf-viewer iOS sample (#3873) 2021-04-29 12:13:34 -07:00
Philip Rideout 5f86233218 Enable Vulkan in our Android Release package. (#3864)
This makes release builds consistent with continuous builds and default
local builds. It also makes it easier to test the Vulkan backend.
Clients who need a smaller APK size can always make their own build.

This also makes filament-android-release.aar go from 1.8M to 2.3M.
Note that we are now including bluevk, vkshaders (for the blit shader),
smol-v (for SPIRV decompression) and vk_mem_alloc (for mem allocation).
2021-04-27 23:00:57 -07:00
Mathias Agopian 8bd73a44c9 Revert "Support a maximum of 8 render buffers (from 4)" (#3868)
This reverts commit 6f948c101f.

This is breaking rendering on Android when certain postprocessing
effects are disabled (e.g. bloom/msaa/dof).
2021-04-27 22:56:10 -07:00
Mathias Agopian f1984b19cc lightbulb: clear background
Fixes #3849
2021-04-27 20:50:48 -07:00
Mathias Agopian c2330fe55a ssao: improve LOW and HIGH quality levels
Simply tweak the "spiralTurns" parameter, empirically to improve the
noise pattern produced by the gradient noise. In turn, this helps the
gaussian filter.
2021-04-27 20:50:03 -07:00
Mathias Agopian dc56408d5f ssao: implement accurate normal reconstruction
This removes "false AO" effect on geometry edges.
Currently this is enabled on desktop only (quality == high).
2021-04-27 20:50:03 -07:00
Romain Guy f5adbbddb8 Fix typo 2021-04-27 20:33:58 -07:00
Mathias Agopian 036bfa9b20 Materials now have a quality property.
We used to have that before, but it was hardcoded and depended on
mobile vs. desktop.
With this change, users can set the quality on the material itself.
The default match the current settings. There are 3 quality levels:

low: enables optimization that might not be 100% correct 
     (e.g. abs(x) instead of sqrt(x*x))

normal: like low, but doesn't sacrifices correctness.

high: could be improved upsampling, etc...
2021-04-27 14:20:50 -07:00
Mathias Agopian 2d9064d2bf Cleanup some shader #defines
- create a new FILAMENT_HAS_FEATURE_TEXTURE_GATHER, which can be used
  in the shaders to use textureGather.

- A new TARGET_GLES_ENVIRONMENT and TARGET_GL_ENVIRONMENT in addition
  to TARGET_METAL_ and TARGET_VULKAN_, for completeness.

- Rename TARGET_LANGUAGE_SPIRV to FILAMENT_VULKAN_SEMANTICS and add
  FILAMENT_OPENGL_SEMANTICS for completeness.

- expose the shader model to shaders as: FILAMENT_SHADER_MODEL_ES30 and
  FILAMENT_SHADER_MODEL_GL41

Use these new #define where appropriate.

The main change here is that TARGET_MOBILE is now only used for dealing
with the `mediump` default on mobile.

This change also enables textureGather on Metal.
2021-04-27 14:20:50 -07:00
Mathias Agopian 6f948c101f Support a maximum of 8 render buffers (from 4)
We chose 8 renderbuffer because it seems to be commonly supported
on mobile gpu and is more than 6 which is needed for generating
cubemaps. 4 was the minimum guaranteed by ES3.0.

The main changes here are:
- TargetBufferFlags is now a uint32_t instead of uint8_t
- The number of render buffer supported by filament and supported by
  the hardware can now be different. Applications/users now must
  query this value if more than 4 is needed.
- added a backend query (used gl terminology)
2021-04-27 12:15:22 -07:00
Romain Guy 9c123a59ab New experimental tone mapper (#3850)
* New experimental tone mapper

The new tone mapper proposed in this change replaces Uchimura (see
below) and is composed of two distinct algorithms:

- The first is the customizable compression curve from Timothy Lotte
  (from GDC 2015). The curve's default parameters were chosen to
  match the overall appearance (contrast) of the ACES curves used
  as our current default tone mapper. This was done to provide a
  good migration path to making this new solution the default in
  a future version of Filament.
  The compression curve can be customized via its contrast, shoulder,
  input middle gray, output middle gray, and maximum "HDR value"
  (scene referred).
  It is important to note that the compression is only applied to
  the luminance of the input scene referred value.
- The second is a novel approach by Troy Sobotka called Exposure
  Value Invariant Luminance Scaling (or EVILS). This solution works
  on the largest chromatic channel of the input value as opposed
  to mapping all RGB channels as we do in our other tone mappers.
  The algorithm effectively scales all channel by a ratio that
  depends on both the compressed luminance from the first stage
  and the luminance of input value normalized by the largest
  channel.

This new solution offers important benefits as it manages to
preserve chromaticity for high input values. It is also designed
to provide a desirable rolloff to white on overexposure. This
means that even without gamut mapping, this solution avoids many
hue skews (red to orange, blue to purple, etc.). The results
provided by this solution are much more natural and make using
other color grading tools much easier.

* Use std::pow instead of pow

* Fix Web builds
2021-04-26 18:09:37 -07:00
Philip Rideout 4006018907 Fix Java warnings. (#3856) 2021-04-26 13:49:49 -07:00
Mathias Agopian 02c1e1dc60 Improve libiblprefilter
- move public headers from filament/foo to filament-foo/
  to avoid confusion with libfilament's headers
- add support for equirectangular to cubemap conversion
- add support for using an .hdr file directly in all our samples
2021-04-26 12:17:42 -07:00
Ben Doherty 03d74f1313 Update web docs, add note about shadowMultiplier (#3855) 2021-04-26 12:05:25 -07:00
Benjamin Doherty d2cf5985ac Bump version to 1.9.23 2021-04-26 10:55:10 -07:00
Benjamin Doherty debcbb8e5c Merge branch 'rc/1.9.22' into release 2021-04-26 10:52:43 -07:00
Benjamin Doherty 4f2460a23c Update RELEASE_NOTES for 1.9.22 2021-04-26 10:52:37 -07:00
Benjamin Doherty f68dbe1902 Release Filament 1.9.22 2021-04-26 10:52:37 -07:00
Benjamin Doherty b9dd62c7d3 Update RELEASE_NOTES for 1.9.22 2021-04-26 10:47:11 -07:00
Mathias Agopian d589634968 don't set sun parameters if we didn't have SH
The parameters would turn out as NaN.
We might need a better API for this, but it's
never okay to set NaN values.
2021-04-26 10:44:12 -07:00
Benjamin Doherty dc2b430f34 Bump version to 1.9.22 2021-04-26 10:39:16 -07:00
Mathias Agopian 9914eb84a4 Fix documentation for getNormalizedViewportCoord
Fixes #3821
2021-04-23 22:39:01 -07:00
Mathias Agopian 0a6886e43b improve the importance sampling code
- fix a lod selection bug
- add interleaved gradient noise when sampling the brdf
- compute the diffuse using importance sampling too
2021-04-23 15:21:07 -07:00
Mathias Agopian bcd4b65f7d fix a memory corruption introduced recently
fixes #3844
2021-04-23 15:20:51 -07:00
Philip Rideout 820717df0e gltfio: Use the new Transcoder API in some cases. (#3840)
Fixes issue seen with Vulkan + the quantized version of Avocado.

We already support the quantized glTF extension, which is when this
comes up. Technically this is only needed for Vulkan but gltfio does
not (and should not) know which backend is being used, so we simply
apply these transformations assuming the worst.

In practice this code usually won't be activated, and if even when it
is, it won't hurt loading time as much as other things like large
textures.
2021-04-22 16:11:34 -07:00
Philip Rideout 6178ba4a6b Add Transcoder API for C++ clients. (#3837)
* Add Transcoder API for C++ clients.

We will add JavaScript and Java support in a later PR.

* Transcoder: use fixed inner loop in some cases.

This lets clang produce better ARM code for common cases.

* Transcoder: stronger typing in Config, etc.

* Transcoder: add UTILS_RESTRICT and noexcept.
2021-04-22 13:29:52 -07:00
Mathias Agopian 6f14c1fa91 don't hardcode drawbuffer to 4
This is the first step at trying to un-hardcode the number of drawbuffer
we support. The ultimate goal is to go from currently 4 to 8.

Until now the maximum render buffer supported was the same than the actual
number of render buffer supported. At some point in the future this will
change, it this will have to be dynamic.

This change is to allow rendering a cubemap in a single pass on h/w that
support it. Many mobile GPU support 8 draw buffers.
2021-04-22 11:59:10 -07:00
Philip Rideout 6a94c77b1e Vulkan: fix VK_FORMAT to correctly handle non-integer types.
The SCALED formats are useful when the shader consumes a float, but
you want to give it an integer.
2021-04-22 11:18:49 -07:00
Philip Rideout c3d6c853ab gltfio: robustness improvements for Draco meshes.
These changes are motivated by #3815.

See also:
    https://github.com/KhronosGroup/glTF-Blender-IO/issues/1326
    https://github.com/KhronosGroup/glTF-Blender-IO/issues/1345
2021-04-21 18:09:45 -07:00
Mathias Agopian 9575a7453e add an option to control the strength of the importance sampling
This is very useful either with a low sample count, or with a very
HDR image.
2021-04-21 15:41:43 -07:00
Mathias Agopian cfd9689444 fix several bugs in the gpu prefilter code
- the miplevel wasn't computed correctly
- the random rotation was incorrect
- the default HDR compression was too aggressive
- better validation of the input cubemap
2021-04-21 15:41:43 -07:00
Mathias Agopian c819265597 Add README.md file and fix some comments 2021-04-21 15:41:43 -07:00
Mathias Agopian 0427787cb7 Generate the kernel texture on the GPU
This avoids having to upload data from the cpu.
2021-04-21 15:41:43 -07:00
Mathias Agopian e372cc25f2 more fixes from review comments
- get rid of createREflectionsTextures public api
- use default material instance
2021-04-21 15:41:43 -07:00
Mathias Agopian b98d9dcff3 clarify requirements 2021-04-21 15:41:43 -07:00
Mathias Agopian 91b08705da rename library to filament-iblprefilter 2021-04-21 15:41:43 -07:00
Mathias Agopian 503abb3c94 rename a few things 2021-04-21 15:41:43 -07:00
Mathias Agopian 4b8d98af8c compute all lod kernel at once
we now store the kernel for each lod in a texture, this has several
advantages:
- the texture can be reused, so we can amortize that cost a bit
- we could generate the texture with a shader, so that we don't
  have to do any texture uplaod (TBD).
2021-04-21 15:41:43 -07:00
Mathias Agopian ced6c3de1f GPU based IBL prefiltering library 2021-04-21 15:41:43 -07:00
Mathias Agopian f8ced1170e fix typo that broke java apps 2021-04-21 15:15:01 -07:00
Ben Doherty a166fcdcdf Specific sampler precision only on GLES (#3829) 2021-04-21 10:11:55 -07:00
Ben Doherty faac96730a Disable VSM MSAA on Adreno devices (#3816) 2021-04-21 10:06:03 -07:00
Mathias Agopian 4929f11793 attempt to fix web build 2021-04-20 22:16:01 -07:00
Mathias Agopian b1d877e7db Add Engine::getEntityManager() 2021-04-20 16:12:40 -07:00
Romain Guy 3f09e62f23 Fix docs 2021-04-20 14:40:04 -07:00
Ben Doherty 03bc9926dd Check that drawSwapChain exists inside endFrame (#3828) 2021-04-20 14:07:43 -07:00
Mathias Agopian e64e8927ce don't use TARGET_MOBILE for quality settings
Until now we were using TARGET_MOBILE in our shaders for both 
quality setting and correctness.

With this PR we introduce a new define FILAMENT_QUALITY which currently
can take two value FILAMENT_QUALITY_LOW and FILAMENT_QUALITY_HIGH and
we use that instead of TARGET_MOBILE for quality settings.

Currently, FILAMENT_QUALITY_LOW is selected when TARGET_MOBILE is set.
2021-04-20 13:39:16 -07:00
Philip Rideout 0643b9e7dd Specify a version range for Pygments. 2021-04-20 12:30:11 -07:00
Benjamin Doherty e5ef4e8868 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:36:37 -07:00
Benjamin Doherty 032ce5ff83 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:36:08 -07:00
Benjamin Doherty c0d6cd3ac3 Merge branch 'rc/1.9.21' into release 2021-04-19 11:34:23 -07:00
Benjamin Doherty b63ab2dc19 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:32:31 -07:00
Benjamin Doherty 623833a5d6 Release Filament 1.9.21 2021-04-19 11:19:05 -07:00
Mathias Agopian f7eb55f2f5 NEW API: Renderer can process standalone View
New Api:

- Renderer::renderStandaloneView() is a new method that can be used
  outside of beginFrame/endFrame on Views that have a RenderTarget
  associated. This can be used as a poor man's compute API.

Improvements to Renderer:

- more aggressively skip lighting/shadowing code that won't be
  needed by the current view

- Allow up to 64 KiB to be allocated from the render stream, up from
  1 KiB
2021-04-19 11:17:38 -07:00
Philip Rideout b095e65e28 VulkanUtility: mark illegal formats with comments. 2021-04-16 15:26:04 -07:00
Benjamin Doherty 98fd95440f Minor updates to release script / guide 2021-04-16 12:11:43 -07:00
Philip Rideout 5f00e715ea Vulkan: another fix to the UBO barrier. (#3814)
Even though the vertex shader comes before the fragment shader,
both bits needs to be present in the barrier, since a Vulkan
implementation might partition its uniform cache between stages.

Thanks to Chris Forbes for pointing this out.
2021-04-16 10:17:51 -07:00
Mathias Agopian 64187ebe8a fix uninitialized state in rendertarget sample 2021-04-15 12:06:21 -07:00
Philip Rideout 1ab127ff03 Fix unused private field warning. 2021-04-15 11:37:08 -07:00
Philip Rideout 3c09d8784a Minor fixups for drag-and-drop viewer page. 2021-04-15 10:11:05 -07:00
Ben Doherty 31ec6550ec Fix Windows build error in filament_framegraph_test.cpp (#3809) 2021-04-15 10:04:34 -07:00
Philip Rideout 24b88219fa VulkanDriver: clean up pipeline barrier for UBO. (#3810)
After eyeballing this barrier I realized it was configured incorrectly,
but it did not seem to manifest as an actual error anywhere.

Basically, it needs to ensure that the UBO is fully updated before it
is read by the vertex shader associated with the next draw call.
2021-04-14 17:54:57 -07:00
Philip Rideout 5c437d9163 matdbg robustness improvements / cleanup. (#3799)
* matdbg robustness improvements / cleanup.

* matdbg code review feedback
2021-04-14 11:39:42 -07:00
Philip Rideout 09bda8a1dc Add glTF viewer to public website.
This will allow folks to drop a GLB into the following page to get a
WebGL preview. It always uses the latest version of Filament via unpkg.

https://google.github.io/filament/viewer

After the next release we can also use the `<filament-viewer>` component
itself from unpkg and remove the local copy.
2021-04-14 10:42:38 -07:00
Philip Rideout f76084213c Update emscripten to 2.0.17
The latest version of emscripten includes major updates to LLVM and
Binaryen.
2021-04-14 10:13:24 -07:00
Philip Rideout b8ed546555 Fix minor warnings. 2021-04-13 13:59:02 -07:00
Philip Rideout 9553786cd5 <filament-viewer> now supports optional drag-and-drop. 2021-04-13 13:41:34 -07:00
Benjamin Doherty 7ef79ad626 Update RELEASE_NOTES for 1.9.20 2021-04-13 11:49:19 -07:00
Benjamin Doherty 0ac2fe02dc Release Filament 1.9.20 2021-04-13 11:49:19 -07:00
Philip Rideout c994ab9f60 sample-gltf-viewer: more improvements for zip files.
- If a resource file is missing, show toast instead of crashing.
- Allow glb files in zip files.
- Run blocking calls like createTempFile() on IO thread.
2021-04-13 11:20:08 -07:00
Mathias Agopian 600600b9af allow the public RenderTarget API to use MRT 2021-04-13 11:02:37 -07:00
Mathias Agopian 1b870a55e2 silently clamp MSAA sample count to maximum allowed
It's an error to ask for a higher MSAA sample count than supported by
the gl driver, and results in corrupted rendering.
We now always clamp the requested sample count to the maximum allowed 
but the gl driver.

includes some minor refactoring.
2021-04-12 16:05:43 -07:00
Philip Rideout 965e845133 sample-gltf-viewer: Delete zip file when done reading. 2021-04-12 16:03:30 -07:00
Philip Rideout 7107afbf0f sample-gltf-viewer: Prevent OOM for large models like Bistro. 2021-04-12 16:03:30 -07:00
Mathias Agopian cbb809e535 enable contact-shadows functionality in mobile gltf-viewer
contact-shadows needs to be enabled per object.
2021-04-12 15:11:18 -07:00
Philip Rideout c5169a431b Fix warning. 2021-04-12 12:46:07 -07:00
Mathias Agopian 6b798ec274 add README to benchmark folder 2021-04-12 12:15:41 -07:00
Ben Doherty 1cde9b326c Fix bad Javadoc in Texture.java 2021-04-12 11:57:18 -07:00
Benjamin Doherty 5d8dad561c Bump version to 1.9.21 2021-04-12 11:38:27 -07:00
Benjamin Doherty 8933be1ae2 Merge branch 'rc/1.9.20' into release 2021-04-12 11:36:17 -07:00
Benjamin Doherty 6b66b48b1d Update RELEASE_NOTES for 1.9.20 2021-04-12 11:35:45 -07:00
Benjamin Doherty 9c23eb6e33 Release Filament 1.9.20 2021-04-12 11:34:39 -07:00
Benjamin Doherty baea54a3fc Update RELEASE_NOTES for 1.9.20 2021-04-12 09:20:31 -07:00
Philip Rideout 4b9ab66ce7 JavaScript: add missing TextureSampler bindings. 2021-04-09 13:00:50 -07:00
Mathias Agopian ba7ebf5ea6 better handle anisotropic filtering with various drivers
Some drivers claim to support anisotropic filtering but don't allow
setting it via glSamplerParameter. Until now we were disabling 
anisotropic filtering entirely on these drivers at compile time.

With this change, we should detect at runtime which drivers have this
issue and use a workaround -- instead of disabling anisotropic 
filtering entirely.
2021-04-09 12:53:21 -07:00
Ben Doherty afdc3d068c Add default precision qualifiers for special sampler types (#3786) 2021-04-09 10:12:03 -07:00
Mathias Agopian 941e81b3aa rework the "debugCommand" feature of backend
- it was called on the main thread side, which didn't allow to,
  for instance, systrace commands on the backend thread side.

- moved to a begin/end callback model

- implemented basic logging/systracing for all backends in Driver.cpp
  (and removed this functionality for the metal driver).

note: refactored CommandStream class attributes only to work around
a clang bug we running into in CI.
2021-04-08 16:35:07 -07:00
Mathias Agopian de7075ff8f enable timer queries on Mali-G series 2021-04-08 16:34:48 -07:00
Philip Rideout 5deed8dc5a Vulkan: fix image layout validation error on Android. 2021-04-08 15:17:24 -07:00
Philip Rideout 93f0d0576d Improve error reporting for vkAllocateDescriptorSets. 2021-04-08 13:06:22 -07:00
Ben Doherty ec339b0282 Fix texture swizzling crash with older Nvidia GPUs (#3779) 2021-04-08 10:38:59 -07:00
Philip Rideout a67505bbe2 VertexBuffer cleanup and simplification.
This includes changes to OpenGL, Metal, and Vulkan backends.

At the backend level, vertex buffers are now always composed of buffer
objects. This lets us simplify the Driver API and some bookkeeping in
the backends.

This change also splits MAX_VERTEX_ATTRIBUTE_COUNT into two constants
because the maximum number of bound buffers is a separate concept from
the maximum number of attribute semantics (e.g. consider interleaving).
For now these two constants are set to the same value.

We also now store a byte count in HwBufferObject, which allows us to
remove the byte count from the Metal-specific handle, and to add some
asserts to debug builds to prevent size overflow.
2021-04-08 09:56:51 -07:00
Philip Rideout 8fd1cefcdf sample-gltf-viewer: keep screen turned on 2021-04-07 16:39:29 -07:00
Ben Doherty 03f7ac6ef4 Fix Material and MaterialInstance Javadocs (#3778) 2021-04-07 14:21:32 -07:00
Mathias Agopian 274e227f49 Fix some mediump related issues
- DoF: don't convert gl_FragCoord to mediump when generating noise
- SSAO: add a bunch of missing highp qualifiers
- all matrices and UV should be highp
- Also fix some typo in comments.
2021-04-07 11:39:36 -07:00
Mathias Agopian 9302a2e711 update remote controler 2021-04-06 21:18:18 -07:00
Mathias Agopian ee9d87b543 use more reasonable near/far for gltf viewer 2021-04-06 17:55:51 -07:00
Mathias Agopian 391cf2487a add missing parameters in ssao serialization 2021-04-06 17:52:01 -07:00
Philip Rideout 914503a30e gltfio: honor stride in normalizeSkinningWeights.
This fixes the issue seen with RecursiveSkeletons.gltf, which is a model
that might soon be added to the Khronos sample models repo.

Fixes #3765.
2021-04-06 15:42:21 -07:00
Philip Rideout 17b8717557 Fix unit test regression. 2021-04-06 15:04:10 -07:00
Philip Rideout 4f49cdbd1e Update remote control web page. 2021-04-06 14:17:07 -07:00
Philip Rideout 24c5cbac68 ModelViewer and Remote UI now support focal length.
The focal length slider now works over a remote connection. Also, the
slider for focus distance now controls the value in `ViewerSettings`
(which gets applied to Camera) rather than the value in
`DepthOfFieldOptions` (which is deprecated).
2021-04-06 14:17:07 -07:00
Mathias Agopian befc1de389 improve a bit GLES error logging code.
no functionality changes, just easier to use when debugging.
2021-04-06 14:00:32 -07:00
Mathias Agopian 45522f24c9 fix MSAA w/ multisampled_render_to_texture on Mali
according to the gl spec, we can't mix the EXT versions of
glRenderbufferStorageMultisample/glFramebufferMultisample with
the regular versions. Other drivers are more permissive.

When allocating a renderbuffer and the extention is supported, we always
use it.
2021-04-06 14:00:16 -07:00
Mathias Agopian 1bd0bb9b81 fix output location in fragment shaders
It looks like the layout(location) is needed for output parameters of
the fragment shader in GLES. Adreno dirver didn't seem to care, but
Mali drivers do. 

This fixes shaders that use multiple out buffers in debug mode.
2021-04-06 13:59:56 -07:00
Philip Rideout 4229610f05 Update emscripten in Google Actions.
This now matches what is already specified in BUILDING.md
2021-04-06 07:58:26 -07:00
Mathias Agopian c062cd9914 gl backend minor code cleanup
- be more consistant with extension naming
- sort extension queries alphabetically
2021-04-05 22:51:56 -07:00
Mathias Agopian 449a5907d1 Better handle GL_GOOGLE_cpp_style_line_directive
We now alwyas scrap this extension usage if the driver doesn't support
it, regardless of being in debug or release mode.
2021-04-05 15:28:40 -07:00
Ben Doherty 9130ef5451 Check environment variable to force integrated Metal device (#3757) 2021-04-05 14:43:38 -07:00
Philip Rideout 82fcb656d9 gltfio: Use BufferObject API, simplify MorphHelper. (#3737)
* gltfio: Use BufferObject API, simplify MorphHelper.

* Repair Android build.
2021-04-05 13:00:39 -07:00
Philip Rideout a139d7fc01 Fix Java warnings.
This adds the 565 enum to a switch block (which is an actual bug),
and it fixes a JavaDoc warning about missing summary fragments (which
is just a silly warning).
2021-04-05 13:00:15 -07:00
Ben Doherty 3242fbaf20 Implement Metal BufferObjects (#3749) 2021-04-05 12:45:07 -07:00
Philip Rideout 037a783e07 Add web component demo.
Just for fun, this is an example of a web component that allows you to
embed a Filament viewer with a single HTML element. It does not have
many features, but is much easier to use than our raw JavaScript API.
2021-04-05 11:42:27 -07:00
Benjamin Doherty 8c714d5a1f Update RELEASE_NOTES for 1.9.19 2021-04-05 11:14:52 -07:00
Benjamin Doherty 3fbc4f2915 Release Filament 1.9.19 2021-04-05 11:14:51 -07:00
Benjamin Doherty d9f800454c Bump version to 1.9.20 2021-04-05 11:14:17 -07:00
Benjamin Doherty f9ee0de07a Merge branch 'rc/1.9.19' into release 2021-04-05 11:11:13 -07:00
Benjamin Doherty 2786d0a9f7 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:10:50 -07:00
Benjamin Doherty 491e8032e6 Release Filament 1.9.19 2021-04-05 11:10:20 -07:00
Benjamin Doherty ef3f13f5d3 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:09:38 -07:00
Benjamin Doherty bcb5b2d790 Implement Metal BufferObjects 2021-04-05 11:01:36 -07:00
Adrian PerezandPhilip Rideout e29bfc2c86 ImGuiHelper can construct with a context (#3753)
* ImGuiHelper supports client-provided context

this lets impress load >1 embedded  font into the font table

* ImGuiHelper supports client-provided context

this lets impress load >1 embedded  font into the font table

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2021-04-05 10:42:57 -07:00
Mathias Agopian 8a34f3c289 revive somewhat the importance sampling mode 2021-04-04 23:36:17 -07:00
Mathias Agopian 951802dd73 SSAO: fix high-quality upsampling
Another mediump issue.
2021-04-04 22:20:03 -07:00
Philip Rideout b95d91a65e WebGL: expose fitIntoUnitCube to JS. 2021-04-04 21:38:08 -07:00
Thomas Gorisse fe94f935f1 Expose TransformManager.getParent(int) (#3751)
It will be nice to have access to TransformManager EntityInstance parent.
2021-04-03 15:45:46 -07:00
Romain Guy 6b529bb231 Fix typo 2021-04-02 15:16:00 -07:00
Philip Rideout c2fabbf9d9 WebGL: support for multiple <canvas> elements.
We now annotate the JS wrapper for Engine with a GL context handle.

This is fairly hacky because emscripten hides its internal GL object
from JavaScript, and it does not provide a mechanism to pass JS objects
into inline assembly.
2021-04-02 14:29:48 -07:00
Philip Rideout 7d604cd05b Add script that updates remote UI.
This script makes it easy to update the web page at
https://google.github.io/filament/remote/ even if you do not have the
emscripten SDK. It works by downloadinug the latest continuous web
build, then placing the wasm file in the right place.

After running the script, the user must make a git commit to finish the
operation.
2021-04-02 12:34:16 -07:00
Philip Rideout 57f1932744 Vulkan: add swizzle support. 2021-04-02 12:34:00 -07:00
Mathias Agopian 891fb65daa added a slider to debug dynamic scaling issues
This is a big hackish, but is intended to help us debug scaling issues,
this adds a couple of sliders under [Debug] to control dynamic
scaling manually.
2021-04-02 11:01:53 -07:00
Mathias Agopian f35be05e76 DoF: fix anamorphism of the Bokeh when dynamic scaling is used 2021-04-02 11:01:29 -07:00
Romain Guy bd4a207b37 Switch specular-color to CIE 1931 10 degree observer 2021-04-02 09:55:11 -07:00
Philip Rideout e19dff18c3 Add JSON unit test, fix ring count output.
Shockingly there were no unit tests that did a simple write-then-read.
This is important because it's easy to forget details such as trailing
commas and the fact that uint8_t is a char.
2021-04-01 21:06:44 -07:00
Philip Rideout deee5d2815 Update the remote web page. 2021-04-01 18:00:49 -07:00
Philip Rideout 53f5fd91b7 Add print operator for BufferObjectBinding. 2021-04-01 14:52:06 -07:00
Philip Rideout 0969cec45d BufferObject API: add Vulkan support. 2021-04-01 14:52:06 -07:00
Philip Rideout ded542a543 Introduce BufferObject API.
NOTE: after Metal and Vulkan support lands, we can potentially simplify
the Driver API by removing some of the old VertexBuffer entry points.

This introduces a new API-level object called `BufferObject`, and a new
backend-level object called `HwBufferObject`. This encapsulates a single
VBO. It's especially useful when clients need to share data between
multiple VertexBuffer objects. (e.g. for morphing).

In the future, buffer objects could perhaps be used for non-vertex data
(e.g. for compute).

The existing `VertexBuffer` class can now be configured to use buffer
objects by calling `enableBufferObjects` on the builder. By default its
API is unchanged. If buffer objects are enabled, then clients should use
`setBufferObjectAt` (which takes a buffer object) rather than
`setBufferAt` (which takes CPU data).

OpenGL is the trickiest backend for this, due to existence of VAOs.
The implementation in this PR uses a version-tracking scheme to
figure out when to update the VAO.
2021-04-01 14:52:06 -07:00
Mathias Agopian 385a17b8a5 DoF: add many user settings
- native/half resolution
- gather kernel ring counts
- circle-of-confusion radius clamps
2021-04-01 14:42:10 -07:00
Ben Doherty 0a0588aec8 Add Metal and Vulkan backend support to Suzanne sample (#3736) 2021-04-01 12:22:15 -07:00
Ben Doherty 9af62251b6 Fix Metal texture swizzling (#3732) 2021-04-01 10:19:50 -07:00
Mathias Agopian 819878a1da DoF: implement "background hole filling"
We use the technique used by Jimenez for the foreground applied to the
background, where we "guess" the missing background information from
neighboring pixels. In several papers it's not deemed useful for the
background, however, it does improve the blur quality a lot very shallow
DoF, i.e. when a moderately blurred background sits over a strongly 
blured one.
2021-03-31 17:49:41 -07:00
Mathias Agopian e7364cdcb3 DoF: don't rely on texture swizzle being supported 2021-03-31 12:17:34 -07:00
Mathias Agopian e5bfe81d0c DoF: use only a single low res source for both fg and bg
Before we were keeping a foreground and background version of the
low resolution source, but in practice it really doesn't make a big
difference and we save a fair amount of bandwidth this way.

The bulk of the change is to remove a texture/target which mostly
affects the downsample and mipmap passes.
Also renamed some variables to be less confusing (MaxMin to MinMax for e.g.)
and fixed a few typos.
2021-03-31 12:17:34 -07:00
Mathias Agopian c4eb790065 Add support for texture swizzling in framegraph 2021-03-31 12:17:34 -07:00
Romain Guy ac56efcd95 Revert misguided attempt to fix bloom with glTF (#3728)
* Revert misguided attempt to fix bloom with glTF

* Put back line removed by mistake
2021-03-31 10:08:36 -07:00
Mathias Agopian 9fcb8ccb9e DoF: document a typo
there has been a typo in the DoF code a while, but fixing it looks
much worse. we need to understand why. so for now we at least
document the typo in the code.
2021-03-30 21:34:59 -07:00
Mathias Agopian 67a936d845 fix a linker warning 2021-03-30 15:58:17 -07:00
Ben Doherty d11f3f7d5a Implement Metal texture swizzling (#3720) 2021-03-30 15:38:55 -07:00
Mathias Agopian 625c4d8968 implement query for texture swizzle
unfortunately metal does support texture swizzle on all versions of
macos we support.
2021-03-30 14:24:17 -07:00
Ben Doherty 239b933d5e Fix VSM on Android (#3719) 2021-03-30 14:05:53 -07:00
Philip Rideout 3161f6a8f1 Remote UI now handles keyboard input. 2021-03-30 08:15:01 -07:00
Philip Rideout d2bff95c90 Easy build: add matdbg option and help message. 2021-03-30 08:14:23 -07:00
Philip Rideout a0e7c26a63 Remote pip lockfile from web docs generator. 2021-03-29 14:49:12 -07:00
Ben Doherty 02de3f2e2a Fix, regression with Metal buffers (#3715) 2021-03-29 14:21:34 -07:00
Ben Doherty 5bfa9633d2 Fix, regression with Metal buffers (#3715) 2021-03-29 14:20:40 -07:00
Benjamin Doherty 0e7bb53c07 Bump version to 1.9.19 2021-03-29 11:09:32 -07:00
Benjamin Doherty 759109d478 Merge branch 'rc/1.9.18' into release 2021-03-29 11:06:55 -07:00
Benjamin Doherty ff5ecb17ea Update RELEASE_NOTES for 1.9.18 2021-03-29 11:06:35 -07:00
Benjamin Doherty 83ba56d3e7 Release Filament 1.9.18 2021-03-29 11:05:44 -07:00
Benjamin Doherty 54d5af6edf Update RELEASE_NOTES for 1.9.18 2021-03-29 11:04:57 -07:00
Mathias Agopian 2d398c2398 DoF: fix noise radius calculation (#3709)
This small bug was introduced recently with the dynamic kernel size
changes, the noise radius depends on the number of rings in the kernel.
2021-03-29 10:46:34 -07:00
Philip Rideout 38fbe47ced RenderTarget: fix NPE when depth is not present.
This fixes a recent regression that would occur when a RenderTarget
does not have a depth attachment.
2021-03-29 10:32:22 -07:00
Philip Rideout cf070c6bc7 RenderTarget: fix NPE when depth is not present.
This fixes a recent regression that would occur when a RenderTarget
does not have a depth attachment.
2021-03-29 10:31:04 -07:00
Mathias Agopian 3c577b6191 DoF: fix several mediump-related bugs
The gist of it is that we can't always accumulate samples naively, and
we have to use different strategies with different tile types.

For the fast tiles it seems enough to reorder the sum, accumulating each
ring first, and then accumulating that into the output, because all
samples have the same weight.

For the foreground tiles, for some reason I couldn't find any major
issue and I'm not sure why.

For the background tiles, we need to use highp intermediates because
every sample has different magnitudes (weights)
2021-03-29 09:48:51 -07:00
Mathias Agopian acb2da7759 Improvements to Camera APIs (#3701)
* move the focus distance from DofOptions to Camera

The DofOption parameter is now deprecated, but will still work if the
focus distance is not set on Camera.

* A few new helper APIs on Camera

- getFocalLength() which returns the focal length used internally for
  DoF computations.

- computeEffectiveFov() and computeEffectiveFocalLength() which can be
used to better simulate a real camera's FOV changes with the
focus distance.

Modified gltf_viewer so it uses the effective fov/focallendth when
DoF is active.

* simplify setLensProjection

We can call setProjection directly instead of converting to a fov
first, which ends up performing atan(tan(x)).

Also improve parameters names.
2021-03-25 15:22:19 -07:00
Mathias Agopian a0c2edd1a2 DoF: dynamically and conservatively adjust the kernel density per tile
This adjustment is conservative, i.e. we limit the number of rings in
the kernel based on the kernel size in a way that it won't impact the
result. For instance, if the kernel size is 2 or lower, we don't need 4
rings.

This improves performance significantly, especially with large maximum
right counts.
2021-03-25 15:19:57 -07:00
Ben Doherty ad555d897d Expose MaterialInstance APIs that should have been public (#3703) 2021-03-25 11:29:39 -07:00
Mathias Agopian 4a6e62070b DoF: slightly better opacity for the background
We now use the same calculation than for the foreground, this seems
to produce slightly smoother transitions
2021-03-24 22:10:40 -07:00
Mathias Agopian 0c081d4295 DoF: implement fix for foreground opacity
This fixes an issue where objects in-focus show through the blurred
foreground.
2021-03-24 16:22:22 -07:00
Mathias Agopian 04ff2fb806 DoF: shader code refactoring
here we just move the fast/foreground and background tiles processing
into their own function. this is just to make the code more readable.
2021-03-24 16:22:22 -07:00
Philip Rideout 4fb9ee4470 Remove old emscripten workaround from GL backend.
This was put in as a workaround for #2856. I made a fix to emscripten
itself (yay open source) in July. So, this workaround is no longer
necessary.

Verified with the rigged figure model.

https://github.com/emscripten-core/emscripten/pull/11742
2021-03-24 14:58:53 -07:00
Philip Rideout 3d2734b163 Minor Driver API simplification.
As far as I can tell, there is no need for the `enabledAttributes`
argument in `setRenderPrimitiveBuffer`. This helps pave the way for
the upcoming BufferObject API.
2021-03-24 14:31:18 -07:00
Philip Rideout c4a12fe48a Update cgltf to v1.10 2021-03-24 14:31:09 -07:00
Ben Doherty 40b8667aef Fix Metal bug when setGeometryAt is called multiple times (#3693) 2021-03-24 12:42:55 -07:00
Mathias Agopian cb9578327b attempt to improve doxygen formating
fixes: #3692
2021-03-24 12:24:12 -07:00
Mathias Agopian 7b0a8cf2c2 fix JNI setImage and friends buffer size calculation
- setImage() used the width of the texture for calculating the required
  user buffer size, but this was too large when only updating a
  portion of the texture. It would result in a BufferOverFlowException.

- setImage3D() had the opposite problem where it didn't take into
  account the depth of the texture.

- the offset in the user buffer was called "bottom" on the C++ JNI side,
  but it is called "top" on the java and filament side.

Fixes #3685
2021-03-24 12:20:16 -07:00
Philip Rideout 4197afba49 Web site: update Filament in /remote. 2021-03-24 08:24:00 -07:00
Philip Rideout 495fb14b9c Move Camera settings from gltf_viewer to SimpleViewer. 2021-03-24 08:24:00 -07:00
Mathias Agopian 4de1b0de2d DoF: add a "filter" parameter to the DoF settings
Currently the only NONE and MEDIAN are available options, at some 
point we may add a "MAX" option which is cheaper.

There is no real practical uses for this option with these only two
choices, other than for debugging.
2021-03-23 17:27:31 -07:00
Mathias Agopian abcf4010dd DoF: support full-resolution DoF
This is mostly used for debugging and having somewhat of a reference.
Change to the shader are minimal because all CoC values were always
treated as full-resolution. We just need to replace the downsampling
shader by one that just calculates the CoC. And we need to introduce
a CoC scale factor to compute the LOD to use (this was hardcoded
before).

On the C++ side, it's mostly a matter of replacing hardcoded buffer size
scales by a runtime or compile time variable.
2021-03-23 16:12:03 -07:00
Philip Rideout 65928612b1 Add vkshaders to README. 2021-03-23 12:38:50 -07:00
Adrian PerezandMathias Agopian a33c85bdd4 CString can construct from a string_view (#3677)
* CString can construct from a string_view

(string_views lack a null terminator)

* Update libs/utils/src/CString.cpp

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-03-23 00:46:18 -07:00
Mathias Agopian 3ec3f222c5 Dof: improve significantly foreground layer
We're implementing the two-layer technique described in
Jimenez DoF paper, where the foreground field is split in two layers, front
and back. In addition we compute accurately the foreground field alpha.

From a performance standpoint, most of the extra work is increased
register pressure and a bit of ALU.
2021-03-22 16:55:40 -07:00
Mathias Agopian e9a43e7344 DoF: code cleanup
- mostly rename variables
2021-03-22 16:55:40 -07:00
Mathias Agopian fc835aebc6 DoF: fix a few small bugs
- foreground in-layer feather was off
- sample weights was off my 2x
2021-03-22 16:55:40 -07:00
Mathias Agopian a3504bd9b6 DoF: make code a bit less confusing
Always store min CoC in the red channel and max Coc in the green
channel for both the CoC and Tiles textures.
(The tiles texture was doing the opposite).
2021-03-22 16:55:40 -07:00
Mathias Agopian 7c604623e6 DoF: code cleanup
Remove the RING_DENSITY variable because it
can't be changed.
2021-03-22 16:55:40 -07:00
Ben Doherty 3d3f19aa71 Enable VSM shadows with shadow multiplier (#3678) 2021-03-22 12:37:07 -07:00
Benjamin Doherty f066c925ba Bump version to 1.9.18 2021-03-22 10:16:34 -07:00
Benjamin Doherty 00f4b45df6 Update RELEASE_NOTES for 1.9.17 2021-03-22 10:16:20 -07:00
Benjamin Doherty 07140cf2fa Release Filament 1.9.17 2021-03-22 10:16:02 -07:00
Benjamin Doherty 994fdf4e1d Merge branch 'rc/1.9.17' into release 2021-03-22 10:12:20 -07:00
Benjamin Doherty 50b50d65e3 Update RELEASE_NOTES for 1.9.17 2021-03-22 10:11:02 -07:00
Romain Guy 28acd0fa6a Update build scripts to match latest AGP and Kotlin 2021-03-19 12:44:25 -07:00
Philip Rideout 0b91f3d785 Add deprecation annotation to Camera. 2021-03-19 11:04:30 -07:00
Mathias Agopian 1bb18f5f0a DoF: fix a bug that caused black dots around the fast tiles
this would happen only when a fast tile had a CoC < 2, because it
would then have an opacity, but we were ignoring it. It's color then
didn't match the color of the surrounding layer and the median filter
would spread a pixel from the surrounding layer into the fast tile.

we simply fix this by (1) generating the alpha/color for fast tiles,
which is easy to do and on the combine pass, skip the fast tile 
combine when the tile has a an opacity.
2021-03-18 14:57:46 -07:00
Mathias Agopian 2e1d88caae DoF: always apply the correct sample weight
before we were not doing that because it caused some aliasing
artifacts with mipmapping, however it turns out that there are artifacts
anyways, and using the proper weights actually reduces the most severe
ones.

the artifacts are due -- it seems -- to the low density of the kernel.
2021-03-18 14:57:46 -07:00
Mathias Agopian a59f4dd3fc DoF: minor optimizations
we can refactor the code to get rid off the call to mergeRings() for 
the first ring, and we don't need to initialize the current bucket
either.
2021-03-18 14:57:46 -07:00
Mathias Agopian 0aaa985649 Fix a hang in JobSystem
The hang was caused by a subtle race. When a job is completed, its 
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.

Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of 
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).

It would then get stuck forever.

This bug was introduced in 2df639133b


Also add some debugging code for this kind of failure (disabled)
2021-03-18 09:57:25 -07:00
prewettg 46b356cb2c Fix blanking windows not being drawn into on macOS (#3616)
* Fix blanking windows not being drawn into on macOS

* Refactored to create swap chain info object; added fixes for resizing; added sample.

* CocoaGLSwapChain should inherit from Platform::SwapChain

* Link to SDL directly for multiple_windows example

* SDL apparently redefines main to SDL_main and requires C++ linkage

* Fix main to have SDL-approved signature
2021-03-18 09:49:20 -07:00
Philip Rideout a20ae75d11 gltfio: Add support for data:// in image URI's. (#3662) 2021-03-17 17:57:41 -07:00
Philip Rideout 8d78b1f2e1 gltfio: Add internal MorphHelper, enable up to 255 targets. (#3661)
* gltfio: Add internal MorphHelper, enable up to 255 targets.

Previously, gltfio could not animate models with more than 4 morph
targets. Now we can handle up to 255 targets, as long as no more than
4 targets are ever used simultaneously. This allows us to handle
many more models, such as those exported by Modo, and the horse model
in #1852.

We do this by picking the highest 4 weights. The indices for these
weights are called the "primary indices", and we construct a new
VertexBuffer for each unique set of primary indices.

In the near future this will be made more efficient by adding a new
VertexBuffer API to the Filament core.

Fixes #1487.

* Code review fixups.
2021-03-17 15:52:24 -07:00
Ben Doherty 9030abaa89 Fix RenderTarget slice bug (#3656) 2021-03-17 15:47:31 -07:00
Mathias Agopian e8b16d600e Fix a hang in JobSystem
The hang was caused by a subtle race. When a job is completed, its 
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.

Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of 
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).

It would then get stuck forever.

This bug was introduced in 2df639133b


Also add some debugging code for this kind of failure (disabled)
2021-03-17 13:44:30 -07:00
Benjamin Doherty 24121a4734 Fix typo with Metal createRenderTarget 2021-03-17 10:29:07 -07:00
Philip Rideout 6eabe0491c gltfio: Refactor Animator.
This does not change any behavior, it just prepares for the upcoming
MorphHelper class.
2021-03-17 07:38:00 -07:00
Philip Rideout 20b0972130 gltfio: Refactor the tangents job.
This cleans up the glTF tangents generator and allows it to be used
in other parts of the library.
2021-03-16 16:43:02 -07:00
Mathias Agopian 98da09b247 fix rendertarget sample app
we can't use a projection with infinite far as a custom
projection matrix, because this is not suited for culling.

recently a new version of setCustomProjection was added which allows
to specify both the rendering and culling projections.
2021-03-16 16:09:14 -07:00
Mathias Agopian cc13420e31 add missing includes
Should fix #3633
2021-03-15 22:45:31 -07:00
Benjamin Doherty 29564f8eae Bump version to 1.9.17 2021-03-15 10:15:25 -07:00
Benjamin Doherty c15db68a5b Merge branch 'rc/1.9.16' into release 2021-03-15 10:12:56 -07:00
Benjamin Doherty fd55da0319 Update RELEASE_NOTES for 1.9.16 2021-03-15 10:12:24 -07:00
Benjamin Doherty 240d9d0919 Release Filament 1.9.16 2021-03-15 10:11:11 -07:00
Benjamin Doherty 3452fb3e56 Update RELEASE_NOTES for 1.9.16 2021-03-15 10:10:40 -07:00
Mathias Agopian 41634a301e demangle callstacks in debug builds (unixes only)
This requires dladdr() and __cxa_demangle().
2021-03-13 23:22:01 -08:00
Philip Rideout cf75b11cba Add missing deprecated annotations. 2021-03-12 13:33:14 -08:00
Philip Rideout 81bba4644a Remove unused imports. 2021-03-12 13:07:29 -08:00
Mathias Agopian 35eb8e7be1 Revert GL backend handle tracking
This wasn't very useful in the first place because we're recycling
handles very quickly. Additionally there was a race condition
which cause false positives.

This reverts commit bc6acd5c5a.
This reverts commit 3a15756c78.
2021-03-12 13:02:55 -08:00
Mathias Agopian f7e92b0ee3 Revert GL backend handle tracking
This wasn't very useful in the first place because we're recycling
handles very quickly. Additionally there was a race condition
which cause false positives.

This reverts commit bc6acd5c5a.
This reverts commit 3a15756c78.
2021-03-12 12:57:03 -08:00
Mathias Agopian 1e58fd4842 minor jobsystem fixes
- one version of run() ignored the flags parameter
- don't immediately signal created jobs in froxelizer
  to avoid redundant calls to signal()
2021-03-12 11:47:28 -08:00
Ben Doherty fa7ad8d867 Fix dominant light shadows in Metal and Vulkan (#3631) 2021-03-12 10:08:33 -08:00
Mathias Agopian 834b774128 Fixes some issues with imported rendertargets
We were not declaring the attachments it was using.

Fixes #3628
2021-03-12 08:26:16 -08:00
Philip Rideout eb40fa753f gltfio: Fix tangents when morphing is enabled.
The vertex data for glTF morph targets are deltas rather than final
values, so we were passing incorrect data into the SurfaceOrientation
helper.

This has been a long-standing bug that affected models with morphing,
including Buster Drone. However in practice we have observed visual
issues only with AnimatedMorphCube.

Tested against AnimatedMorphCube, Buster Drone, Cesium Man, Fox, and
Littlest Tokyo.

Fixes #1609
2021-03-11 14:09:52 -08:00
Mathias Agopian dc36b228d6 Fixes some issues with imported rendertargets
We were not declaring the attachments it was using.

Fixes #3628
2021-03-11 14:06:26 -08:00
Philip Rideout 11e3eff009 Update TypeScript bindings. 2021-03-11 10:28:44 -08:00
Philip Rideout 52abe75cfd RemoteServer code cleanup and logcat cleanup.
This fixes two different logcat messages that would occur when scrubbing
a slider in the UI:

- "Discarding message, message queue overflow."
- "Downloading model..." would repeat itself needlessly
2021-03-11 07:52:32 -08:00
Romain Guy 8065d18f54 Update release notes 2021-03-10 16:15:18 -08:00
Philip Rideout 1b3684933d Repair WebGL build. 2021-03-10 16:01:29 -08:00
Mathias Agopian e657921b5a Camera API improvements
- Add a "shift" parameter to Camera. This has the effect of translating
  the viewport, without changing its size. 
  This is an effect similar to using a shift lens.

- Camera::setScaling() now takes a double2 instead of double4, this is
  because scaling the result of the projection in the Z direction 
  can lead to very confusing problems -- it will essentially move the
  near/far planes, and we don't want to expose that as a public API.

- setCustomProjection() now allows to set a different projection for
  rendering and culling (useful for e.g. for using an infinite far 
  rendering projection matrix).
2021-03-10 16:01:29 -08:00
Seth Vargo 91ce5c785b Improve Actions hygiene (#3630)
Only run GitHub Actions for pushes and PRs against the main branch of the repository.
2021-03-10 15:02:16 -08:00
Philip Rideout 676b0542c4 sample-gltf-viewer: fix ColorGrading JNI assert 2021-03-10 11:14:31 -08:00
Philip Rideout dced766999 Update Remote Control page. 2021-03-10 10:51:19 -08:00
Philip Rideout eb0b5d16bf Migrate ColorGrading to SimpleViewer. 2021-03-10 09:27:51 -08:00
Mathias Agopian 2845f37ac7 improve CoC computation comment 2021-03-09 22:21:28 -08:00
Mathias Agopian 922ce83f48 add the --split-view option to gltf_viewer
useful for debugging shadows problems
2021-03-09 10:48:23 -08:00
Mathias Agopian 7445d80202 Improve circle-of-confusion computation
- generously document the CoC computation

- rewrite the code so that the computation will work for any
  perspective projection matrix, instead of assuming
  an "infinite-far" projection.
2021-03-09 10:48:08 -08:00
Philip Rideout 4d6f3ad392 JsonSerializer: do not repeatedly re-construct ostringstream. 2021-03-08 15:13:01 -08:00
Philip Rideout c4ac8a9f06 AutomationEngine can now be used as a remote control. 2021-03-08 10:32:06 -08:00
Philip Rideout b554a68186 Remote page now has UI and pushes settings. 2021-03-08 10:32:06 -08:00
Philip Rideout b7ad20249d Improve the Settings serialization API, expose to JS.
This not only makes it easier to expose to JavaScript, it also paves the
way for a much more efficient implementation.
2021-03-08 10:32:06 -08:00
Philip Rideout 65f4b600bc Polish up the Remote Control page. 2021-03-08 10:32:06 -08:00
Philip Rideout 03945b88c8 ImGuiHelper now manages the UI camera. 2021-03-08 10:32:06 -08:00
Philip Rideout 24583332a2 Add filagui and SimpleViewer to the WASM build. 2021-03-08 10:32:06 -08:00
Benjamin Doherty 5aa0eb9f9d Bump version to 1.9.16 2021-03-08 10:09:14 -08:00
Benjamin Doherty d9a6e2e649 Merge branch 'rc/1.9.15' into release 2021-03-08 10:07:00 -08:00
Benjamin Doherty ce26801a91 Update RELEASE_NOTES for 1.9.15 2021-03-08 10:06:30 -08:00
Benjamin Doherty 7fd5b65f3b Release Filament 1.9.15 2021-03-08 10:05:56 -08:00
Benjamin Doherty cb823b16a1 Update RELEASE_NOTES for 1.9.15 2021-03-08 10:05:19 -08:00
Philip Rideout 61b1542468 Add new remote page to site. 2021-03-08 08:57:57 -08:00
Mathias Agopian d740378277 More code size optimizations and bvecn fixes
MaterialInstance: generate versions of setParameter() methods that
are templated on the parameter sizeof(), which allows us to
coalesce implementations, e.g. vec4<float> and vec4<int> are now
the same. We make the compiler generate non-inline version of all
these methods, the typed version just call through, taking
advantage of the tail-call optimization in clang.


MaterialParser: improve code to avoid calling multiple methods that
all did more or less the same thing and were inlined.

PostProcessManager: use a loop to initialize the materials

ToneMapping: de-dup ACES implementation

And other more minor optimizations.


Fix alignment issues with setting booleans in UBOs
2021-03-05 10:59:30 -08:00
Philip Rideout 0815adf722 PostProcessManager: fix setMinMaxLevels for StructureMipmap. 2021-03-05 08:15:04 -08:00
Philip Rideout ef1eacf22e PostProcessManager: fix setMinMaxLevels for StructureMipmap. 2021-03-05 08:15:04 -08:00
Benjamin Doherty fc896f81f0 Fix broken filamat lite build 2021-03-04 10:09:26 -08:00
Ben Doherty 884d5c1b87 Make material compilation deterministic (#3610)
With multithreaded variant compilation, compiled materials differ based on which variants finish first. This change ensures that compiled materials are always bit-for-bit identical.

This is helpful when comparing two compiled materials. Hashing the material files can be used to check for equality. It's also convenient for variants to occupy the same index when using matinfo's --print-glsl flag, for example.
2021-03-03 16:55:35 -08:00
Romain Guy 627186abc8 Update incorrect documentation (#3608) 2021-03-03 14:42:47 -08:00
Philip Rideout 30b0f39a36 sample-gltf-viewer: add polish to the drag-and-drop feature. 2021-03-03 14:41:22 -08:00
Philip Rideout c3c2a732cd gltfio: Add ResourceLoader evict API. 2021-03-03 14:41:22 -08:00
Philip Rideout 5cc8ebd3e1 gltfio: fix ResourceLoader cache bug. 2021-03-03 14:41:22 -08:00
Philip Rideout 9ceb3b016c sample-gltf-viewer: add drag-and-drop feature.
This adds a WebSockets server to filament-utils-android.

Unlike my first attempt (#3599), this does not use a piping server and
is therefore much faster to use over a LAN. It also has lower user
friction because there is no need to touch a button in the app or
scan a QR code.
2021-03-03 14:41:22 -08:00
Philip Rideout 76e18475d3 gltf_viewer: avoid writeJson when automation is off. 2021-03-03 12:10:42 -08:00
Philip Rideout 2964e99175 sample-gltf-viewer: add URL hint. 2021-03-03 12:10:42 -08:00
Mathias Agopian 1189c9e294 FrameGraph rewrite from the ground up
The main goal of this rewrite was to make the code
simpler and easier to maintain.

The API is mostly unchanged, however there are some differences.
- we now have the concept of subresources, e.g. for Textures, as
  subresource is a mip level or layer.
- RenderTargets are no longer resources, instead they are transiant
  objects associated to a pass and are now called RenderPasses.
- RenderPasses take subresources for attachments.
- We have better validation of graph building.

We should also compute discard flags more accurately.
2021-03-02 22:25:56 -08:00
Philip Rideout 50799f3760 Replace QR code page with something better. 2021-03-02 18:36:38 -08:00
Philip Rideout 4b580b6eb1 Add automation to Android build, change PNG to PPM.
This adds libs/viewer to filament-utils-android and provides JNI
bindings for AutomationEngine.

This commit also changes the AutomationEngine to use PPM for screenshots
rather than PNG. The reasoning is that it is wasteful to include stb and
our two image-related libraries just to dump screenshots, especially for
a feature we might not use on Android.
2021-03-02 10:41:06 -08:00
Ben Doherty 8d6e794486 Remove exceptions on iOS (#3600) 2021-03-02 10:38:19 -08:00
Ben Doherty 0bd41e877e Downgrade Linux GitHub Actions environment to fix error (#3588) 2021-03-01 11:21:11 -08:00
Benjamin Doherty ecc3e73967 Bump version to 1.9.15 2021-03-01 11:13:44 -08:00
Benjamin Doherty 464b4c24f9 Merge branch 'rc/1.9.14' into release 2021-03-01 11:11:53 -08:00
Benjamin Doherty 7fa2053c55 Update RELEASE_NOTES for 1.9.14 2021-03-01 11:11:15 -08:00
Benjamin Doherty cb7f81ccd6 Release Filament 1.9.14 2021-03-01 11:10:46 -08:00
Benjamin Doherty 32367516e8 Update RELEASE_NOTES for 1.9.14 2021-03-01 11:10:06 -08:00
Philip Rideout 6227496478 Update MoltenVK to 1.1.2 2021-03-01 09:42:23 -08:00
Philip Rideout 74aa7d3c87 Add QRCode page for glTF files. 2021-02-28 17:59:53 -08:00
Ben Doherty bc107e7def Downgrade Linux GitHub Actions environment to fix error (#3588) 2021-02-26 17:00:56 -08:00
Ben Doherty 09e05ae00d Label Metal render encoders with group markers (#3583) 2021-02-26 10:37:34 -08:00
Philip Rideout 1709a55606 filamat: Fix data race with SPIRV error registrations. 2021-02-26 10:34:36 -08:00
Philip Rideout 1921536f90 filamat: Fix data race with SPIRV error registrations. 2021-02-24 10:17:51 -08:00
Philip Rideout 1a9334e818 Modernize Python print syntax. 2021-02-23 14:43:30 -08:00
Mathias Agopian bc6acd5c5a GL backend: fix race condition when asserting a handle exists 2021-02-22 23:25:43 -08:00
Mathias Agopian 3a15756c78 GL backend: track handles lifetime in debug builds 2021-02-22 17:22:18 -08:00
Mathias Agopian f1fd96983b assert_invariant() now terminates the program in failure
rename logAndPanic to panicLog, since it doesn't actually panics.
2021-02-22 14:57:41 -08:00
Benjamin Doherty 58b4455979 Bump version to 1.9.14 2021-02-22 10:32:56 -08:00
Benjamin Doherty ea1dede19c Merge branch 'rc/1.9.13' into release 2021-02-22 10:29:57 -08:00
Benjamin Doherty 1f000bd10d Update RELEASE_NOTES for 1.9.13 2021-02-22 10:29:30 -08:00
Benjamin Doherty ce2c49217f Release Filament 1.9.13 2021-02-22 10:29:02 -08:00
Benjamin Doherty 20ea3381fa Update RELEASE_NOTES for 1.9.13 2021-02-22 10:28:21 -08:00
Philip Rideout ec9640695c Provide a docstring for the Stream class.
Mathias noticed that the `setAcquiredImage` method was not well
documented on the C++ side. While fixing this I figured I'd try to write
up a docstring for the class itself.
2021-02-22 10:15:01 -08:00
Romain Guy f2ed3480d8 Attempt at improving bloom/emissive with glTF files (#3560)
* Attempt at improving bloom/emissive with glTF files

* Publicly expose Exposure API for gltfio
2021-02-22 09:40:31 -08:00
Romain Guy 5d9384fca7 Fix docs typos 2021-02-20 16:43:12 -08:00
Romain Guy 22d16c1910 Fix typo in docs 2021-02-19 12:04:45 -08:00
Philip Rideout 7aa6fccd7c Modernize Python print syntax to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout adbd54f4f8 Change abs() to std::abs to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout 9d54261f18 Move vk_mem_alloc to its own cpp.
This will improve parity between the GitHub repo and its sister codebase
within Google.
2021-02-19 11:38:18 -08:00
Philip Rideout a97757c9ae Avoid uninitialized reads in computeVisibilityMasks.
I verified that this code is not enabled in our GitHub builds, and I
verified that the MSAN error goes away.
2021-02-19 11:38:18 -08:00
Philip Rideout 7c79d9f89d Remove some Windows line endings.
These line endings cause annoying diffs when comparing Filament's GitHub
source with its twin sister within Google.
2021-02-19 11:38:18 -08:00
Philip Rideout 20dadf06f1 Modernize Python print syntax to appease external codebase. 2021-02-18 13:31:02 -08:00
Romain Guy b3a4788e56 Fix doc warning 2021-02-17 15:05:45 -08:00
Philip Rideout 811e7c59cf Change abs() to std::abs to appease external codebase. 2021-02-17 14:45:17 -08:00
Philip Rideout be22360903 Move vk_mem_alloc to its own cpp.
This will improve parity between the GitHub repo and its sister codebase
within Google.
2021-02-17 14:40:19 -08:00
Philip Rideout 2b68665cd8 Avoid uninitialized reads in computeVisibilityMasks.
I verified that this code is not enabled in our GitHub builds, and I
verified that the MSAN error goes away.
2021-02-17 14:33:56 -08:00
Philip Rideout 6297ef9193 Remove some Windows line endings.
These line endings cause annoying diffs when comparing Filament's GitHub
source with its twin sister within Google.
2021-02-17 10:11:22 -08:00
Mathias Agopian 68e99240d0 don't use assert() inside filament
assert() is now replaced by assert_invariant() which has the same
prototype and (currently) behaves the same than assert().

<assert.h> should not be used anymore, and is replaced by 
<utils/debug.h>, which is where assert_invariant() is found.

The main motivation for this is to be able to set a breakpoint on the
assertion as lldb doesn't handle abort() very well, and doesn't
permit to inspect the stack trace.

A secondary motivation is to be able (at some point) to enable 
assertions without necessarily doing a debug build.
2021-02-16 20:30:04 -08:00
Benjamin Doherty bf0914f813 Bump version to 1.9.13 2021-02-16 10:48:24 -08:00
Benjamin Doherty b96bc30fbd Merge branch 'rc/1.9.12' into release 2021-02-16 10:44:13 -08:00
Benjamin Doherty 7bf04e1f71 Update RELEASE_NOTES for 1.9.12 2021-02-16 10:43:46 -08:00
Benjamin Doherty 939f3b975c Release Filament 1.9.12 2021-02-16 10:43:06 -08:00
Benjamin Doherty 62b50eb8ba Update RELEASE_NOTES for 1.9.12 2021-02-16 10:42:41 -08:00
Romain Guy e247ffad9b Correctly name JNI methods so they can be found (#3539) 2021-02-16 10:07:42 -08:00
Philip Rideout fb29ae9fa5 Add MSAA resolve (color and depth) to the blit test. 2021-02-16 08:05:11 -08:00
Philip Rideout 706a685ca6 Add a depth blit to the unit test.
Since we cannot upload a depth buffer, this test works by first drawing
a triangle into COLOR + DEPTH, copying them both to a new render target,
then drawing a slightly larger triangle just underneath the first one.
2021-02-12 17:20:30 -08:00
Romain Guy 4ad947f0ad Update docs 2021-02-12 10:54:54 -08:00
Philip Rideout a1939189ea Code cleanup for test_Blit. 2021-02-12 10:34:59 -08:00
Philip Rideout fe49c1eb82 Add backend unit test for blit.
This is fairly simple for now, only does color.
Will enhance in a future PR.
2021-02-12 10:34:59 -08:00
Philip Rideout 4d18c0d61c BlueVK: use slog for dlopen error message. 2021-02-11 12:51:40 -08:00
Philip Rideout 6fa8f48be5 BlueVK: optionally consult environment variable.
One of Filament's Linux clients at Google wishes to specify a special
path to the SwiftShader library that proffers Vulkan entry points, and
this path can only be determined at run time.

An environment variable seems like the easiest way to support this
functionality. To prevent a security hazard, the env var is checked only
if a special build-time flag is enabled.
2021-02-11 12:51:40 -08:00
Philip Rideout ba32cef717 Vulkan: conform to PORTABILITY_SUBSET for Molten.
According to the portability spec: "If this extension is supported by
the Vulkan implementation, the application must enable this extension."

On my 2019 MacBook, enabling this extension triggers errors relating to
depth comparison samplers which I believe to be bogus, so I filed a
LunarG bug. For now we silence this specific error message.
2021-02-11 12:51:24 -08:00
Ben Doherty e6d3d26c6b Fix, computeDataSize returns incorrect value for USHORT_565 (#3530) 2021-02-10 16:35:39 -08:00
Romain Guy 180cf24b58 Update cgltf to latest 2021-02-10 13:22:17 -08:00
Philip Rideout 0f9cee0b83 Update WebGL demos on website.
This includes an important fix for Chrome on Windows, which does not
support RGB16F.
2021-02-09 11:41:09 -08:00
Romain Guy 317c82711b Improve docs generation (#3527)
build.sh -w now performs a full install of dependencies instead
of relying on local installation tricks.
2021-02-09 11:40:02 -08:00
Ben Doherty 3f32146849 Fix Android compilation error in UbershaderLoader (#3526) 2021-02-09 10:50:19 -08:00
Romain Guy 9da69dac46 Update documentation 2021-02-09 10:43:49 -08:00
Ben Doherty b4932e384a matc: Use consistent params for semantic code analysis (#3524)
When running semantic analysis on a material, we were arbitrarily choosing the first code gen permutation to analyze. So, running matc with arguments --api metal versus --api all would run analysis on slightly different shader code. This causes bugs when flags passed to glslang differ during semantic analysis. This change updates all semantic analysis to always use the same shader code.
2021-02-08 14:06:47 -08:00
Ben Doherty 1516b135fd matc: Use consistent params for semantic code analysis (#3524)
When running semantic analysis on a material, we were arbitrarily choosing the first code gen permutation to analyze. So, running matc with arguments --api metal versus --api all would run analysis on slightly different shader code. This causes bugs when flags passed to glslang differ during semantic analysis. This change updates all semantic analysis to always use the same shader code.
2021-02-08 14:06:11 -08:00
Philip Rideout 06538145b5 Vulkan: implement setMinMaxLevels, refactor VulkanTexture. 2021-02-08 13:33:25 -08:00
Philip Rideout ec486b888c PostProcessManager: call setMinMaxLevels in more places.
This fixes some OpenGL non-compliance (as per "Rendering Feedback
Loops" in the spec), as well as validation errors with Vulkan.

I'm hopeful this can be automatic in the new frame graph. :)
2021-02-08 13:33:02 -08:00
Philip Rideout 7b7d63a91f Fix ubershader regression with Transmission / Sheen. 2021-02-08 13:04:25 -08:00
Philip Rideout 466629d967 Ignore VK_KHR_portability_subset for now.
This is a temporary workaround to allow running validation with MoltenVK
even though we do not conform to the portability subset.
2021-02-08 12:24:02 -08:00
Benjamin Doherty 5e68dc5f8d Bump version to 1.9.12 2021-02-08 09:58:15 -08:00
Ben Doherty c4d0dcf639 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:54:27 -08:00
Benjamin Doherty ad90fa1183 Release Filament 1.9.11 2021-02-08 09:54:27 -08:00
Philip Rideout ed57d6a40f Vulkan: fix lifetime issue with image views.
This prevents an "Invalid VkImageView Object" error that would occur
after disabling bloom.

This was caused by the fact that we do not bother zeroing out all the
descriptor slots that are not used by the current draw call.
2021-02-08 09:53:42 -08:00
Ben Doherty 22e4a54782 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:50:23 -08:00
Benjamin Doherty 1289922c5f Release Filament 1.9.11 2021-02-08 09:48:50 -08:00
Ben Doherty 00f50c5f5a Draft: fix TSAN issue by using lock in ColorGrading constructor (#3510)
This is a second attempt to fix Google3 TSAN failures seen inside of the ColorGrading constructor.

Related first attempt: #3462
2021-02-05 14:05:21 -08:00
Philip Rideout 23c90a624d RenderTarget demo should create depth attachment.
This "fixes" #3501, which was not really a bug.  (doh)
2021-02-05 11:21:06 -08:00
Philip Rideout 0e27f0c162 RenderTarget demo now disables post-processing in offscreen view.
The color now match up perfectly.  Woops.

(#3402)
2021-02-05 11:21:06 -08:00
Philip Rideout 297f3d9808 Fix logcat spam with ubershaders.
Since the ubershader does not have variants for clear coat, the dummy
texture there should be unconditional.
2021-02-05 09:07:58 -08:00
Philip Rideout b4f6400d2e Do not exclude Vulkan from continuous Android CI. 2021-02-05 09:07:27 -08:00
Philip Rideout 4d905eb4bb Repair Vulkan-enabled Android builds.
We should probably change our continuous CI so that it does not
exclude Vulkan, but keep our release CI as is (for small binaries).

Fixes #3505
2021-02-05 08:41:39 -08:00
Philip Rideout 83a58033d1 Re-enable optimal bloom on Intel GPUs. 2021-02-05 08:38:29 -08:00
Philip Rideout edc8162ebb PostProcessManager Bloom: fix call to setMinMaxLevels.
This was being called on the wrong texture.
2021-02-05 08:38:29 -08:00
Romain Guy da2c9b8092 Fix doc typo 2021-02-04 14:47:22 -08:00
Romain Guy 2cf3fb569a Update Kotlin to 1.4.30 2021-02-04 14:42:50 -08:00
Benjamin Doherty 0c6de2cb58 Update RELEASE_NOTES 2021-02-04 12:47:53 -08:00
Ben Doherty 07ddd52dcf Add getVertexIndex API for vertex shaders (#3493) 2021-02-04 12:40:21 -08:00
Philip Rideout f6425fdcfb VulkanBlitter progress. 2021-02-03 17:59:59 -08:00
Philip Rideout 521c7fc713 Restore "magic resolve" as per code review. 2021-02-03 17:56:01 -08:00
Philip Rideout 3175711323 Fix MSAA for OpenGL ES 3.0 core.
This fixes `GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE` caused by the
following spec clause being violated:

```
The value of RENDERBUFFER_SAMPLES [must be] the same for all
attached renderbuffers and, if the attached images are a mix of
renderbuffers and textures, the value of RENDERBUFFER_SAMPLES
is zero.
```

Tested on Chrome with Triangle and Helmet demos (after enabling MSAA).
Also tried running the automation suite in a debug build on macOS.

Fixes #3128.
2021-02-03 17:56:01 -08:00
Philip Rideout d669b1b26f Add null terminator to fix Windows build. 2021-02-03 14:56:34 -08:00
Philip Rideout c2b4b6347e matc: add --raw argument for internal use.
This feature can generate SPIRV blobs and will be used by VulkanBlitter.

(#3485)
2021-02-03 14:56:34 -08:00
Philip Rideout 8d13b7634c Upgrade MoltenVK. 2021-02-03 09:54:19 -08:00
Philip Rideout 89bf201b6c Refactoring: Add VulkanBlitter, inspired by MetalBlitter.
This is a prep step to fix #3485.
2021-02-03 08:13:21 -08:00
Philip Rideout 9f68daeb8f Remove unused sampler params. 2021-02-02 10:51:16 -08:00
Philip Rideout c62b88013b Add setMinMaxLevels to DriverAPI.
This adds setMinMaxLevels to the DriverAPI and calls it from
PostProcessManager and the new unit test. The allows us to be compliant
to the OpenGL specification. The new unit test now looks much better on
Intel GPUs. Chrome still gives an INVALID_OPERATION.

Unfortunately the actual bloom effect still has issues on my Intel GPU,
even though the test passes. So, we need to keep the ping-pong
implementation both for Chrome and for Intel.
2021-02-02 10:51:16 -08:00
Philip Rideout 2e8df10e6e Quaternion slerp: ensure "short path" when falling back to lerp.
I noticed that our slerp function sometimes produces a jolt in
animation, but only when the time delta is very small, and only when the
two operands have completely opposing signs.

For example, let's say you are slerping from <0.76, 0.39, 0.51, 0.19>
to <-0.72, -0.45, -0.49, -0.17>.

These quats are actually quite near to each other because the total
negation of the second quat is similar to the first quat.

We were already doing the short path check in the proper slerp path, but
not when falling back to lerp due to a small angle.
2021-02-01 14:35:05 -08:00
Romain Guy 2f9c310127 Update RELEASE_NOTES.md 2021-02-01 14:24:02 -08:00
2716 changed files with 297786 additions and 159051 deletions
+4
View File
@@ -17,6 +17,10 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Logs**
If applicable, copy logs from your console here. Please *do not*
use screenshots of logs, copy them as text.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- GPU: [e.g. NVIDIA GTX 1080]
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build-linux:
name: build-linux
runs-on: ubuntu-latest
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2.0.0
+3
View File
@@ -21,3 +21,6 @@ jobs:
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
build/common/check-headers.sh out/release/filament/include
+8 -2
View File
@@ -1,6 +1,12 @@
name: Presubmit
on: [pull_request]
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build-desktop:
@@ -9,7 +15,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
os: [macos-latest, ubuntu-18.04]
steps:
- uses: actions/checkout@v2.0.0
+36 -11
View File
@@ -1,14 +1,25 @@
name: Release
# This Workflow can be triggered two ways:
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to build and upload assets.
# 2. A repository_dispatch API event is sent. This triggers a build for only the platform specified in the dispatch event.
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to
# build and upload assets.
# 2. A workflow_dispatch event is triggered from the GitHub web UI. This triggers a build for only
# the platform specified in the dispatch event.
env:
RELEASE_TAG: ${{ github.event.client_payload.release_tag }}
RELEASE_TAG: ${{ github.event.inputs.release_tag }}
on:
repository_dispatch:
workflow_dispatch:
inputs:
platform:
description: 'Platform to build (desktop, web, android, ios, windows)'
required: true
default: 'desktop'
release_tag:
description: 'Release tag to build (e.g., v1.13.0)'
required: true
default: 'v1.13.0'
release:
types: [created]
@@ -16,11 +27,11 @@ jobs:
build-desktop:
name: build-desktop
runs-on: ${{ matrix.os }}
if: github.event_name == 'release' || github.event.client_payload.platform == 'desktop'
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
os: [macos-latest, ubuntu-18.04]
steps:
- name: Decide Git ref
@@ -51,7 +62,7 @@ jobs:
build-web:
name: build-web
runs-on: macos-latest
if: github.event_name == 'release' || github.event.client_payload.platform == 'web'
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
steps:
- name: Decide Git ref
@@ -80,7 +91,7 @@ jobs:
build-android:
name: build-android
runs-on: macos-latest
if: github.event_name == 'release' || github.event.client_payload.platform == 'android'
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
steps:
- name: Decide Git ref
@@ -96,6 +107,20 @@ jobs:
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh release
- name: Sign sample-gltf-viewer
run: |
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
base64 --decode filament.jks.base64 > filament.jks
BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | sort -V | tail -n 1)
APKSIGNER=${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner
IN_FILE="out/sample-gltf-viewer-release.apk"
OUT_FILE="out/filament-gltf-viewer-${TAG}-android.apk"
${APKSIGNER} sign --ks filament.jks --key-pass=pass:${APK_KEYSTORE_PASS} --ks-pass=pass:${APK_KEYSTORE_PASS} --in ${IN_FILE} --out ${OUT_FILE}
rm "${IN_FILE}"
env:
TAG: ${{ steps.git_ref.outputs.tag }}
APK_KEYSTORE_BASE64: ${{ secrets.APK_KEYSTORE_BASE64 }}
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
- name: Upload release assets
run: |
pip3 install setuptools
@@ -107,7 +132,7 @@ jobs:
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
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
env:
TAG: ${{ steps.git_ref.outputs.tag }}
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
@@ -115,7 +140,7 @@ jobs:
build-ios:
name: build-ios
runs-on: macos-latest
if: github.event_name == 'release' || github.event.client_payload.platform == 'ios'
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
steps:
- name: Decide Git ref
@@ -144,7 +169,7 @@ jobs:
build-windows:
name: build-windows
runs-on: windows-latest
if: github.event_name == 'release' || github.event.client_payload.platform == 'windows'
if: github.event_name == 'release' || github.event.inputs.platform == 'windows'
steps:
- name: Decide Git ref
+16 -41
View File
@@ -4,29 +4,23 @@
To build Filament, you must first install the following tools:
- CMake 3.10 (or more recent)
- CMake 3.19 (or more recent)
- clang 7.0 (or more recent)
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
To build the Java based components of the project you can optionally install (recommended):
- OpenJDK 1.8 (or more recent)
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
Additional dependencies may be required for your operating system. Please refer to the appropriate
section below.
To build Filament for Android you must also install the following:
- Android Studio 4.1.0 or more recent
- Android Studio Arctic Fox or more recent
- Android SDK
- Android NDK "side-by-side" 22.0 or higher
- Android NDK "side-by-side" 23.1 or higher
### Environment variables
Make sure the environment variable `ANDROID_HOME` points to the location of your Android SDK.
By default our build system will attempt to compile the Java bindings. To do so, the environment
variable `JAVA_HOME` should point to the location of your JDK.
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
location of your Android SDK.
When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#webassembly).
@@ -65,25 +59,13 @@ To install the libraries and executables in `out/debug/` and `out/release/`, add
You can force a clean build by adding the `-c` flag. The script offers more features described
by executing `build.sh -h`.
### Disabling Java builds
By default our build system will attempt to compile the Java bindings. If you wish to skip this
compilation step simply pass the `-j` flag to `build.sh`:
```
$ ./build.sh -j release
```
If you use CMake directly instead of the build script, pass `-DFILAMENT_ENABLE_JAVA=OFF`
to CMake instead.
### Filament-specific CMake Options
The following CMake options are boolean options specific to Filament:
- `FILAMENT_ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
- `FILAMENT_ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
- `FILAMENT_SUPPORTS_OPENGL`: Include the OpenGL backend
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
@@ -162,14 +144,6 @@ make sure the command line tools are setup by running:
$ xcode-select --install
```
After installing Java 1.8 you must also ensure that your `JAVA_HOME` environment variable is
properly set. If it doesn't already point to the appropriate JDK, you can simply add the following
to your `.profile`:
```
export JAVA_HOME="$(/usr/libexec/java_home)"
```
Then run `cmake` and `ninja` to trigger a build:
```
@@ -317,11 +291,11 @@ Alternatively you can build the AAR from the command line by executing the follo
`android/` directory:
```
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
$ ./gradlew -Pcom.google.android.filament.dist-dir=../../out/android-release/filament assembleRelease
```
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
the CMake install prefix used in the previous steps).
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
directory (it must match the CMake install prefix used in the previous steps).
#### Using Filament's AAR
@@ -375,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.12.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python ./emsdk.py install latest
python ./emsdk.py activate latest
@@ -422,12 +396,13 @@ filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
```
Most samples accept an IBL that must be generated using the `cmgen` tool (`./tools/filamesh/cmgen`
in your build directory). These sample apps expect a path to a directory containing the '.rgb32f'
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data). To generate an IBL simply use
this command:
in your build directory). These sample apps expect a path to a directory containing the `.rgb32f`
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data) or a path to a directory
containing two `.ktx` files (one for the IBL itself, one for the skybox). To generate an IBL
simply use this command:
```
cmgen -x ./ibls/ my_ibl.exr
cmgen -f ktx -x ./ibls/ my_ibl.exr
```
The source environment map can be a PNG (8 or 16 bit), a PSD (16 or 32 bit), an HDR or an OpenEXR
+121 -53
View File
@@ -1,7 +1,7 @@
# ==================================================================================================
# CMake
# ==================================================================================================
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.19)
# ==================================================================================================
# Project declaration
@@ -11,8 +11,6 @@ project(TNT)
# ==================================================================================================
# Options
# ==================================================================================================
option(FILAMENT_ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(FILAMENT_USE_SWIFTSHADER "Compile Filament against SwiftShader" OFF)
@@ -25,6 +23,16 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_WAYLAND "Include Wayland support in Linux builds" OFF)
option(FILAMENT_SKIP_SDL2 "Skip dependencies of SDL2, and SDL2" OFF)
option(FILAMENT_LINUX_IS_MOBILE "Treat Linux as Mobile" OFF)
set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
)
@@ -37,8 +45,12 @@ set(FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB "1" CACHE STRING
"Size of the command-stream buffer. As a rule of thumb use the same value as FILAMENT_PER_FRRAME_COMMANDS_SIZE_IN_MB, default 1."
)
set(FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB "2" CACHE STRING
"Size of the OpenGL handle arena, default 2."
set(FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB "4" CACHE STRING
"Size of the OpenGL handle arena, default 4."
)
set(FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB "8" CACHE STRING
"Size of the Metal handle arena, default 8."
)
# ==================================================================================================
@@ -88,20 +100,34 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
endif()
if (LINUX)
if (FILAMENT_SUPPORTS_XCB)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
endif()
if (FILAMENT_SUPPORTS_WAYLAND)
add_definitions(-DFILAMENT_SUPPORTS_WAYLAND)
set(FILAMENT_SUPPORTS_X11 FALSE)
else ()
if (FILAMENT_SUPPORTS_XCB)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
endif()
if (FILAMENT_SUPPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
if (FILAMENT_SUPPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
endif()
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_X11)
set(FILAMENT_SUPPORTS_X11 TRUE)
endif()
endif()
endif()
if (ANDROID OR WEBGL OR IOS)
if (ANDROID OR WEBGL OR IOS OR FILAMENT_LINUX_IS_MOBILE)
set(IS_MOBILE_TARGET TRUE)
endif()
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
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()
@@ -125,27 +151,35 @@ if (WIN32)
# __declspec(dllexport) in front of each functions).
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
# The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
# global method here:
if (${USE_STATIC_CRT})
set(CRT_FLAGS_RELEASE "/MT")
set(CRT_FLAGS_DEBUG "/MTd")
add_compile_options(
$<$<CONFIG:>:/MT>
$<$<CONFIG:Debug>:/MTd>
$<$<CONFIG:Release>:/MT>
)
else()
set(CRT_FLAGS_RELEASE "/MD")
set(CRT_FLAGS_DEBUG "/MDd")
add_compile_options(
$<$<CONFIG:>:/MD>
$<$<CONFIG:Debug>:/MDd>
$<$<CONFIG:Release>:/MD>
)
endif()
# TODO: Figure out why pdb generation messes with incremental compilaton.
# IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Z7")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
# In RELEASE, also generate PDBs.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
# In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
# Instead generate debug info directly inside obj files.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
# Special settings when building on CI.
if (${FILAMENT_WINDOWS_CI_BUILD})
@@ -265,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)
@@ -285,6 +319,12 @@ if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
endif()
# Use hidden by default and expose what we need.
if (NOT WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
endif()
# ==================================================================================================
# Release compiler flags
# ==================================================================================================
@@ -299,7 +339,7 @@ endif()
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
if (ANDROID OR WEBGL)
if (ANDROID OR IOS OR WEBGL)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
endif()
@@ -365,6 +405,12 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebIn
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTNT_DEV")
endif()
# By default, build with support for OpenGL on all platforms.
option(FILAMENT_SUPPORTS_OPENGL "Include the OpenGL backend" ON)
if (FILAMENT_SUPPORTS_OPENGL)
add_definitions(-DFILAMENT_SUPPORTS_OPENGL)
endif()
# By default, build with Vulkan support on desktop platforms, although clients must request to use
# it at run time.
if (WIN32 OR WEBGL OR IOS)
@@ -400,6 +446,13 @@ else()
option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" OFF)
endif()
# Only optimize materials in Release mode (so error message lines match the source code)
if (CMAKE_BUILD_TYPE MATCHES Release)
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" OFF)
else()
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" ON)
endif()
# ==================================================================================================
# Material compilation flags
# ==================================================================================================
@@ -413,9 +466,9 @@ endif()
set(MATC_API_FLAGS )
# TODO: Add a flag to build Filament without support for OpenGL.
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
if (FILAMENT_SUPPORTS_OPENGL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a vulkan)
endif()
@@ -423,9 +476,9 @@ if (FILAMENT_SUPPORTS_METAL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
endif()
# Only optimize materials in Release mode (so error message lines match the source code)
if (NOT CMAKE_BUILD_TYPE MATCHES Release)
set(MATC_OPT_FLAGS -g)
# Disable optimizations and enable debug info (preserves names in SPIR-V)
if (FILAMENT_DISABLE_MATOPT)
set(MATC_OPT_FLAGS -gd)
endif()
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
@@ -443,11 +496,15 @@ if (NOT DIST_ARCH)
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*;.*")
set(DIST_ARCH "universal")
else()
if (NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
if (NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
set(DIST_ARCH "${CMAKE_OSX_ARCHITECTURES}")
endif()
endif()
endif()
# On Windows machines, the host processor is set to 'AMD64', which we'll interpret as x86_64.
string(TOLOWER "${DIST_ARCH}" DIST_ARCH)
string(REPLACE "amd64" "x86_64" DIST_ARCH "${DIST_ARCH}")
if (NOT DIST_DIR)
set(DIST_DIR "${DIST_ARCH}")
endif()
@@ -465,11 +522,15 @@ function(list_licenses OUTPUT MODULES)
foreach(module ${_MODULES})
set(license_path "../../third_party/${module}/LICENSE")
get_filename_component(fullname "${license_path}" ABSOLUTE)
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
file(READ ${license_path} license_long)
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
string(APPEND CONTENT "\n\n")
if(EXISTS ${fullname})
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
file(READ ${license_path} license_long)
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
string(APPEND CONTENT "\n\n")
else()
message(AUTHOR_WARNING "${license_path} not found. You can ignore this warning if you have devendored ${module}.")
endif()
endforeach()
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
endfunction(list_licenses)
@@ -485,7 +546,12 @@ function(combine_static_libs TARGET OUTPUT DEPS)
# Loop through the dependent libraries and query their location on disk.
set(DEPS_FILES )
foreach(DEPENDENCY ${DEPS})
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
if(TARGET ${DEPENDENCY})
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
if(dep_type STREQUAL "STATIC_LIBRARY")
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
endif()
endif()
endforeach()
add_custom_command(
@@ -518,12 +584,14 @@ if (FILAMENT_USE_SWIFTSHADER)
find_library(SWIFTSHADER_VK NAMES vk_swiftshader HINTS "$ENV{SWIFTSHADER_LD_LIBRARY_PATH}")
message(STATUS "Found SwiftShader VK library in: ${SWIFTSHADER_VK}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${SWIFTSHADER_VK}\")
elseif (FILAMENT_SUPPORTS_VULKAN AND APPLE)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
if (Vulkan_LIBRARY)
set(Vulkan_FOUND ON)
message(STATUS "Found Vulkan library in SDK: ${Vulkan_LIBRARY}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${Vulkan_LIBRARY}\")
elseif (FILAMENT_SUPPORTS_VULKAN)
if (APPLE OR FILAMENT_LINUX_IS_MOBILE)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
if (Vulkan_LIBRARY)
set(Vulkan_FOUND ON)
message(STATUS "Found Vulkan library in SDK: ${Vulkan_LIBRARY}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${Vulkan_LIBRARY}\")
endif()
endif()
endif()
@@ -572,23 +640,29 @@ add_subdirectory(${EXTERNAL}/libgtest/tnt)
add_subdirectory(${LIBRARIES}/camutils)
add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
add_subdirectory(${LIBRARIES}/image)
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}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
add_subdirectory(${EXTERNAL}/smol-v/tnt)
add_subdirectory(${EXTERNAL}/benchmark/tnt)
add_subdirectory(${EXTERNAL}/meshoptimizer)
add_subdirectory(${EXTERNAL}/cgltf/tnt)
add_subdirectory(${EXTERNAL}/draco/tnt)
add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
@@ -602,7 +676,6 @@ if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
# the material debugger requires filamat
if (FILAMENT_ENABLE_MATDBG OR IS_HOST_PLATFORM)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${LIBRARIES}/matdbg)
endif()
endif()
@@ -624,22 +697,16 @@ if (WEBGL)
endif()
if (IS_HOST_PLATFORM)
add_subdirectory(${LIBRARIES}/bluegl)
if (FILAMENT_SUPPORTS_OPENGL)
add_subdirectory(${LIBRARIES}/bluegl)
endif()
add_subdirectory(${LIBRARIES}/filamentapp)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/java/filamat)
add_subdirectory(${FILAMENT}/java/filament)
add_subdirectory(${FILAMENT}/java/gltfio)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
@@ -655,6 +722,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/mipgen)
add_subdirectory(${TOOLS}/normal-blending)
add_subdirectory(${TOOLS}/resgen)
add_subdirectory(${TOOLS}/rgb-to-lmsr)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color)
endif()
+40 -60
View File
@@ -31,39 +31,28 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.9.11'
implementation 'com.google.android.filament:filament-android:1.17.0'
}
```
Here are all the libraries available in the group `com.google.android.filament`:
[![filament-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android/badge.svg?subject=filament-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android)
The Filament rendering engine itself.
[![gltfio-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android)
A glTF 2.0 loader for Filament, depends on `filament-android` .
[![gltfio-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite/badge.svg?subject=gltfio-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite)
Trimmed version of `gltfio` that does not support some glTF features.
[![filament-utils-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android)](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`.
[![filament-utils-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite/badge.svg?subject=filament-utils-lite)](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.
[![filamat-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android)](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.
[![filamat-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite)](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.
| Artifact | Description |
| ------------- | ------------- |
| [![filament-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android/badge.svg?subject=filament-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
| [![gltfio-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [![gltfio-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite/badge.svg?subject=gltfio-android-lite)](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. |
| [![filament-utils-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android)](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`. |
| [![filament-utils-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite/badge.svg?subject=filament-utils-lite)](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. |
| [![filamat-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android)](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. |
| [![filamat-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite)](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. |
### iOS
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.9.11'
pod 'Filament', '~> 1.17.0'
```
### Snapshots
@@ -97,25 +86,12 @@ steps:
![Helmet](docs/images/samples/example_helmet.jpg)
![Screen-space refraction](docs/images/samples/example_ssr.jpg)
### Applications
Here are a few screenshots of applications that use Filament in production:
#### Google Maps AR Navigation
![Google Maps AR Navigation](docs/images/samples/app_gmm_ar_nav.jpg)
#### Google Search 3D/AR Viewer on Android
![Google Search 3D/AR Viewer on Android](docs/images/samples/app_google_3d_viewer.jpg)
## Features
### APIs
- Native C++ API for Android, iOS, Linux, macOS and Windows
- Java/JNI API for Android, Linux, macOS and Windows
- Java/JNI API for Android
- JavaScript API
### Backends
@@ -131,6 +107,7 @@ Here are a few screenshots of applications that use Filament in production:
- Clustered forward renderer
- Cook-Torrance microfacet specular BRDF
- Lambertian diffuse BRDF
- Custom lighting/surface shading
- HDR/linear lighting
- Metallic workflow
- Clear coat
@@ -142,20 +119,27 @@ Here are a few screenshots of applications that use Filament in production:
- Physically-based camera (shutter speed, sensitivity and aperture)
- Physical light units
- Point lights, spot lights and directional light
- Specular anti-aliasing
- Spot and directional light shadows
- Cascaded shadows
- VSM or PCF shadows
- EVSM, PCSS, DPCF, or PCF shadows
- Transparent shadows
- Contact shadows
- Screen-space ambient occlusion
- Screen-space refraction
- Global fog
- Dynamic resolution (with support for AMD FidelityFX FSR)
### Post processing
- HDR bloom
- Depth of field bokeh
- Multiple tone mappers: ACES, filmic, etc.
- Color grading: white balance, channel mixer, shadows/mid-tones/highlights, ASC CDL,
contrast, saturation, etc.
- TAA, FXAA, MSAA and specular anti-aliasing
- Dynamic resolution
- Multiple tone mappers: generic (customizable), ACES, filmic, etc.
- Color and tone management: luminance scaling, gamut mapping
- Color grading: exposure, night adaptation, white balance, channel mixer,
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
- TAA, FXAA, MSAA
- Screen-space lens flares
### glTF 2.0
@@ -167,9 +151,9 @@ Here are a few screenshots of applications that use Filament in production:
- [x] Points
- [x] Lines
- [ ] Line Loop
- [ ] Line Strip
- [x] Line Strip
- [x] Triangles
- [ ] Triangle Strip
- [x] Triangle Strip
- [ ] Triangle Fan
- Animation
@@ -184,10 +168,12 @@ Here are a few screenshots of applications that use Filament in production:
- [x] KHR_draco_mesh_compression
- [x] KHR_lights_punctual
- [x] KHR_materials_clearcoat
- [x] KHR_materials_ior
- [x] KHR_materials_pbrSpecularGlossiness
- [x] KHR_materials_sheen
- [x] KHR_materials_transmission
- [x] KHR_materials_unlit
- [x] KHR_materials_volume
- [x] KHR_mesh_quantization
- [x] KHR_texture_transform
@@ -255,22 +241,11 @@ if (renderer->beginFrame(swapChain)) {
```
For complete examples of Linux, macOS and Windows Filament applications, look at the source files
in the `samples/` directory. These samples are all based on `samples/app/` which contains the code
that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
in the `samples/` directory. These samples are all based on `libs/filamentapp/` which contains the
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
### Java on Linux, macOS and Windows
After building Filament, you can use `filament-java.jar` and its companion `filament-jni` native
library to use Filament in desktop Java applications.
You must always first initialize Filament by calling `Filament.init()`.
You can use Filament either with AWT or Swing, using respectively a `FilamentCanvas` or a
`FilamentPanel`.
Following the steps above (how to use Filament from native code), create an `Engine` and a
`Renderer`, but instead of calling `beginFrame` and `endFrame` on the renderer itself, call
these methods on `FilamentCanvas` or `FilamentPanel`.
For more information on how to prepare environment maps for image-based lighting please refer to
[BUILDING.md](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples).
### Android
@@ -301,6 +276,10 @@ To get started you can use the textures and environment maps found respectively
`third_party/textures` and `third_party/environments`. These assets are under CC0 license. Please
refer to their respective `URL.txt` files to know more about the original authors.
Environments must be pre-processed using
[`cmgen`](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples) or
using the `libiblprefilter` library.
## How to make contributions
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
@@ -323,9 +302,9 @@ and tools.
- `docs`: Documentation
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
- `filament`: Filament rendering engine (minimal dependencies)
- `backend`: Rendering backends/drivers (Vulkan, Metal, OpenGL/ES)
- `ide`: Configuration files for IDEs (CLion, etc.)
- `ios`: Sample projects for iOS
- `java`: Java bindings for Filament libraries
- `libs`: Libraries
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
@@ -345,6 +324,7 @@ and tools.
- `math`: Math library
- `mathio`: Math types support for output streams
- `utils`: Utility library (threads, memory, data structures, etc.)
- `viewer`: glTF viewer library (requires gltfio)
- `samples`: Sample desktop applications
- `shaders`: Shaders used by `filamat` and `matc`
- `third_party`: External libraries and assets
+5 -3
View File
@@ -39,7 +39,7 @@ build/common/bump-version.sh $RELEASE
Commit changes to main with the title:
```
Bump version to $RELEASE
Release Filament $RELEASE
```
Do not push to origin yet.
@@ -106,7 +106,9 @@ git push origin release
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
Make sure the target is set to the release branch.
## 7. Delete the old rc branch.
## 7. Delete the old rc branch (optional).
This step is optional. The old rc branch may be left alive for a few weeks for posterity.
```
git push origin --delete rc/$RELEASE
@@ -134,5 +136,5 @@ git push origin main
## 10. Push the new rc branch.
```
git push origin rc/$NEXT_RELEASE
git push origin -u rc/$NEXT_RELEASE
```
+421 -6
View File
@@ -3,7 +3,422 @@
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.
## Next release (main branch)
## v1.17.1 (currently main branch)
## 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**].
- engine: Add support for the glTF extension KHR_materials_emissive_strength.
- engine: Improvements and fixes to skinning calculations.
- engine: Fix debug checks for compressed textures.
- Metal: Fix `readPixels` when dimensions are greater than the render target's.
## 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.
## v1.15.1
- engine: add support for DPCF (PCF shadows with contact hardening).
- engine: add support for Wayland and Vulkan.
- engine: Fade lights out when close to light far plane.
- Java: Add missing `Engine#destroySkinningBuffer` method.
## v1.15.0
- engine: Fix spotlights normal bias calculation [⚠️ **Material breakage**].
- libimage: Fix loading spherical harmonics on certain locals.
## v1.14.2
- Metal: Fix validation error when rendering to `RenderTarget` without depth attachment.
- engine: Fix rendering glitch with zero-scale bone transforms.
## v1.14.1
- engine: Improvements to shadowing.
## v1.14.0
- engine: Internal materials can use structures as parameters [⚠️ **Material breakage**].
- engine: `readPixels` on a `SwapChain` must be called within `beginFrame` / `endFrame` [⚠️ **API
Change**].
- engine: Fix normal bias and improve spotlight quality.
- Java: Fix shadow biases.
## v1.13.0
- Android: Gradle configuration caching is now enabled.
- Android: Filament's Gradle properties have all been renamed to `com.google.android.filament.xxx`
where `xxx` is the property name. See `android/build.gradle` for a complete list [⚠️]
- Android: The Gradle property `filament_tools_dir` (now called
`com.google.android.filament.tools-dir`) does not have a default value anymore. Please specify one
in your `gradle.properties` if you reuse the Gradle plugin in your projects [⚠️]
- engine: Fix spotlights direction and falloff [⚠️ **Material breakage**].
- engine: Improvements to VSM and spotlight shadows.
## v1.12.11
- Metal: Color grading performance improvement on M1 devices.
- samples: Fix glitchy animation seen in gltf-viewer iOS sample.
## v1.12.10
- engine: rewrite dynamic resolution scaling controller for better accuracy and less jittering.
- Java: fix missing ASTC texture enum.
- tools: Fix normal map issues in mipgen.
- WebGL: expose some `SurfaceOrientation` functions.
## v1.12.9
- engine: New API: `MultiSampleAntiAliasingOptions` and HDR-aware MSAA resolve. When `customResolve`
is enabled, improves anti-aliasing quality [**NEW API**].
- engine: Fixes and improvements for FSR.
- engine: All APIs that take a callback as argument now also take a `CallbackHandler*`, a new
interface that provides more flexibility around callback dispatch [**NEW API**].
- Android: Fix JNI bindings for `DepthOfFieldOptions`.
- Android: workarounds for Adreno-specific fraembuffer issue.
- JavaScript: updates to JS bindings.
## v1.12.8
- engine: Added picking API to `View` [⚠️ **Materials need to be rebuilt to access this new feature**].
- engine: A new `Engine::pumpMessageQueues()` method can be used to trigger all pending user
callbacks right away [**NEW API**].
- engine: new inline helpers to more easily use lambdas, functors and method callbacks with
`{Pixel}BufferDescriptor`.
- Vulkan: fix vertical offset for `readPixels`.
- Vulkan: various internal improvements.
- Metal: support integer formats with `readPixels`.
## v1.12.7
- engine: Fix, apply emissive after shadowing.
## v1.12.6
- engine: Added concept of lod bias to materials.
[⚠️ **Materials need to be rebuilt to access this new feature**].
- engine: Fix, BGRA ordering respected for external images with OpenGL on iOS.
- engine: Use more sensible defaults for spot light inner outer cone angles.
- engine: Fix potential race condition that caused stalls in `endFrame`.
- gltfio: Improved handling of transparent materials.
- Metal: Fix potential crash on earlier versions of iOS (<= 13.0).
- Android: Fix `filament-utils-android` 'lite' flavor.
- Java: Fix potential crash with `IBLPrefilter`.
## v1.12.5
- engine: work around a job scheduling issue in `endFrame` that caused stuttering on some Android
devices.
## v1.12.4
- engine: New night adaptation API on `ColorGrading`. This API can be used to create an effect that
that simulates color and brightness shifts in human vision in low-light conditions.
- engine: improved performance of AMD FidelityFX FSR1 by 4.6x, it now runs in about 2ms in 4K.
- engine: Dynamic resolution quality `MEDIUM`, `HIGH` and `ULTRA` now all use AMD FidelityFX FSR1.
- engine: Fix crash when duplicating material instances.
- gltfio: generate tangents if requested by the material.
## v1.12.3
- engine: Support AMD FidelityFX Super Resolution for dynamic resolution scaling
## v1.12.2
- engine: New API on `ColorGrading` to enable or disable gamut mapping at will [**New API**].
- engine: Fix typo causing ShadowOptions::shadowFar to not work properly.
- engine: Fix, CSM glitch when using shadowMultiplier materials.
- engine: Improve precision when computing camera projection.
- engine: Increase the number of supported spot shadows to 14 (from 6).
- Metal: Add texture swizzling support for external textures.
## v1.12.1
- engine: `double` precision translation support in TransformManager. Disabled by default.
Augment model (and view) matrix on `Camera` to accept double precision matrices. When enabled,
double precision translations allow filament to handle a very large world space [**New API**].
- engine: Fix, Views with custom render targets are now blendable.
## v1.12.0
- engine: Option to automatically compute bent normals from SSAO & apply to specular AO
[⚠️ **Material breakage**].
- engine: New APIs: Light channels. Geometry and lights now have a channel associated to them, at
least one channel must match for lighting to occur [⚠️ **Material breakage**].
- engine: Fix potential GPU crash with punctual lights near the far clipping plane.
- materials: The `inverseTonemap` API is now an exact inverse of the Filmic tonemapper.
- Metal: Better support for texture formats on M1 Macs.
## v1.11.2
- engine: New API: `ColorGrading::Builder::toneMapper(const ToneMapper*)`.
- engine: New tone mapper: `GenericToneMapper`, a configurable tone mapper.
- engine: `ColorGrading::Builder::toneMapping(ColorGrading::ToneMapping)` is now deprecated.
- engine: Removed `REINHARD` tonemap operator[⚠️ **API Change**].
- engine: Improve s3tc_srgb detection on desktop.
- engine: Add bilateral threshold in SSAO options.
- gltfio: Fix AssetLoader leak, remove unwanted destructor.
- Metal/Vulkan: Fix uploading texture data with padding or offset.
- Metal: fix GPU crash seen with large amounts of geometry.
## v1.11.1
- engine: Luminance scaling can now be used with any tone mapping operator. It was previously tied
to the "EVILS" tone mapping operator.
- engine: Removed the "EVILS" tone mapping operator [⚠️ **API Change**].
- engine: Improvements to Skinning. A new `SkinningBuffer` API allows bone sharing between
renderables.
- engine: Improvements to internal memory allocation for Metal and Vulkan backends.
- engine: Default to OpenGL backend when Windows does not support Vulkan.
- samples: Add new sample app: image_viewer.
## v1.11.0
- engine: Added support for transparent shadows. Add `transparentShadow : true` in the material file.
- engine: honor user-defined precision in material files for non-samplers, rename `SamplerPrecision`
to `ParameterPrecicion`. [⚠️ **API Change**]
- engine: Work around Qualcomm issue with point lights.
- engine: Allow MSAA when post-processing is disabled.
- engine: enable up to 6 spot-light shadows.
- gltfio: Added support for `KHR_materials_volume`.
- gltfio: fix precision in KHR_texture_transform.
- java: Removed support for Java desktop targets (macOS, Linux, and Windows) [⚠️ **API Change**].
## v1.10.7
- engine: Spot-light position calculation moved to fragment shader.
- engine: Small shadow mapping fixes and improvements.
- gltfio: Add fast path for native material providers.
- gltfio: Allow Java / Kotlin clients to customize MaterialProvider.
- engine: Fix out of bounds access with `RenderTarget` java bindings.
- Metal: `TextureFormat::DEPTH24_STENCIL8` now maps to a 32 bit depth format on iOS.
## v1.10.6
- engine: Use exponential VSM and improve VSM user settings [⚠️ **Recompile Materials for VSM**].
- engine: Optional blurring of VSM shadowmaps.
- engine: Fix a crash when using lens flares.
- engine: Fix backend crashes when using an unsupported sample count.
- gltfio: Add new `getAsset`API to `FilamentInstance`.
- gltfio: Introduce support for extras strings.
- OpenGL: Increase OpenGL backend handle arena from 2 to 4 MiB.
- Vulkan: Fix Texture swizzle support.
## v1.10.5
- android: AAR libraries now properly include their ProGuard rules.
- engine: User materials can now provide custom lighting/surface shading, please consult
the [materials documentation](https://google.github.io/filament/Materials.html) for details.
- engine: `Backend::DEFAULT` now selects the most appropriate backend for the platform, rather than
always `OPENGL`. On Android the default is `OPENGL`, on Apple platforms the default is `METAL` and
on all other platforms that default is `VULKAN`.
- engine: Fix a potential memory corruption when using more than 4 render targets.
- engine: Fix a possible crash when bloom is enabled.
- engine: Fix and refactor support for S3TC + SRGB with OpenGL.
- engine: Fix automatic clearing of rendertargets.
- engine: Fix imported render target discard and clear flags.
- engine: Fix opaque blit with imported render targets.
## v1.10.4
- engine: improvements to internal job system.
- Vulkan: performance improvements on Mali.
- gltfio: improvements to load time for large models.
- WebGL: remove bogus stride argument, fix `BindingType` TypeScript definition.
## v1.10.3
- android: use `debug.filament.backend` system property to select the desired backend.
- engine: fix `LightManager::getFalloff`.
- gltfio: fix crash with non-triangles.
- macOS: fix main thread checker warnings with OpenGL.
- vulkan: fix crash on Windows machines with NVIDIA GPUs.
## v1.10.2
- Vulkan: validation and diagnostic improvements
- engine: improvements for scenes with many renderables.
- gltfio: added support for `KHR_materials_ior`.
- java: Add bindings for `IBLPrefilterContext`.
- java: add `KTXLoader.getSphericalHarmonics` JNI binding
- libimage: fix, respect sRGB option for compressed formats.
- sample-gltf-viewer: fix lifetime cycle for RemoteServer.
## v1.10.1
- engine: Add `getPlatform` API to Engine.
- engine: Add a new cone angles API to `LightManager`.
- engine: Attachments of custom RendereTargets are not systematically discarded.
- engine: Fix a crash when using custom rendertargets.
- engine: New API to duplicate a `MaterialInstance`.
- filagui: fix support for custom images in ImGuiHelper.
- java: Add bindings for HDRLoader.
## v1.10.0
- engine: User materials can now use 9 samplers instead of 8 [⚠️ **Material breakage**].
- engine: Remove `populateTangentQuaternions` [⚠️ **API change**].
- engine: Deprecate `Stream::Builder::stream(intptr_t)` [⚠️ **API Change**].
- engine: Remove deprecated APIs: `Camera::setScaling`, `Engine::destroy(Camera*)`,
`Engine::createCamera`, `Renderer::beginFrame(SwapChain*, uint64_t,
backend::FrameScheduledCallback, void*)`, and `View::setShadowsEnabled` [⚠️ **API Change**].
- engine: Remove `focusDistance` from `View::BloomOptions` [⚠️ **API Change**].
- engine: Add a `FILAMENT_SUPPORTS_OPENGL` CMake option to enable/disable OpenGL support.
- Vulkan: fixes and improvements for large scenes.
- gltfio: fix morphing bugs uncovered by MorphStressTest.
- Java: add API for `Texture::Builder::import()`.
- WebGL: Fix a potential INVALID_OPERATION.
## v1.9.25
- NEW API: Screen-space lens flare effect.
- engine: Fix several memory leaks in the GL backend.
- Vulkan: General bug fixes and improvements.
- Vulkan: Fix some problems seen on Mali devices.
- ios: Fix VSM shadows not working.
- webgl: Fix black screen seen with some samples.
## v1.9.24
- engine: Fix memory leaks in OpenGL driver.
- engine: new experimental tone mapper, `EVILS` (name will most likely change).
- engine: Improvements to Vulkan backend.
- engine: Fix incorrect units documented for `LightManager.getIntensity`.
- engine: fix high quality upsampling for SSAO.
- engine: implement accurate normal reconstruction for SSAO.
- engine: improve LOW and HIGH quality levels for SSAO.
- libs: improvements to `libiblprefilter`.
- materials: New `quality` property.
- samples: Add new gltf-viewer iOS sample.
- samples: clear the background in lightbulb sample.
## v1.9.23
- Vulkan: various fixes.
- android: fix crash seen using VSM with MSAA on Adreno devices.
- engine: Add `Engine::getEntityManager()`.
- engine: Fix desktop crash seen with some GPU drivers.
- engine: improve importance sampling.
- gltfio: robustness improvements for Draco meshes.
- libs: Add new Transcoder API for C++ clients (part of `libgeometry`).
- libs: New `iblprefilter` library to compute IBL pre-integration on the GPU using filament.
- materials: Fix documentation for `getNormalizedViewportCoord`.
- samples: fix rendertarget sample crash on launch.
## v1.9.22
- NEW API: `Renderer::renderStandaloneView()` is a new method that can be used outside of
beginFrame/endFrame on Views that have a RenderTarget associated. This can be used as a
pseudo-compute API.
- Vulkan: bug fixes and improvements.
- engine: RenderTarget API can now use MRT.
- sample-gltf-viewer: improvements for reading zip files.
- sample-gltf-viewer: enable contact-shadows functionality in mobile gltf-viewer.
- windows: fix build error in filament_framegraph_test.
## v1.9.21
- JavaScript: add missing TextureSampler bindings.
- Metal: Fix texture swizzling crash with older Nvidia GPUs.
- Vulkan: fix image layout validation error on Android.
- android: fix MSAA w/ multisampled_render_to_texture on Mali.
- engine: better anisotropic filtering with various drivers.
- gltfio: Use BufferObject API, simplify MorphHelper.
- gltfio: honor stride in normalizeSkinningWeights.
- samples: Add web component demo.
## v1.9.20
- Android: Fix VSM.
- engine: Introduce BufferObject API.
- engine: Add new isTextureSwizzleSupported API on Texture.
- engine: Add support to Metal and Vulkan backends for texture swizzling.
- engine: Add new DoF settings (native/half res, gather kernel ring counts, CoC radius clamp).
- engine: DoF quality and performance improvements.
- engine: Fix high-quality upsampling issue with SSAO.
- Java: Expose `TransformManager.getParent(int)`.
- samples: Add Metal and Vulkan backend support to Suzanne sample.
- WebGL: expose fitIntoUnitCube to JS.
- WebGL: support for multiple `<canvas>` elements.
## v1.9.19
- engine: Fix Metal bug when setGeometryAt is called multiple times.
- engine: Improvements to DoF.
- 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
should have been public.
- java: fix bug with Texture::setImage buffer size calculation.
## v1.9.18
- engine: Fix a DoF bug that caused black dots around the fast tiles.
- engine: Minor DoF optimizations.
- engine: Fix blanking windows not being drawn into on macOS.
- gltfio: Add support for data:// in image URI's.
- gltfio: Add internal MorphHelper, enable up to 255 targets.
- engine: Fix a hang in JobSystem.
- samples: Fix rendertarget sample app.
## v1.9.17
- engine: New shift parameter on `Camera` to translate the viewport and emulate a tilt/shift lens.
- engine: `Camera::setCustomProjection()` now allows to set a different projection for culling and rendering.
- engine: Fixed depth of field rendering with custom projection matrices.
- engine: Fix a rare indefinite hang.
- gltfio: `SimpleViewer` now exposes more rendering parameters, including `ColorGrading`.
- gltfio: Fix tangents when morphing is enabled.
- Metal/Vulkan: fix incorrect dominant light shadows rendering.
- Fixe some issues with imported rendertargets.
## v1.9.16
gltfio: Add ResourceLoader evict API.
gltfio: Fix ResourceLoader cache bug.
iOS: Disable exceptions to reduce binary size.
## v1.9.15
- filamat/matc: fix sporadic crash.
## v1.9.14
- Improve bloom/emissive with glTF files.
- Publicly expose Exposure API for gltfio.
## v1.9.13
- Android: fix "No implementation found" error.
- Android: fix compilation error in UbershaderLoader.
- engine: computeDataSize now returns correct value for USHORT_565.
- Vulkan: various internal improvements.
## v1.9.12
- engine: Fixed GL errors seen with MSAA on WebGL.
Warning: this can affect multisampling behavior on devices that do not support OpenGL ES 3.1
- materials: Added new `getVertexIndex()` API for vertex shaders.
- samples: RenderTarget demo now disables post-processing in offscreen view and creates depth attachment.
- gltfio: Fix, animation jolt when time delta is very small.
## v1.9.11
@@ -55,12 +470,12 @@ A new header is inserted each time a *tag* is created.
## v1.9.9
- Vulkan: internal robustness improvements
- Metal: Support CVPixelBuffer SwapChains
- Metal: Support copyFrame
- Vulkan: internal robustness improvements.
- Metal: Support CVPixelBuffer SwapChains.
- Metal: Support copyFrame.
- Fix clear behavior with RenderTarget API.
- Fix GetRefractionMode JNI binding
- Additional fixes for Fence bug
- Fix GetRefractionMode JNI binding.
- Additional fixes for Fence bug.
## v1.9.8
+5 -5
View File
@@ -122,20 +122,20 @@ The Gradle project used to generate the AAR is located at `<filament>\android`.
```
cd android
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease
copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
```
If you're only interested in building for a single ABI, you'll need to pass a `filament_abis` parameter:
If you're only interested in building for a single ABI, you'll need to pass a `com.google.android.filament.abis` parameter:
```
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_abis=x86
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pcom.google.android.filament.abis=x86
```
If you're only interested in building SDK, you may skip samples build by passing a `filament_skip_samples` flag:
If you're only interested in building SDK, you may skip samples build by passing a `com.google.android.filament.skip-samples` flag:
```
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
```
+48 -33
View File
@@ -1,26 +1,28 @@
// This script accepts the following parameters:
//
// filament_dist_dir
// com.google.android.filament.dist-dir
// Path to the Filament distribution/install directory for Android
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
//
// filament_tools_dir
// com.google.android.filament.tools-dir
// Path to the Filament distribution/install directory for desktop.
// This directory must contain bin/matc.
//
// filament_exclude_vulkan
// com.google.android.filament.exclude-vulkan
// When set, support for Vulkan will be excluded.
//
// filament_skip_samples
// com.google.android.filament.skip-samples
// Exclude samples from the project. Useful to speed up compilation.
//
// filament_abis
// com.google.android.filament.abis
// List of supported ABIs to build as a comma separated list. Available options are:
// arm64-v8a, armeabi-v7a, x86_64, x86, all
// Defaults to all.
//
// Example:
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease -Pfilament_abis=x86
// ./gradlew -Pcom.google.android.filament.dist-dir=../dist-android-release \
// -Pcom.google.android.filament.abis=x86 \
// assembleRelease
// Publishing to Maven Central:
// - Build and upload artifacts with ./gradlew publish
@@ -40,45 +42,58 @@
//
buildscript {
def filamentPath = file("../out/android-release/filament").absolutePath
if (project.hasProperty("filament_dist_dir")) {
filamentPath = file(project.property("filament_dist_dir")).absolutePath
}
def path = providers
.gradleProperty("com.google.android.filament.dist-dir")
.forUseAtConfigurationTime().get()
def directory = objects.fileProperty().fileValue(new File(path)).getAsFile().get()
def filamentPath = directory.absolutePath
// Our CMake scripts require a forward-slash path for the FILAMENT_DIST_DIR
// variable, so here we convert the native path to a forward-slash path.
filamentPath = filamentPath.replace(File.separator, '/')
// Warning: changing this property does not work well with incremental builds.
def excludeVulkan = project.hasProperty("filament_exclude_vulkan")
def excludeVulkan = providers
.gradleProperty("com.google.android.filament.exclude-vulkan")
.forUseAtConfigurationTime()
.isPresent()
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
if (project.hasProperty("filament_abis")) {
def newAbis = project.property("filament_abis").split(',')
if (!newAbis.contains("all")) {
abis = newAbis
}
def newAbis = providers
.gradleProperty("com.google.android.filament.abis")
.forUseAtConfigurationTime()
.get()
.split(',')
if (!newAbis.contains("all")) {
abis = newAbis
}
// Our minSdkVersion is 19.
ext.versions = [
'minSdk': 19,
'targetSdk': 30,
'compileSdk': 30,
'kotlin': '1.4.21',
'buildTools': '30.0.3',
'ndk': '22.0.7026061'
'targetSdk': 31,
'compileSdk': 31,
'kotlin': '1.6.0',
'kotlin_coroutines': '1.5.2',
'buildTools': '31.0.0',
'ndk': '23.1.7779620'
]
ext.deps = [
'androidx': [
'annotations': "androidx.annotation:annotation:1.1.0",
'core': "androidx.core:core:1.3.0",
'annotations': "androidx.annotation:annotation:1.3.0",
'core': "androidx.core:core:1.7.0",
],
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}",
'coroutines': [
'core': "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlin_coroutines}",
'android': "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlin_coroutines}",
]
]
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
// NOTE: See TODO in gradle.properties once we move to Gradle 7.2
classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -93,8 +108,7 @@ buildscript {
ext.cppFlags = [
"-std=c++17",
"-Wno-unused-command-line-argument",
// Required to support API levels below 23
"-Wl,--hash-style=both",
"-Wl,--hash-style=both", // Required to support API levels below 23
"-fno-stack-protector",
"-fno-exceptions",
"-fno-unwind-tables",
@@ -116,12 +130,11 @@ buildscript {
repositories {
mavenCentral()
google()
jcenter()
}
}
plugins {
id 'io.codearte.nexus-staging' version '0.22.0'
id 'io.codearte.nexus-staging' version '0.30.0'
}
// Nexus Staging configuration
@@ -138,7 +151,6 @@ subprojects {
repositories {
mavenCentral()
google()
jcenter()
}
if (!name.startsWith("sample")) {
@@ -163,11 +175,13 @@ subprojects {
ndk {
abiFilters(*rootProject.ext.abis)
}
}
consumerProguardFiles '../proguard-rules.pro'
}
externalNativeBuild {
cmake {
version "3.19.0+"
path "CMakeLists.txt"
}
}
@@ -189,7 +203,8 @@ subprojects {
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.each {
it.onlyIf {
!it.project.ext.has('isSample') || !project.hasProperty('filament_skip_samples')
!it.project.ext.has('isSample') ||
!project.hasProperty('com.google.android.filament.skip-samples')
}
}
}
+14
View File
@@ -1,3 +1,17 @@
plugins {
id 'groovy-gradle-plugin'
}
gradlePlugin {
plugins {
create("filament-tools-plugin") {
id = "filament-tools-plugin"
implementationClass = "FilamentToolsPlugin"
}
}
}
repositories {
mavenCentral()
}
@@ -1,56 +1,72 @@
// This plugin accepts the following parameters:
//
// filament_tools_dir
// com.google.android.filament.tools-dir
// Path to the Filament distribution/install directory for desktop.
// This directory must contain bin/matc.
//
// filament_exclude_vulkan
// com.google.android.filament.exclude-vulkan
// When set, support for Vulkan will be excluded.
//
// Example:
// ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
// ./gradlew -Pcom.google.android.filament.tools-dir=../../dist-release assembleDebug
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.FileType
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.logging.LogLevel
import org.gradle.api.logging.Logger
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.InputFileDetails
import org.gradle.api.model.ObjectFactory
import org.gradle.internal.os.OperatingSystem
import org.gradle.process.ExecOperations
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import java.nio.file.Paths
class TaskWithBinary extends DefaultTask {
import javax.inject.Inject
abstract class TaskWithBinary extends DefaultTask {
private final String binaryName
private File binaryPath = null
private Property<String> binaryPath = null
TaskWithBinary(String name) {
binaryName = name
}
String getBinaryName() {
return binaryName
}
@Inject abstract ObjectFactory getObjects()
@Inject abstract ProviderFactory getProviders()
File getBinary() {
@Input
Property<String> getBinary() {
if (binaryPath == null) {
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
def fullPath = tool.collect { path ->
Paths.get(project.ext.filamentToolsPath.absolutePath, path).toFile()
def filamentToolsPath = providers
.gradleProperty("com.google.android.filament.tools-dir")
.forUseAtConfigurationTime().get()
def directory = objects.fileProperty()
.fileValue(new File(filamentToolsPath)).getAsFile().get()
Paths.get(directory.absolutePath, path).toFile()
}
binaryPath = OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]
binaryPath = objects.property(String.class)
binaryPath.set(
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
}
return binaryPath
}
@@ -65,14 +81,6 @@ class LogOutputStream extends ByteArrayOutputStream {
this.level = level
}
Logger getLogger() {
return logger
}
LogLevel getLevel() {
return level
}
@Override
void flush() {
logger.log(level, toString())
@@ -85,10 +93,15 @@ class LogOutputStream extends ByteArrayOutputStream {
abstract class MaterialCompiler extends TaskWithBinary {
@Incremental
@InputDirectory
final DirectoryProperty inputDir = project.objects.directoryProperty()
abstract DirectoryProperty getInputDir()
@OutputDirectory
final DirectoryProperty outputDir = project.objects.directoryProperty()
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
@Inject abstract ObjectFactory getObjects()
@Inject abstract ProviderFactory getProviders()
MaterialCompiler() {
super("matc")
@@ -97,7 +110,9 @@ abstract class MaterialCompiler extends TaskWithBinary {
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamat' })
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*.filamat' })
})
}
inputs.getFileChanges(inputDir).each { InputFileDetails change ->
@@ -115,21 +130,24 @@ abstract class MaterialCompiler extends TaskWithBinary {
out.write(header)
out.flush()
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
def matcArgs = []
if (!project.hasProperty("filament_exclude_vulkan")) {
def exclude_vulkan = providers
.gradleProperty("com.google.android.filament.exclude-vulkan")
.forUseAtConfigurationTime().present
if (!exclude_vulkan) {
matcArgs += ['-a', 'vulkan']
}
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
project.exec {
exec.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
executable "${binary.get()}"
args matcArgs
}
}
@@ -143,15 +161,21 @@ abstract class MaterialCompiler extends TaskWithBinary {
// Custom task to process IBLs using cmgen
// This task handles incremental builds
class IblGenerator extends TaskWithBinary {
String cmgenArgs = null
abstract class IblGenerator extends TaskWithBinary {
@Input
@Optional
abstract Property<String> getCmgenArgs()
@Incremental
@InputFile
final RegularFileProperty inputFile = project.objects.fileProperty()
abstract RegularFileProperty getInputFile()
@OutputDirectory
final DirectoryProperty outputDir = project.objects.directoryProperty()
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
@Inject abstract ObjectFactory getObjects()
IblGenerator() {
super("cmgen")
@@ -160,7 +184,9 @@ class IblGenerator extends TaskWithBinary {
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*' })
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*' })
})
}
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
@@ -178,23 +204,25 @@ class IblGenerator extends TaskWithBinary {
out.write(header)
out.flush()
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
def outputPath = outputDir.get().asFile
project.exec {
def commandArgs = cmgenArgs.getOrNull()
if (commandArgs == null) {
commandArgs =
'-q -x ' + outputPath + ' --format=rgb32f ' +
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
}
commandArgs = commandArgs + " " + file
exec.exec {
standardOutput out
if (!cmgenArgs) {
cmgenArgs =
'-q -x ' + outputPath + ' --format=rgb32f ' +
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
}
cmgenArgs = cmgenArgs + " " + file
errorOutput err
executable "${getBinary()}"
args(cmgenArgs.split())
executable "${binary.get()}"
args(commandArgs.split())
}
}
}
@@ -207,13 +235,16 @@ class IblGenerator extends TaskWithBinary {
// Custom task to compile mesh files using filamesh
// This task handles incremental builds
class MeshCompiler extends TaskWithBinary {
abstract class MeshCompiler extends TaskWithBinary {
@Incremental
@InputFile
final RegularFileProperty inputFile = project.objects.fileProperty()
abstract RegularFileProperty getInputFile()
@OutputDirectory
final DirectoryProperty outputDir = project.objects.directoryProperty()
abstract DirectoryProperty getOutputDir()
@Inject abstract FileSystemOperations getFs()
@Inject abstract ExecOperations getExec()
MeshCompiler() {
super("filamesh")
@@ -222,7 +253,9 @@ class MeshCompiler extends TaskWithBinary {
@TaskAction
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamesh' })
fs.delete({
delete(objects.fileTree().from(outputDir).matching { include '*.filamesh' })
})
}
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
@@ -240,15 +273,15 @@ class MeshCompiler extends TaskWithBinary {
out.write(header)
out.flush()
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
if (!new File(binary.get()).exists()) {
throw new GradleException("Could not find ${binary.get()}." +
" Ensure Filament has been built/installed before building this app.")
}
project.exec {
exec.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
executable "${binary.get()}"
args(file, getOutputFile(file))
}
}
@@ -282,17 +315,12 @@ class FilamentToolsPlugin implements Plugin<Project> {
extension.meshInputFile = project.objects.fileProperty()
extension.meshOutputDir = project.objects.directoryProperty()
project.ext.filamentToolsPath = project.file("../../../out/release/filament")
if (project.hasProperty("filament_tools_dir")) {
project.ext.filamentToolsPath = project.file(project.property("filament_tools_dir"))
}
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
enabled =
extension.materialInputDir.isPresent() &&
extension.materialOutputDir.isPresent()
inputDir = extension.materialInputDir.getOrNull()
outputDir = extension.materialOutputDir.getOrNull()
inputDir.set(extension.materialInputDir.getOrNull())
outputDir.set(extension.materialOutputDir.getOrNull())
}
project.preBuild.dependsOn "filamentCompileMaterials"
+59 -58
View File
@@ -16,8 +16,10 @@
#include "CallbackUtils.h"
#include "private/backend/VirtualMachineEnv.h"
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils) {
#ifdef ANDROID
#ifdef __ANDROID__
callbackUtils.handlerClass = env->FindClass("android/os/Handler");
callbackUtils.handlerClass = (jclass) env->NewGlobalRef(callbackUtils.handlerClass);
callbackUtils.post = env->GetMethodID(callbackUtils.handlerClass,
@@ -32,7 +34,7 @@ void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils) {
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback) {
if (handler && callback) {
#ifdef ANDROID
#ifdef __ANDROID__
if (env->IsInstanceOf(handler, callbackUtils.handlerClass)) {
env->CallBooleanMethod(handler, callbackUtils.post, callback);
}
@@ -43,59 +45,12 @@ void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler,
}
env->DeleteGlobalRef(handler);
env->DeleteGlobalRef(callback);
#ifdef ANDROID
#ifdef __ANDROID__
env->DeleteGlobalRef(callbackUtils.handlerClass);
#endif
env->DeleteGlobalRef(callbackUtils.executorClass);
}
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
return new JniBufferCallback(env, handler, callback, std::move(buffer));
}
JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callback,
AutoBuffer&& buffer)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mBuffer(std::move(buffer)) {
acquireCallbackJni(env, mCallbackUtils);
}
JniBufferCallback::~JniBufferCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
void JniBufferCallback::invoke(void*, size_t, void* user) {
JniBufferCallback* data = reinterpret_cast<JniBufferCallback*>(user);
delete data;
}
// -----------------------------------------------------------------------------------------------
JniImageCallback* JniImageCallback::make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, long image) {
return new JniImageCallback(env, handler, callback, image);
}
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mImage(image) {
acquireCallbackJni(env, mCallbackUtils);
}
JniImageCallback::~JniImageCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
void JniImageCallback::invoke(void*, void* user) {
JniImageCallback* data = reinterpret_cast<JniImageCallback*>(user);
delete data;
}
// -----------------------------------------------------------------------------------------------
JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
@@ -103,17 +58,63 @@ JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
}
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback)) {
: mHandler(env->NewGlobalRef(handler)),
mCallback(env->NewGlobalRef(callback)) {
acquireCallbackJni(env, mCallbackUtils);
}
JniCallback::~JniCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
JniCallback::~JniCallback() = default;
void JniCallback::post(void* user, filament::backend::CallbackHandler::Callback callback) {
callback(user);
}
void JniCallback::invoke(void* user) {
JniCallback* data = reinterpret_cast<JniCallback*>(user);
delete data;
void JniCallback::postToJavaAndDestroy(JniCallback* callback) {
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
delete callback;
}
// -----------------------------------------------------------------------------------------------
JniBufferCallback* JniBufferCallback::make(filament::Engine*,
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
return new JniBufferCallback(env, handler, callback, std::move(buffer));
}
JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callback,
AutoBuffer&& buffer)
: JniCallback(env, handler, callback),
mBuffer(std::move(buffer)) {
}
JniBufferCallback::~JniBufferCallback() = default;
void JniBufferCallback::postToJavaAndDestroy(void*, size_t, void* user) {
JniBufferCallback* callback = (JniBufferCallback*)user;
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
callback->mBuffer.attachToJniThread(env);
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
delete callback;
}
// -----------------------------------------------------------------------------------------------
JniImageCallback* JniImageCallback::make(filament::Engine*,
JNIEnv* env, jobject handler, jobject callback, long image) {
return new JniImageCallback(env, handler, callback, image);
}
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
: JniCallback(env, handler, callback),
mImage(image) {
}
JniImageCallback::~JniImageCallback() = default;
void JniImageCallback::postToJavaAndDestroy(void*, void* user) {
JniImageCallback* callback = (JniImageCallback*)user;
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
delete callback;
}
+43 -39
View File
@@ -18,13 +18,14 @@
#include <jni.h>
#include "common/CallbackUtils.h"
#include "common/NioUtils.h"
#include <backend/CallbackHandler.h>
#include <filament/Engine.h>
struct CallbackJni {
#ifdef ANDROID
#ifdef __ANDROID__
jclass handlerClass = nullptr;
jmethodID post = nullptr;
#endif
@@ -35,57 +36,60 @@ struct CallbackJni {
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils);
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback);
struct JniBufferCallback {
struct JniCallback : private filament::backend::CallbackHandler {
JniCallback(JniCallback const &) = delete;
JniCallback(JniCallback&&) = delete;
JniCallback& operator=(JniCallback const &) = delete;
JniCallback& operator=(JniCallback&&) = delete;
// create a JniCallback
static JniCallback* make(JNIEnv* env, jobject handler, jobject runnable);
// execute the callback on the java thread and destroy ourselves
static void postToJavaAndDestroy(JniCallback* callback);
// CallbackHandler interface.
void post(void* user, Callback callback) override;
// Get the CallbackHandler interface
filament::backend::CallbackHandler* getHandler() noexcept { return this; }
jobject getCallbackObject() { return mCallback; }
protected:
JniCallback(JNIEnv* env, jobject handler, jobject runnable);
explicit JniCallback() = default; // this version does nothing
virtual ~JniCallback();
jobject mHandler{};
jobject mCallback{};
CallbackJni mCallbackUtils{};
};
struct JniBufferCallback : public JniCallback {
// create a JniBufferCallback
static JniBufferCallback* make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
static void invoke(void* buffer, size_t n, void* user);
// execute the callback on the java thread and destroy ourselves
static void postToJavaAndDestroy(void*, size_t, void* user);
private:
JniBufferCallback(JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
JniBufferCallback(JniBufferCallback const &) = delete;
JniBufferCallback(JniBufferCallback&&) = delete;
~JniBufferCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
virtual ~JniBufferCallback();
AutoBuffer mBuffer;
CallbackJni mCallbackUtils;
};
struct JniImageCallback {
struct JniImageCallback : public JniCallback {
// create a JniImageCallback
static JniImageCallback* make(filament::Engine* engine, JNIEnv* env, jobject handler,
jobject runnable, long image);
static void invoke(void* image, void* user);
// execute the callback on the java thread and destroy ourselves
static void postToJavaAndDestroy(void*, void* user);
private:
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
JniImageCallback(JniImageCallback const &) = delete;
JniImageCallback(JniImageCallback&&) = delete;
~JniImageCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
virtual ~JniImageCallback();
long mImage;
CallbackJni mCallbackUtils;
};
struct JniCallback {
static JniCallback* make(JNIEnv* env, jobject handler, jobject runnable);
static void invoke(void* user);
private:
JniCallback(JNIEnv* env, jobject handler, jobject runnable);
JniCallback(JniCallback const &) = delete;
JniCallback(JniCallback&&) = delete;
~JniCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
CallbackJni mCallbackUtils;
};
+4
View File
@@ -38,6 +38,10 @@ public:
AutoBuffer(AutoBuffer&& rhs) noexcept;
~AutoBuffer() noexcept;
void attachToJniThread(JNIEnv* env) noexcept {
mEnv = env;
}
void* getData() const noexcept {
return mUserData;
}
+2 -1
View File
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.19)
project(filamat-android)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
@@ -123,19 +123,22 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpo
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint precision, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
builder->parameter((MaterialBuilder::UniformType) uniformType,
(MaterialBuilder::ParameterPrecision) precision, name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jint precision,
jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size,
(MaterialBuilder::ParameterPrecision) precision, name);
env->ReleaseStringUTFChars(name_, name);
}
@@ -146,7 +149,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision,
name);
env->ReleaseStringUTFChars(name_, name);
}
@@ -255,6 +258,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShadowM
builder->shadowMultiplier(shadowMultiplier);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTransparentShadow(
JNIEnv*, jclass, jlong nativeBuilder, jboolean transparentShadow) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->transparentShadow(transparentShadow);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecularAntiAliasing(
JNIEnv*, jclass, jlong nativeBuilder, jboolean specularAntiAliasing) {
@@ -291,6 +301,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(
builder->flipUV(flipUV);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCustomSurfaceShading(JNIEnv*,
jclass, jlong nativeBuilder, jboolean customSurfaceShading) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->customSurfaceShading(customSurfaceShading);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBounceAmbientOcclusion(
JNIEnv*, jclass, jlong nativeBuilder, jboolean multiBounceAO) {
@@ -91,7 +91,7 @@ public class MaterialBuilder {
SHADOW
}
public enum SamplerPrecision {
public enum ParameterPrecision {
LOW,
MEDIUM,
HIGH,
@@ -114,14 +114,14 @@ public class MaterialBuilder {
BONE_INDICES, // indices of 4 bones (uvec4)
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
UNUSED, // reserved for future use
CUSTOM0, // custom or MORPH_POSITION_0
CUSTOM1, // custom or MORPH_POSITION_1
CUSTOM2, // custom or MORPH_POSITION_2
CUSTOM3, // custom or MORPH_POSITION_3
CUSTOM4, // custom or MORPH_TANGENTS_0
CUSTOM5, // custom or MORPH_TANGENTS_1
CUSTOM6, // custom or MORPH_TANGENTS_2
CUSTOM7 // custom or MORPH_TANGENTS_3
CUSTOM0, // custom
CUSTOM1, // custom
CUSTOM2, // custom
CUSTOM3, // custom
CUSTOM4, // custom
CUSTOM5, // custom
CUSTOM6, // custom
CUSTOM7 // custom
}
public enum BlendingMode {
@@ -247,19 +247,36 @@ public class MaterialBuilder {
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(),
ParameterPrecision.DEFAULT.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type,
ParameterPrecision precision, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), precision.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
ParameterPrecision.DEFAULT.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size,
ParameterPrecision precision, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
precision.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
SamplerPrecision precision, String name) {
ParameterPrecision precision, String name) {
nMaterialBuilderSamplerParameter(
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
return this;
@@ -349,6 +366,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder transparentShadow(boolean transparentShadow) {
nMaterialBuilderTransparentShadow(mNativeObject, transparentShadow);
return this;
}
@NonNull
public MaterialBuilder specularAntiAliasing(boolean specularAntiAliasing) {
nMaterialBuilderSpecularAntiAliasing(mNativeObject, specularAntiAliasing);
@@ -391,6 +414,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder customSurfaceShading(boolean customSurfaceShading) {
nMaterialBuilderCustomSurfaceShading(mNativeObject, customSurfaceShading);
return this;
}
@NonNull
public MaterialBuilder multiBounceAmbientOcclusion(boolean multiBounceAO) {
nMaterialBuilderMultiBounceAmbientOcclusion(mNativeObject, multiBounceAO);
@@ -523,9 +552,9 @@ public class MaterialBuilder {
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
String name);
int precision, String name);
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
int size, String name);
int size, int precision, String name);
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
int format, int precision, String name);
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,
@@ -545,6 +574,8 @@ public class MaterialBuilder {
private static native void nMaterialBuilderShadowMultiplier(long mNativeObject,
boolean shadowMultiplier);
private static native void nMaterialBuilderTransparentShadow(long mNativeObject,
boolean transparentShadow);
private static native void nMaterialBuilderSpecularAntiAliasing(long mNativeObject,
boolean specularAntiAliasing);
private static native void nMaterialBuilderSpecularAntiAliasingVariance(long mNativeObject,
@@ -556,6 +587,8 @@ public class MaterialBuilder {
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
private static native void nMaterialBuilderCustomSurfaceShading(long nativeBuilder,
boolean customSurfaceShading);
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
boolean multiBounceAO);
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,
+21 -2
View File
@@ -1,7 +1,9 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.19)
project(filament-android)
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
@@ -25,6 +27,10 @@ add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
add_library(filamat STATIC IMPORTED)
set_target_properties(filamat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilamat.a)
add_library(geometry STATIC IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
@@ -37,6 +43,10 @@ add_library(bluevk STATIC IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(vkshaders STATIC IMPORTED)
set_target_properties(vkshaders PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libvkshaders.a)
add_library(smol-v STATIC IMPORTED)
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
@@ -51,6 +61,7 @@ set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
add_library(filament-jni SHARED
src/main/cpp/BufferObject.cpp
src/main/cpp/Camera.cpp
src/main/cpp/Colors.cpp
src/main/cpp/ColorGrading.cpp
@@ -68,11 +79,13 @@ add_library(filament-jni SHARED
src/main/cpp/RenderTarget.cpp
src/main/cpp/Scene.cpp
src/main/cpp/SkyBox.cpp
src/main/cpp/SkinningBuffer.cpp
src/main/cpp/Stream.cpp
src/main/cpp/SurfaceOrientation.cpp
src/main/cpp/SwapChain.cpp
src/main/cpp/Texture.cpp
src/main/cpp/TextureSampler.cpp
src/main/cpp/ToneMapper.cpp
src/main/cpp/TransformManager.cpp
src/main/cpp/VertexBuffer.cpp
src/main/cpp/View.cpp
@@ -91,7 +104,6 @@ target_link_libraries(filament-jni
PRIVATE backend
PRIVATE filaflat
PRIVATE filabridge
PRIVATE geometry
PRIVATE ibl-lite
PRIVATE log
PRIVATE GLESv3
@@ -99,14 +111,21 @@ target_link_libraries(filament-jni
PRIVATE android
PRIVATE jnigraphics
PRIVATE utils
# libgeometry is PUBLIC because gltfio uses it.
PUBLIC geometry
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
)
target_include_directories(filament-jni PRIVATE
..
${FILAMENT_DIR}/include
../../filament/backend/include
../../third_party/robin-map
../../libs/utils/include)
@@ -2,17 +2,25 @@ LIBFILAMENT {
global:
Java_com_google_android_filament_*;
JNI*;
*filament*BufferObject*;
*filament*Camera*;
*filament*Color*;
*filament*Exposure*;
*filament*Skybox*;
*filament*Engine*;
*filament*RenderableManager*;
*filament*Aabb*;
*filament*IndirectLight*;
*filament*LightManager*;
*filament*Renderer*;
*filament*RenderTarget*;
*filament*Scene*;
*filament*ToneMapper*;
*filament*Transform*;
*filament*Material*;
*filament*IndexBuffer*;
*filament*VertexBuffer*;
*filament*View*;
*filament*Texture*;
*filament*geometry*;
@@ -0,0 +1,100 @@
/*
* 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/BufferObject.h>
#include <backend/BufferDescriptor.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_BufferObject_nCreateBuilder(JNIEnv *env, jclass type) {
return (jlong) new BufferObject::Builder();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_BufferObject_nDestroyBuilder(JNIEnv *env, jclass type,
jlong nativeBuilder) {
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
delete builder;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_BufferObject_nBuilderSize(JNIEnv *env, jclass type,
jlong nativeBuilder, jint byteCount) {
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
builder->size((uint32_t) byteCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_BufferObject_nBuilderBindingType(JNIEnv *env, jclass type,
jlong nativeBuilder, jint bindingType) {
using BindingType = BufferObject::BindingType;
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
BindingType types[] = {BindingType::VERTEX};
builder->bindingType(types[bindingType]);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_BufferObject_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeBuilder, jlong nativeEngine) {
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return (jlong) builder->build(*engine);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_BufferObject_nGetByteCount(JNIEnv *env, jclass type,
jlong nativeBufferObject) {
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
return (jint) bufferObject->getByteCount();
}
extern "C" JNIEXPORT int JNICALL
Java_com_google_android_filament_BufferObject_nSetBuffer(JNIEnv *env, jclass type,
jlong nativeBufferObject, jlong nativeEngine, jobject buffer, int remaining,
jint destOffsetInBytes, jint count,
jobject handler, jobject runnable) {
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
Engine *engine = (Engine *) nativeEngine;
AutoBuffer nioBuffer(env, buffer, count);
void* data = nioBuffer.getData();
size_t sizeInBytes = nioBuffer.getSize();
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
BufferDescriptor desc(data, sizeInBytes,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
bufferObject->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
return 0;
}
@@ -18,6 +18,8 @@
#include <filament/Camera.h>
#include <utils/Entity.h>
#include <math/mat4.h>
using namespace filament;
@@ -47,20 +49,31 @@ Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetCustomProjection(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray inMatrix_, jdouble near, jdouble far) {
jlong nativeCamera, jdoubleArray inProjection_, jdoubleArray inProjectionForCulling_,
jdouble near, jdouble far) {
Camera *camera = (Camera *) nativeCamera;
jdouble *inMatrix = env->GetDoubleArrayElements(inMatrix_, NULL);
camera->setCustomProjection(*reinterpret_cast<const filament::math::mat4 *>(inMatrix), near, far);
env->ReleaseDoubleArrayElements(inMatrix_, inMatrix, JNI_ABORT);
jdouble *inProjection = env->GetDoubleArrayElements(inProjection_, NULL);
jdouble *inProjectionForCulling = env->GetDoubleArrayElements(inProjectionForCulling_, NULL);
camera->setCustomProjection(
*reinterpret_cast<const filament::math::mat4 *>(inProjection),
*reinterpret_cast<const filament::math::mat4 *>(inProjectionForCulling),
near, far);
env->ReleaseDoubleArrayElements(inProjection_, inProjection, JNI_ABORT);
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
jlong nativeCamera, jdoubleArray inScaling_) {
jlong nativeCamera, jdouble x, jdouble y) {
Camera *camera = (Camera *) nativeCamera;
jdouble *inScaling = env->GetDoubleArrayElements(inScaling_, NULL);
camera->setScaling(*reinterpret_cast<const filament::math::double4*>(inScaling));
env->ReleaseDoubleArrayElements(inScaling_, inScaling, JNI_ABORT);
camera->setScaling({(double)x, (double)y});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetShift(JNIEnv* env, jclass,
jlong nativeCamera, jdouble x, jdouble y) {
Camera *camera = (Camera *) nativeCamera;
camera->setShift({(double)x, (double)y});
}
extern "C" JNIEXPORT void JNICALL
@@ -89,10 +102,19 @@ Java_com_google_android_filament_Camera_nSetModelMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jfloatArray in_) {
Camera* camera = (Camera *) nativeCamera;
jfloat *in = env->GetFloatArrayElements(in_, NULL);
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4f*>(in));
camera->setModelMatrix((math::mat4)*reinterpret_cast<const filament::math::mat4f*>(in));
env->ReleaseFloatArrayElements(in_, in, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetModelMatrixFp64(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray in_) {
Camera* camera = (Camera *) nativeCamera;
jdouble *in = env->GetDoubleArrayElements(in_, NULL);
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4*>(in));
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray out_) {
@@ -128,21 +150,41 @@ Java_com_google_android_filament_Camera_nGetModelMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jfloatArray out_) {
Camera *camera = (Camera *) nativeCamera;
jfloat *out = env->GetFloatArrayElements(out_, NULL);
const filament::math::mat4f& m = camera->getModelMatrix();
const filament::math::mat4f& m = (math::mat4f)camera->getModelMatrix();
std::copy_n(&m[0][0], 16, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetModelMatrixFp64(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray out_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
const filament::math::mat4& m = camera->getModelMatrix();
std::copy_n(&m[0][0], 16, out);
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetViewMatrix(JNIEnv *env, jclass, jlong nativeCamera,
jfloatArray out_) {
Camera *camera = (Camera *) nativeCamera;
jfloat *out = env->GetFloatArrayElements(out_, NULL);
const filament::math::mat4f& m = camera->getViewMatrix();
const filament::math::mat4f& m = (math::mat4f)camera->getViewMatrix();
std::copy_n(&m[0][0], 16, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetViewMatrixFp64(JNIEnv *env, jclass, jlong nativeCamera,
jdoubleArray out_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
const filament::math::mat4& m = camera->getViewMatrix();
std::copy_n(&m[0][0], 16, out);
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetPosition(JNIEnv *env, jclass, jlong nativeCamera,
jfloatArray out_) {
@@ -205,3 +247,36 @@ Java_com_google_android_filament_Camera_nGetSensitivity(JNIEnv*, jclass,
Camera *camera = (Camera *) nativeCamera;
return camera->getSensitivity();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetFocusDistance(JNIEnv*, jclass,
jlong nativeCamera, jfloat focusDistance) {
Camera *camera = (Camera *) nativeCamera;
camera->setFocusDistance(focusDistance);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_Camera_nGetFocusDistance(JNIEnv*, jclass,
jlong nativeCamera) {
Camera *camera = (Camera *) nativeCamera;
return camera->getFocusDistance();
}
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nGetFocalLength(JNIEnv*, jclass,
jlong nativeCamera) {
Camera *camera = (Camera *) nativeCamera;
return camera->getFocalLength();
}
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nComputeEffectiveFocalLength(JNIEnv*, jclass,
jdouble focalLength, jdouble focusDistance) {
return Camera::computeEffectiveFocalLength(focalLength, focusDistance);
}
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nComputeEffectiveFov(JNIEnv*, jclass,
jdouble fovInDegrees, jdouble focusDistance) {
return Camera::computeEffectiveFov(fovInDegrees, focusDistance);
}
@@ -17,6 +17,7 @@
#include <jni.h>
#include <filament/ColorGrading.h>
#include <filament/ToneMapper.h>
#include <math/vec3.h>
#include <math/vec4.h>
@@ -30,28 +31,35 @@ Java_com_google_android_filament_ColorGrading_nCreateBuilder(JNIEnv*, jclass) {
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass,
jlong nativeBuilder) {
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass, jlong nativeBuilder) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
delete builder;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine) {
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jlong nativeEngine) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return (jlong) builder->build(*engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass,
jlong nativeBuilder, jint quality_) {
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, jlong nativeBuilder, jint quality_) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
ColorGrading::QualityLevel quality = (ColorGrading::QualityLevel) quality_;
builder->quality(quality);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderToneMapper(JNIEnv*, jclass,
jlong nativeBuilder, jlong toneMapper_) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
const ToneMapper* toneMapper = (const ToneMapper*) toneMapper_;
builder->toneMapper(toneMapper);
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclass,
jlong nativeBuilder, jint toneMapping_) {
@@ -59,6 +67,35 @@ Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclas
ColorGrading::ToneMapping toneMapping = (ColorGrading::ToneMapping) toneMapping_;
builder->toneMapping(toneMapping);
}
#pragma clang diagnostic pop
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*, jclass,
jlong nativeBuilder, jboolean luminanceScaling) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->luminanceScaling(luminanceScaling);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderGamutMapping(JNIEnv*, jclass,
jlong nativeBuilder, jboolean gamutMapping) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->gamutMapping(gamutMapping);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderExposure(JNIEnv*, jclass,
jlong nativeBuilder, jfloat exposure) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->exposure(exposure);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderNightAdaptation(JNIEnv*, jclass,
jlong nativeBuilder, jfloat adaptation) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->nightAdaptation(adaptation);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderWhiteBalance(JNIEnv*, jclass,
@@ -16,6 +16,7 @@
#include <jni.h>
#include <filament/Camera.h>
#include <filament/Engine.h>
#include <utils/Entity.h>
@@ -44,12 +45,11 @@ extern "C" {
// handle. Whatever object is returned from this method must match what is in
// folder filament/src/driver/opengl/Context* in particular pay attention to
// the object type in makeCurrent method.
extern void *getNativeWindow(JNIEnv *env, jclass, jobject surface);
extern void* getNativeWindow(JNIEnv* env, jclass, jobject surface);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetBackend(JNIEnv* env,
jclass klass, jlong nativeEngine) {
Java_com_google_android_filament_Engine_nGetBackend(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) engine->getBackend();
}
@@ -63,8 +63,8 @@ Java_com_google_android_filament_Engine_nCreateSwapChain(JNIEnv* env,
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv* env,
jclass klass, jlong nativeEngine, jint width, jint height, jlong flags) {
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv*,
jclass, jlong nativeEngine, jint width, jint height, jlong flags) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) engine->createSwapChain(width, height, (uint64_t) flags);
}
@@ -80,7 +80,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroySwapChain(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSwapChain) {
Engine* engine = (Engine*) nativeEngine;
SwapChain *swapChain = (SwapChain *) nativeSwapChain;
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
return engine->destroy(swapChain);
}
@@ -97,7 +97,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyView(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeView) {
Engine* engine = (Engine*) nativeEngine;
View *view = (View *) nativeView;
View* view = (View*) nativeView;
return engine->destroy(view);
}
@@ -114,21 +114,14 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeRenderer) {
Engine* engine = (Engine*) nativeEngine;
Renderer *renderer = (Renderer *) nativeRenderer;
Renderer* renderer = (Renderer*) nativeRenderer;
return engine->destroy(renderer);
}
// Camera
extern "C" [[deprecated]] JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) engine->createCamera();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateCameraWithEntity(JNIEnv*, jclass,
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
jlong nativeEngine, jint entity_) {
Engine* engine = (Engine*) nativeEngine;
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
@@ -143,12 +136,12 @@ Java_com_google_android_filament_Engine_nGetCameraComponent(JNIEnv*, jclass,
return (jlong) engine->getCameraComponent(entity);
}
extern "C" [[deprecated]] JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nDestroyCamera(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeCamera) {
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nDestroyCameraComponent(JNIEnv*, jclass,
jlong nativeEngine, jint entity_) {
Engine* engine = (Engine*) nativeEngine;
Camera *camera = (Camera *) nativeCamera;
engine->destroy(camera);
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
engine->destroyCameraComponent(entity);
}
// Scene
@@ -164,7 +157,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeScene) {
Engine* engine = (Engine*) nativeEngine;
Scene *scene = (Scene *) nativeScene;
Scene* scene = (Scene*) nativeScene;
return engine->destroy(scene);
}
@@ -181,7 +174,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyFence(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeFence) {
Engine* engine = (Engine*) nativeEngine;
Fence *fence = (Fence *) nativeFence;
Fence* fence = (Fence*) nativeFence;
return engine->destroy(fence);
}
@@ -191,7 +184,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyStream(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeStream) {
Engine* engine = (Engine*) nativeEngine;
Stream *stream = (Stream *) nativeStream;
Stream* stream = (Stream*) nativeStream;
return engine->destroy(stream);
}
@@ -201,7 +194,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndexBuffer) {
Engine* engine = (Engine*) nativeEngine;
IndexBuffer *indexBuffer = (IndexBuffer *) nativeIndexBuffer;
IndexBuffer* indexBuffer = (IndexBuffer*) nativeIndexBuffer;
return engine->destroy(indexBuffer);
}
@@ -209,15 +202,23 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyVertexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeVertexBuffer) {
Engine* engine = (Engine*) nativeEngine;
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
VertexBuffer* vertexBuffer = (VertexBuffer*) nativeVertexBuffer;
return engine->destroy(vertexBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroySkinningBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkinningBuffer) {
Engine* engine = (Engine*) nativeEngine;
SkinningBuffer* skinningBuffer = (SkinningBuffer*) nativeSkinningBuffer;
return engine->destroy(skinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {
Engine* engine = (Engine*) nativeEngine;
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
IndirectLight* indirectLight = (IndirectLight*) nativeIndirectLight;
return engine->destroy(indirectLight);
}
@@ -225,7 +226,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyMaterial(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterial) {
Engine* engine = (Engine*) nativeEngine;
Material *material = (Material *) nativeMaterial;
Material* material = (Material*) nativeMaterial;
return engine->destroy(material);
}
@@ -241,7 +242,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroySkybox(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkybox) {
Engine* engine = (Engine*) nativeEngine;
Skybox *skybox = (Skybox *) nativeSkybox;
Skybox* skybox = (Skybox*) nativeSkybox;
return engine->destroy(skybox);
}
@@ -257,7 +258,7 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyTexture(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeTexture) {
Engine* engine = (Engine*) nativeEngine;
Texture *texture = (Texture *) nativeTexture;
Texture* texture = (Texture*) nativeTexture;
return engine->destroy(texture);
}
@@ -278,7 +279,7 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv *env, jclass clazz,
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
engine->flushAndWait();
@@ -287,22 +288,19 @@ Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv *env, jclass clazz,
// Managers...
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetTransformManager(JNIEnv*, jclass,
jlong nativeEngine) {
Java_com_google_android_filament_Engine_nGetTransformManager(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getTransformManager();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetLightManager(JNIEnv*, jclass,
jlong nativeEngine) {
Java_com_google_android_filament_Engine_nGetLightManager(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getLightManager();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass,
jlong nativeEngine) {
Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getRenderableManager();
}
@@ -312,3 +310,9 @@ Java_com_google_android_filament_Engine_nGetJobSystem(JNIEnv*, jclass, jlong nat
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getJobSystem();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetEntityManager(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getEntityManager();
}
@@ -16,9 +16,7 @@
#include <jni.h>
namespace filament {
extern jint JNI_OnLoad(JavaVM* vm, void* reserved);
};
#include "private/backend/VirtualMachineEnv.h"
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
@@ -26,9 +24,9 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return -1;
}
#if ANDROID
::filament::JNI_OnLoad(vm, reserved);
#endif
// This must be called when the library is loaded. We need this to get a reference to the
// global VM
::filament::VirtualMachineEnv::JNI_OnLoad(vm);
return JNI_VERSION_1_6;
}
@@ -91,7 +91,8 @@ Java_com_google_android_filament_IndexBuffer_nSetBuffer(JNIEnv *env, jclass type
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
BufferDescriptor desc(data, sizeInBytes,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
indexBuffer->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
@@ -76,8 +76,10 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env, jclass,
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance, jint vsmMsaaSamples) {
jfloat shadowFarHint, jboolean stable,
jfloat polygonOffsetConstant, jfloat polygonOffsetSlope,
jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth, jfloat shadowBulbRadius) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
LightManager::ShadowOptions shadowOptions {
.mapSize = (uint32_t)mapSize,
@@ -88,12 +90,16 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
.shadowNearHint = shadowNearHint,
.shadowFarHint = shadowFarHint,
.stable = (bool)stable,
.polygonOffsetConstant = polygonOffsetConstant,
.polygonOffsetSlope = polygonOffsetConstant,
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
.stepCount = uint8_t(stepCount),
.maxShadowDistance = maxShadowDistance,
.vsm = {
.msaaSamples = (uint8_t) vsmMsaaSamples
}
.msaaSamples = (uint8_t) vsmMsaaSamples,
.blurWidth = blurWidth
},
.shadowBulbRadius = shadowBulbRadius
};
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));
@@ -188,6 +194,23 @@ Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclas
builder->sunHaloFalloff(haloFalloff);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderLightChannel(JNIEnv*, jclass,
jlong nativeBuilder, jint channel, jboolean enable) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->lightChannel(channel, (bool)enable);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine, jint entity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
}
// ------------------------------------------------------------------------------------------------
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nComputeUniformSplits(JNIEnv* env, jclass,
jfloatArray splitPositions, jint cascades) {
@@ -212,13 +235,7 @@ Java_com_google_android_filament_LightManager_nComputePracticalSplits(JNIEnv* en
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine, jint entity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
}
// ------------------------------------------------------------------------------------------------
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_LightManager_nGetType(JNIEnv* env,
@@ -379,3 +396,31 @@ Java_com_google_android_filament_LightManager_nIsShadowCaster(JNIEnv*, jclass,
LightManager *lm = (LightManager *) nativeLightManager;
return (jboolean)lm->isShadowCaster((LightManager::Instance) i);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetOuterConeAngle(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return (jfloat)lm->getSpotLightOuterCone((LightManager::Instance) i);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetInnerConeAngle(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return (jfloat)lm->getSpotLightInnerCone((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetLightChannel(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jint channel, jboolean enable) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setLightChannel((LightManager::Instance) i, channel, (bool)enable);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nGetLightChannel(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jint channel) {
LightManager const *lm = (LightManager const *) nativeLightManager;
return lm->getLightChannel((LightManager::Instance) i, channel);
}
@@ -364,3 +364,19 @@ Java_com_google_android_filament_MaterialInstance_nGetMaterial(JNIEnv* env, jcla
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
return (jlong) instance->getMaterial();
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_MaterialInstance_nDuplicate(JNIEnv* env, jclass clazz,
jlong otherNativeMaterialInstance, jstring name) {
MaterialInstance* other = (MaterialInstance*) otherNativeMaterialInstance;
const char *cstr = nullptr;
if (name != nullptr) {
cstr = env->GetStringUTFChars(name, nullptr);
}
MaterialInstance* mi = MaterialInstance::duplicate(other, cstr);
if (name != nullptr) {
env->ReleaseStringUTFChars(name, cstr);
}
return (jlong)mi;
}
@@ -170,6 +170,14 @@ Java_com_google_android_filament_RenderableManager_nBuilderScreenSpaceContactSha
builder->screenSpaceContactShadows(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBuffer(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeSkinningBuffer, jint boneCount, jint offset) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
builder->skinning(skinningBuffer, boneCount, offset);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jclass,
jlong nativeBuilder, jint boneCount) {
@@ -177,6 +185,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jcl
builder->skinning((size_t)boneCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nEnableSkinningBuffers(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->enableSkinningBuffers(enabled);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv* env, jclass,
jlong nativeBuilder, jint boneCount, jobject bones, jint remaining) {
@@ -199,6 +214,22 @@ Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jcl
builder->morphing(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderLightChannel(JNIEnv*, jclass,
jlong nativeBuilder, jint channel, jboolean enable) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->lightChannel(channel, (bool)enable);
}
// ------------------------------------------------------------------------------------------------
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetSkinningBuffer(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jlong nativeSkinningBuffer, jint count, jint offset) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
SkinningBuffer *sb = (SkinningBuffer *) nativeSkinningBuffer;
rm->setSkinningBuffer(i, sb, count, offset);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nSetBonesAsMatrices(JNIEnv* env, jclass,
@@ -239,9 +270,9 @@ Java_com_google_android_filament_RenderableManager_nSetMorphWeights(JNIEnv* env,
jlong nativeRenderableManager, jint instance, jfloatArray weights) {
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);
env->ReleaseFloatArrayElements(weights, vec, JNI_ABORT);
rm->setMorphWeights((RenderableManager::Instance)instance, floatvec);
}
extern "C" JNIEXPORT void JNICALL
@@ -339,21 +370,13 @@ Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv
materialInstance);
}
extern "C" JNIEXPORT long JNICALL
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_RenderableManager_nGetMaterialInstanceAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (long) rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_RenderableManager_nGetMaterialAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
MaterialInstance *mi = rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
return (long) mi->getMaterial();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIJJII(JNIEnv*,
jclass, jlong nativeRenderableManager, jint i, jint primitiveIndex, jint primitiveType,
@@ -390,3 +413,17 @@ Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEn
AttributeBitset enabled = rm->getEnabledAttributesAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
return enabled.getValue();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetLightChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint channel, jboolean enable) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setLightChannel((RenderableManager::Instance) i, channel, (bool)enable);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nGetLightChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint channel) {
RenderableManager const *rm = (RenderableManager const *) nativeRenderableManager;
return rm->getLightChannel((RenderableManager::Instance) i, channel);
}
@@ -50,6 +50,14 @@ Java_com_google_android_filament_Renderer_nRender(JNIEnv *, jclass, jlong native
renderer->render(view);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nRenderStandaloneView(JNIEnv *, jclass, jlong nativeRenderer,
jlong nativeView) {
Renderer *renderer = (Renderer *) nativeRenderer;
View *view = (View *) nativeView;
renderer->renderStandaloneView(view);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nCopyFrame(JNIEnv *, jclass, jlong nativeRenderer,
jlong nativeDstSwapChain,
@@ -89,7 +97,8 @@ Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
renderer->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
std::move(desc));
@@ -124,7 +133,8 @@ Java_com_google_android_filament_Renderer_nReadPixelsEx(JNIEnv *env, jclass,
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
renderer->readPixels(renderTarget,
uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
@@ -0,0 +1,116 @@
/*
* 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/SkinningBuffer.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_SkinningBuffer_nCreateBuilder(JNIEnv*, jclass) {
return (jlong) new SkinningBuffer::Builder();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_SkinningBuffer_nDestroyBuilder(JNIEnv*, jclass,
jlong nativeBuilder) {
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
delete builder;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_SkinningBuffer_nBuilderBoneCount(JNIEnv*, jclass,
jlong nativeBuilder, jint boneCount) {
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
builder->boneCount((uint32_t)boneCount);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_SkinningBuffer_nBuilderInitialize(JNIEnv*, jclass,
jlong nativeBuilder, jboolean initialize) {
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
builder->initialize((bool)initialize);
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_SkinningBuffer_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine) {
SkinningBuffer::Builder* builder = (SkinningBuffer::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return (jlong) builder->build(*engine);
}
// ------------------------------------------------------------------------------------------------
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_SkinningBuffer_nSetBonesAsMatrices(JNIEnv* env, jclass,
jlong nativeSkinningBuffer, jlong nativeEngine, jobject matrices, jint remaining, jint boneCount,
jint offset) {
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
Engine *engine = (Engine *) nativeEngine;
AutoBuffer nioBuffer(env, matrices, boneCount * 16);
void* data = nioBuffer.getData();
size_t sizeInBytes = nioBuffer.getSize();
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
skinningBuffer->setBones(*engine,
static_cast<filament::math::mat4f const *>(data), (size_t)boneCount, (size_t)offset);
return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_SkinningBuffer_nSetBonesAsQuaternions(JNIEnv* env, jclass,
jlong nativeSkinningBuffer, jlong nativeEngine, jobject quaternions, jint remaining,
jint boneCount, jint offset) {
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
Engine *engine = (Engine *) nativeEngine;
AutoBuffer nioBuffer(env, quaternions, boneCount * 8);
void* data = nioBuffer.getData();
size_t sizeInBytes = nioBuffer.getSize();
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
skinningBuffer->setBones(*engine,
static_cast<RenderableManager::Bone const *>(data), (size_t)boneCount, (size_t)offset);
return 0;
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_SkinningBuffer_nGetBoneCount(JNIEnv*, jclass,
jlong nativeSkinningBuffer) {
SkinningBuffer *skinningBuffer = (SkinningBuffer *) nativeSkinningBuffer;
return (jint)skinningBuffer->getBoneCount();
}
@@ -100,7 +100,7 @@ Java_com_google_android_filament_Skybox_nSetColor(JNIEnv *, jclass,
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybix_nGetTexture(JNIEnv* env, jclass,
Java_com_google_android_filament_Skybox_nGetTexture(JNIEnv* env, jclass,
jlong nativeSkybox) {
Skybox *skybox = (Skybox *) nativeSkybox;
Texture const *tex = skybox->getTexture();
@@ -24,7 +24,7 @@
#include "common/NioUtils.h"
#include "common/CallbackUtils.h"
#ifdef ANDROID
#ifdef __ANDROID__
#if __has_include(<android/hardware_buffer_jni.h>)
#include <android/hardware_buffer_jni.h>
@@ -102,7 +102,10 @@ 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
@@ -166,7 +169,8 @@ Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(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));
@@ -186,7 +190,7 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
Engine* engine = (Engine*) nativeEngine;
Stream* stream = (Stream*) nativeStream;
#ifdef ANDROID
#ifdef __ANDROID__
// This function is not available before NDK 15 or before Android 8.
if (UTILS_UNLIKELY(!AHardwareBuffer_fromHardwareBuffer_fn)) {
@@ -218,5 +222,6 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
#endif
stream->setAcquiredImage((void*) nativeBuffer, &JniImageCallback::invoke, callback);
stream->setAcquiredImage((void*) nativeBuffer,
callback->getHandler(), &JniImageCallback::postToJavaAndDestroy, callback);
}
@@ -27,5 +27,8 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto *callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameCompletedCallback(&JniCallback::invoke, callback);
swapChain->setFrameCompletedCallback([](void* user) {
JniCallback* callback = (JniCallback*)user;
JniCallback::postToJavaAndDestroy(callback);
}, callback);
}
@@ -19,7 +19,7 @@
#include <algorithm>
#include <functional>
#ifdef ANDROID
#ifdef __ANDROID__
#include <android/bitmap.h>
#endif
@@ -31,15 +31,18 @@
#include "common/CallbackUtils.h"
#include "common/NioUtils.h"
#include "private/backend/VirtualMachineEnv.h"
using namespace filament;
using namespace backend;
static size_t getTextureDataSize(const Texture *texture, size_t level,
Texture::Format format, Texture::Type type, size_t stride, size_t alignment) {
static size_t getTextureDataSize(const Texture *texture,
size_t level, Texture::Format format, Texture::Type type,
size_t stride, size_t height, size_t alignment) {
// Zero stride implies tight row-to-row packing.
stride = stride == 0 ? texture->getWidth(level) : std::max(size_t(1), stride >> level);
return Texture::computeTextureDataSize(format, type,
stride, texture->getHeight(level), alignment);
stride = stride == 0 ? texture->getWidth(level) : std::max(size_t(1), stride >> level);
height = height == 0 ? texture->getHeight(level) : std::max(size_t(1), height >> level);
return Texture::computeTextureDataSize(format, type, stride, height, alignment);
}
extern "C" JNIEXPORT jboolean JNICALL
@@ -50,6 +53,13 @@ Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv*, jcla
(Texture::InternalFormat) internalFormat);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nIsTextureSwizzleSupported(JNIEnv*, jclass,
jlong nativeEngine) {
Engine *engine = (Engine *) nativeEngine;
return (jboolean) Texture::isTextureSwizzleSupported(*engine);
}
// Texture::Builder...
extern "C" JNIEXPORT jlong JNICALL
@@ -121,6 +131,13 @@ Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
builder->import((intptr_t)id);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine) {
@@ -175,14 +192,14 @@ extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong nativeTexture,
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment,
jint left, jint top, jint type, jint alignment,
jint stride, jint format,
jobject handler, jobject runnable) {
Texture* texture = (Texture*) nativeTexture;
Engine* engine = (Engine*) nativeEngine;
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
(Texture::Type) type, (size_t) stride, (size_t) alignment);
(Texture::Type) type, (size_t) stride, (size_t) height, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
@@ -194,8 +211,9 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong na
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
(uint32_t) width, (uint32_t) height, std::move(desc));
@@ -225,7 +243,7 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
&JniBufferCallback::invoke, callback);
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
(uint32_t) width, (uint32_t) height, std::move(desc));
@@ -239,14 +257,14 @@ Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong
jint xoffset, jint yoffset, jint zoffset,
jint width, jint height, jint depth,
jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment,
jint left, jint top, jint type, jint alignment,
jint stride, jint format,
jobject handler, jobject runnable) {
Texture* texture = (Texture*) nativeTexture;
Engine* engine = (Engine*) nativeEngine;
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
(Texture::Type) type, (size_t) stride, (size_t) alignment);
(Texture::Type) type, (size_t) stride, (size_t) height, (size_t) alignment) * depth;
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
@@ -258,8 +276,9 @@ Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
@@ -293,7 +312,7 @@ Java_com_google_android_filament_Texture_nSetImage3DCompressed(JNIEnv *env, jcla
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
&JniBufferCallback::invoke, callback);
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
@@ -306,7 +325,7 @@ Java_com_google_android_filament_Texture_nSetImage3DCompressed(JNIEnv *env, jcla
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment, jint stride, jint format,
jint left, jint top, jint type, jint alignment, jint stride, jint format,
jintArray faceOffsetsInBytes_,
jobject handler, jobject runnable) {
Texture *texture = (Texture *) nativeTexture;
@@ -318,7 +337,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
size_t sizeInBytes = 6 * getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
(Texture::Type) type, (size_t) stride, (size_t) alignment);
(Texture::Type) type, (size_t) stride, 0, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
@@ -330,8 +349,9 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
@@ -341,7 +361,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment,
jint left, jint top, jint type, jint alignment,
jint compressedSizeInBytes, jint compressedFormat, jintArray faceOffsetsInBytes_,
jobject handler, jobject runnable) {
@@ -366,7 +386,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
&JniBufferCallback::invoke, callback);
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
@@ -439,7 +459,7 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment,
(uint32_t) left, (uint32_t) top, (uint32_t) stride,
&JniBufferCallback::invoke, callback);
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
Texture::PrefilterOptions options;
options.sampleCount = sampleCount;
@@ -453,7 +473,7 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
// ANDROID SPECIFIC BITS
////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef ANDROID
#ifdef __ANDROID__
#define BITMAP_CONFIG_ALPHA_8 0
#define BITMAP_CONFIG_RGB_565 1
@@ -462,46 +482,37 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
#define BITMAP_CONFIG_RGBA_F16 4
#define BITMAP_CONFIG_HARDWARE 5
class AutoBitmap {
public:
class AutoBitmap : public JniCallback {
private:
AutoBitmap(JNIEnv* env, jobject bitmap) noexcept
: mEnv(env)
, mBitmap(env->NewGlobalRef(bitmap))
{
: JniCallback(),
mBitmap(env->NewGlobalRef(bitmap)) {
if (mBitmap) {
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
AndroidBitmap_getInfo(env, mBitmap, &mInfo);
AndroidBitmap_lockPixels(env, mBitmap, &mData);
}
}
AutoBitmap(JNIEnv* env, jobject bitmap, jobject handler, jobject runnable) noexcept
: mEnv(env)
, mBitmap(env->NewGlobalRef(bitmap))
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(runnable))
{
acquireCallbackJni(env, mCallbackUtils);
: JniCallback(env, handler, runnable),
mBitmap(env->NewGlobalRef(bitmap)) {
if (mBitmap) {
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
AndroidBitmap_getInfo(env, mBitmap, &mInfo);
AndroidBitmap_lockPixels(env, mBitmap, &mData);
}
}
~AutoBitmap() noexcept {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
void release(JNIEnv* env) {
if (mBitmap) {
AndroidBitmap_unlockPixels(mEnv, mBitmap);
mEnv->DeleteGlobalRef(mBitmap);
AndroidBitmap_unlockPixels(env, mBitmap);
env->DeleteGlobalRef(mBitmap);
}
}
AutoBitmap(AutoBitmap &&rhs) noexcept {
mEnv = rhs.mEnv;
std::swap(mData, rhs.mData);
std::swap(mBitmap, rhs.mBitmap);
std::swap(mInfo, rhs.mInfo);
}
~AutoBitmap() override = default;
public:
void* getData() const noexcept {
return mData;
}
@@ -528,28 +539,39 @@ public:
}
}
static void invoke(void* buffer, size_t n, void* user) {
AutoBitmap* data = reinterpret_cast<AutoBitmap*>(user);
delete data;
}
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap) {
return new AutoBitmap(env, bitmap);
}
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap,
jobject handler, jobject runnable) {
// create a AutoBitmap
static AutoBitmap* make(JNIEnv* env, jobject bitmap, jobject handler, jobject runnable) {
return new AutoBitmap(env, bitmap, handler, runnable);
}
// execute the callback on the java thread and destroy ourselves
static void invoke(void*, size_t, void* user) {
auto* autoBitmap = reinterpret_cast<AutoBitmap*>(user);
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
releaseCallbackJni(env, autoBitmap->mCallbackUtils, autoBitmap->mHandler, autoBitmap->mCallback);
autoBitmap->release(env);
delete autoBitmap;
}
// create a AutoBitmap without a handler
static AutoBitmap* make(JNIEnv* env, jobject bitmap) {
return new AutoBitmap(env, bitmap);
}
// just destroy ourselves
static void invokeNoCallback(void*, size_t, void* user) {
auto* autoBitmap = reinterpret_cast<AutoBitmap*>(user);
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
autoBitmap->release(env);
delete autoBitmap;
}
private:
JNIEnv* mEnv;
void* mData = nullptr;
jobject mBitmap = nullptr;
jobject mHandler = nullptr;
jobject mCallback = nullptr;
AndroidBitmapInfo mInfo;
CallbackJni mCallbackUtils;
AndroidBitmapInfo mInfo{};
};
extern "C"
@@ -560,14 +582,14 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmap(JNIEnv* env, j
Texture* texture = (Texture*) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap);
auto* autoBitmap = AutoBitmap::make(env, bitmap);
Texture::PixelBufferDescriptor desc(
autoBitmap->getData(),
autoBitmap->getSizeInBytes(),
autoBitmap->getFormat(format),
autoBitmap->getType(format),
&AutoBitmap::invoke, autoBitmap);
&AutoBitmap::invokeNoCallback, autoBitmap);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset,
@@ -583,14 +605,14 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
Texture* texture = (Texture*) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap, handler, runnable);
auto* autoBitmap = AutoBitmap::make(env, bitmap, handler, runnable);
Texture::PixelBufferDescriptor desc(
autoBitmap->getData(),
autoBitmap->getSizeInBytes(),
autoBitmap->getFormat(format),
autoBitmap->getType(format),
&AutoBitmap::invoke, autoBitmap);
autoBitmap->getHandler(), &AutoBitmap::invoke, autoBitmap);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset,
@@ -0,0 +1,98 @@
/*
* 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 <filament/ToneMapper.h>
using namespace filament;
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nDestroyToneMapper(JNIEnv *env, jclass clazz,
jlong toneMapper_) {
ToneMapper* toneMapper = (ToneMapper*) toneMapper_;
delete toneMapper;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateLinearToneMapper(JNIEnv*, jclass) {
return (jlong) new LinearToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateACESToneMapper(JNIEnv*, jclass) {
return (jlong) new ACESToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateACESLegacyToneMapper(JNIEnv*, jclass) {
return (jlong) new ACESLegacyToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jclass) {
return (jlong) new FilmicToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass,
jfloat contrast, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
return (jlong) new GenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_ToneMapper_nGenericGetContrast(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getContrast();
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getMidGrayIn();
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayOut(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getMidGrayOut();
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_ToneMapper_nGenericGetHdrMax(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getHdrMax();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nGenericSetContrast(JNIEnv*, jclass,
jlong nativeObject, jfloat contrast) {
((GenericToneMapper*) nativeObject)->setContrast(contrast);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass,
jlong nativeObject, jfloat midGrayIn) {
((GenericToneMapper*) nativeObject)->setMidGrayIn(midGrayIn);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayOut(JNIEnv*, jclass,
jlong nativeObject, jfloat midGrayOut) {
((GenericToneMapper*) nativeObject)->setMidGrayOut(midGrayOut);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nGenericSetHdrMax(JNIEnv*, jclass,
jlong nativeObject, jfloat hdrMax) {
((GenericToneMapper*) nativeObject)->setHdrMax(hdrMax);
}
@@ -70,6 +70,23 @@ Java_com_google_android_filament_TransformManager_nCreateArray(JNIEnv* env,
return tm->getInstance(entity);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TransformManager_nCreateArrayFp64(JNIEnv* env,
jclass, jlong nativeTransformManager, jint entity_, jint parent,
jdoubleArray localTransform_) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
if (localTransform_) {
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
tm->create(entity, (TransformManager::Instance) parent,
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
} else {
tm->create(entity, (TransformManager::Instance) parent);
}
return tm->getInstance(entity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nDestroy(JNIEnv*, jclass,
jlong nativeTransformManager, jint entity_) {
@@ -86,6 +103,13 @@ Java_com_google_android_filament_TransformManager_nSetParent(JNIEnv*, jclass,
(TransformManager::Instance) newParent);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TransformManager_nGetParent(JNIEnv*, jclass,
jlong nativeTransformManager, jint i) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
return tm->getParent((TransformManager::Instance) i).getId();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
@@ -97,6 +121,17 @@ Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
env->ReleaseFloatArrayElements(localTransform_, localTransform, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nSetTransformFp64(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
jdoubleArray localTransform_) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
tm->setTransform((TransformManager::Instance) i,
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
@@ -108,6 +143,17 @@ Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
env->ReleaseFloatArrayElements(outLocalTransform_, outLocalTransform, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nGetTransformFp64(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
jdoubleArray outLocalTransform_) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
jdouble *outLocalTransform = env->GetDoubleArrayElements(outLocalTransform_, NULL);
*reinterpret_cast<filament::math::mat4 *>(outLocalTransform) = tm->getTransformAccurate(
(TransformManager::Instance) i);
env->ReleaseDoubleArrayElements(outLocalTransform_, outLocalTransform, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
@@ -119,6 +165,17 @@ Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env
env->ReleaseFloatArrayElements(outWorldTransform_, outWorldTransform, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nGetWorldTransformFp64(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
jdoubleArray outWorldTransform_) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
jdouble *outWorldTransform = env->GetDoubleArrayElements(outWorldTransform_, NULL);
*reinterpret_cast<filament::math::mat4 *>(outWorldTransform) = tm->getWorldTransformAccurate(
(TransformManager::Instance) i);
env->ReleaseDoubleArrayElements(outWorldTransform_, outWorldTransform, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nOpenLocalTransformTransaction(
JNIEnv*, jclass, jlong nativeTransformManager) {
@@ -132,3 +189,19 @@ Java_com_google_android_filament_TransformManager_nCommitLocalTransformTransacti
TransformManager* tm = (TransformManager*) nativeTransformManager;
tm->commitLocalTransformTransaction();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nSetAccurateTranslationsEnabled(JNIEnv*,
jclass, jlong nativeTransformManager, jboolean enable) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
tm->setAccurateTranslationsEnabled((bool)enable);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_TransformManager_nIsAccurateTranslationsEnabled(JNIEnv*,
jclass, jlong nativeTransformManager) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
return (jboolean)tm->isAccurateTranslationsEnabled();
}
@@ -32,33 +32,40 @@ using namespace filament::math;
using namespace backend;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_VertexBuffer_nCreateBuilder(JNIEnv *env, jclass type) {
Java_com_google_android_filament_VertexBuffer_nCreateBuilder(JNIEnv*, jclass) {
return (jlong) new VertexBuffer::Builder();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nDestroyBuilder(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nDestroyBuilder(JNIEnv*, jclass,
jlong nativeBuilder) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
delete builder;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv*, jclass,
jlong nativeBuilder, jint vertexCount) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
builder->vertexCount((uint32_t) vertexCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderBufferCount(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nBuilderEnableBufferObjects(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
builder->enableBufferObjects(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderBufferCount(JNIEnv*, jclass,
jlong nativeBuilder, jint bufferCount) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
builder->bufferCount((uint8_t) bufferCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv*, jclass,
jlong nativeBuilder, jint attribute, jint bufferIndex, jint attributeType, jint byteOffset,
jint byteStride) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
@@ -68,14 +75,14 @@ Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jcl
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv*, jclass,
jlong nativeBuilder, jint attribute, jboolean normalized) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
builder->normalized((VertexAttribute) attribute, normalized);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
@@ -83,14 +90,14 @@ Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv *env, jclass
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_VertexBuffer_nGetVertexCount(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nGetVertexCount(JNIEnv*, jclass,
jlong nativeVertexBuffer) {
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
return (jint) vertexBuffer->getVertexCount();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass type,
Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass,
jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex,
jobject buffer, jint remaining,
jint destOffsetInBytes, jint count, jobject handler, jobject runnable) {
@@ -107,7 +114,8 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
BufferDescriptor desc(data, sizeInBytes,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
vertexBuffer->setBufferAt(*engine, (uint8_t) bufferIndex, std::move(desc),
(uint32_t) destOffsetInBytes);
@@ -115,42 +123,11 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
return 0;
}
extern "C" [[deprecated]] JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nPopulateTangentQuaternions(JNIEnv *env,
jclass type, jint quatType, jint quatCount, jobject outBuffer, jint outRemaining,
jint outStride, jobject normals, jint normalsRemaining, jint normalsStride,
jobject tangents, jint tangentsRemaining, jint tangentsStride) {
AutoBuffer outNioBuffer(env, outBuffer, outRemaining, true);
void* outData = outNioBuffer.getData();
AutoBuffer normalsNioBuffer(env, normals, normalsRemaining);
auto normalsData = (const float3*) normalsNioBuffer.getData();
if (tangents) {
AutoBuffer tangentsNioBuffer(env, tangents, tangentsRemaining);
auto tangentsData = (const float4*) tangentsNioBuffer.getData();
VertexBuffer::populateTangentQuaternions({
.quatType = (VertexBuffer::QuatType) quatType,
.quatCount = (size_t) quatCount,
.outBuffer = outData,
.outStride = (size_t) outStride,
.normals = normalsData,
.normalsStride = (size_t) normalsStride,
.tangents = tangentsData,
.tangentsStride = (size_t) tangentsStride
});
return;
}
VertexBuffer::populateTangentQuaternions({
.quatType = (VertexBuffer::QuatType) quatType,
.quatCount = (size_t) quatCount,
.outBuffer = outData,
.outStride = (size_t) outStride,
.normals = normalsData,
.normalsStride = (size_t) normalsStride,
.tangents = nullptr,
.tangentsStride = 0
});
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv*, jclass,
jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex, jlong nativeBufferObject) {
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
Engine *engine = (Engine *) nativeEngine;
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
vertexBuffer->setBufferObjectAt(*engine, (uint8_t) bufferIndex, bufferObject);
}
+115 -10
View File
@@ -20,6 +20,10 @@
#include <filament/View.h>
#include <filament/Viewport.h>
#include "common/CallbackUtils.h"
#include "private/backend/VirtualMachineEnv.h"
using namespace filament;
extern "C" JNIEXPORT void JNICALL
@@ -82,13 +86,19 @@ Java_com_google_android_filament_View_nSetRenderTarget(JNIEnv*, jclass,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, jlong nativeView, jint count) {
View* view = (View*) nativeView;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
view->setSampleCount((uint8_t) count);
#pragma clang diagnostic pop
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return view->getSampleCount();
#pragma clang diagnostic pop
}
extern "C" JNIEXPORT void JNICALL
@@ -119,13 +129,14 @@ Java_com_google_android_filament_View_nGetDithering(JNIEnv*, jclass,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jclass, jlong nativeView,
jboolean enabled, jboolean homogeneousScaling,
jfloat minScale, jfloat maxScale, jint quality) {
jfloat minScale, jfloat maxScale, jfloat sharpness, jint quality) {
View* view = (View*)nativeView;
View::DynamicResolutionOptions options;
options.enabled = enabled;
options.homogeneousScaling = homogeneousScaling;
options.minScale = filament::math::float2{ minScale };
options.maxScale = filament::math::float2{ maxScale };
options.sharpness = sharpness;
options.quality = (View::QualityLevel)quality;
view->setDynamicResolutionOptions(options);
}
@@ -138,13 +149,27 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
jint anisotropy) {
jint anisotropy, jboolean mipmapping, jfloat minVarianceScale,
jfloat lightBleedReduction) {
View* view = (View*) nativeView;
View::VsmShadowOptions options;
options.anisotropy = (uint8_t) anisotropy;
options.anisotropy = (uint8_t)anisotropy;
options.mipmapping = (bool)mipmapping;
options.minVarianceScale = minVarianceScale;
options.lightBleedReduction = lightBleedReduction;
view->setVsmShadowOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetSoftShadowOptions(JNIEnv*, jclass, jlong nativeView,
jfloat penumbraScale, jfloat penumbraRatioScale) {
View* view = (View*) nativeView;
View::SoftShadowOptions options;
options.penumbraScale = penumbraScale;
options.penumbraRatioScale = penumbraRatioScale;
view->setSoftShadowOptions(options);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetRenderQuality(JNIEnv*, jclass,
@@ -211,7 +236,9 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
jfloat bilateralThreshold,
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jboolean bentNormals,
jfloat minHorizonAngleRad) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.radius = radius;
@@ -219,10 +246,12 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
options.bias = bias;
options.resolution = resolution;
options.intensity = intensity;
options.bilateralThreshold = bilateralThreshold;
options.quality = (View::QualityLevel)quality;
options.lowPassFilter = (View::QualityLevel)lowPassFilter;
options.upsampling = (View::QualityLevel)upsampling;
options.enabled = (bool)enabled;
options.bentNormals = (bool)bentNormals;
options.minHorizonAngleRad = minHorizonAngleRad;
view->setAmbientOcclusionOptions(options);
}
@@ -253,7 +282,10 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
jlong nativeView, jlong nativeTexture,
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight) {
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight,
jboolean lensFlare, jboolean starburst, jfloat chromaticAberration, jint ghostCount,
jfloat ghostSpacing, jfloat ghostThreshold, jfloat haloThickness, jfloat haloRadius,
jfloat haloThreshold) {
View* view = (View*) nativeView;
Texture* dirt = (Texture*) nativeTexture;
View::BloomOptions options = {
@@ -266,7 +298,16 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
.blendMode = (View::BloomOptions::BlendMode)blendMode,
.threshold = (bool)threshold,
.enabled = (bool)enabled,
.highlight = highlight
.highlight = highlight,
.lensFlare = (bool)lensFlare,
.starburst = (bool)starburst,
.chromaticAberration = chromaticAberration,
.ghostCount = (uint8_t)ghostCount,
.ghostSpacing = ghostSpacing,
.ghostThreshold = ghostThreshold,
.haloThickness = haloThickness,
.haloRadius = haloRadius,
.haloThreshold = haloThreshold
};
view->setBloomOptions(options);
}
@@ -299,11 +340,25 @@ Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nat
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass ,
jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled) {
Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass,
jlong nativeView, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled, jint filter,
jboolean nativeResolution, jint foregroundRingCount, jint backgroundRingCount, jint fastGatherRingCount,
jint maxForegroundCOC, jint maxBackgroundCOC) {
View* view = (View*) nativeView;
view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale,
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled});
View::DepthOfFieldOptions::Filter eFilter{};
if (filter == 1) {
// View::DepthOfFieldOptions::Filter::MEDIAN value is actually 2
eFilter = View::DepthOfFieldOptions::Filter::MEDIAN;
}
view->setDepthOfFieldOptions({.cocScale = cocScale,
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter,
.nativeResolution = (bool)nativeResolution,
.foregroundRingCount = (uint8_t)foregroundRingCount,
.backgroundRingCount = (uint8_t)backgroundRingCount,
.fastGatherRingCount = (uint8_t)fastGatherRingCount,
.maxForegroundCOC = (uint8_t)maxForegroundCOC,
.maxBackgroundCOC = (uint8_t)maxBackgroundCOC,
});
}
extern "C"
@@ -315,6 +370,17 @@ Java_com_google_android_filament_View_nSetVignetteOptions(JNIEnv*, jclass, jlong
.color = LinearColorA{r, g, b, a}, .enabled = (bool)enabled});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetMultiSampleAntiAliasingOptions(JNIEnv* env, jclass clazz,
jlong nativeView, jboolean enabled, jint sampleCount, jboolean customResolve) {
View* view = (View*) nativeView;
view->setMultiSampleAntiAliasingOptions({
.enabled = (bool)enabled,
.sampleCount = (uint8_t)sampleCount,
.customResolve = (bool)customResolve});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *, jclass,
@@ -346,3 +412,42 @@ Java_com_google_android_filament_View_nIsScreenSpaceRefractionEnabled(JNIEnv *,
View* view = (View*) nativeView;
return (jboolean)view->isScreenSpaceRefractionEnabled();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nPick(JNIEnv* env, jclass,
jlong nativeView,
jint x, jint y, jobject handler, jobject internalCallback) {
// jniState will be initialized the first time this method is called
static const struct JniState {
jclass internalOnPickCallbackClass;
jfieldID renderableFieldId;
jfieldID depthFieldId;
jfieldID fragCoordXFieldId;
jfieldID fragCoordYFieldId;
jfieldID fragCoordZFieldId;
explicit JniState(JNIEnv* env) noexcept {
internalOnPickCallbackClass = env->FindClass("com/google/android/filament/View$InternalOnPickCallback");
renderableFieldId = env->GetFieldID(internalOnPickCallbackClass, "mRenderable", "I");
depthFieldId = env->GetFieldID(internalOnPickCallbackClass, "mDepth", "F");
fragCoordXFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsX", "F");
fragCoordYFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsY", "F");
fragCoordZFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsZ", "F");
}
} jniState(env);
View* view = (View*) nativeView;
JniCallback *callback = JniCallback::make(env, handler, internalCallback);
view->pick(x, y, [callback](View::PickingQueryResult const& result) {
// this is executed on the backend/service thread
jobject obj = callback->getCallbackObject();
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
env->SetIntField(obj, jniState.renderableFieldId, (jint)result.renderable.getId());
env->SetFloatField(obj, jniState.depthFieldId, result.depth);
env->SetFloatField(obj, jniState.fragCoordXFieldId, result.fragCoords.x);
env->SetFloatField(obj, jniState.fragCoordYFieldId, result.fragCoords.y);
env->SetFloatField(obj, jniState.fragCoordZFieldId, result.fragCoords.z);
JniCallback::postToJavaAndDestroy(callback);
}, callback->getHandler());
}
@@ -1,71 +0,0 @@
/*
* Copyright (C) 2018 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 <stdio.h>
#include <jawt.h>
#if defined(__has_include)
#if __has_include(<darwin/jawt_md.h>)
#include <darwin/jawt_md.h>
#else
#include <jawt_md.h>
#endif
#else
#include <darwin/jawt_md.h>
#endif
#include <filament/Engine.h>
#include "JAWTUtils.h"
#import <Cocoa/Cocoa.h>
#pragma clang diagnostic push
#pragma ide diagnostic ignored "NotReleasedValue"
extern "C" {
void *getNativeWindow(JNIEnv *env, jclass klass, jobject surface) {
void *win = nullptr;
JAWT_DrawingSurface *ds = nullptr;
JAWT_DrawingSurfaceInfo *dsi = nullptr;
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
return win;
}
NSObject<JAWT_SurfaceLayers>* jawldsip = (NSObject<JAWT_SurfaceLayers>*)dsi->platformInfo;
// Use jawt_DrawingSurfaceInfo.bounds for frame dimension.
NSView *view = [[NSView alloc] initWithFrame:
NSMakeRect(dsi->bounds.x, dsi->bounds.y, dsi->bounds.width, dsi->bounds.height)];
view.wantsLayer = true;
[jawldsip setLayer:view.layer];
win = (void*) view;
releaseDrawingSurface(ds, dsi);
return win;
}
jlong createNativeSurface(jint width, jint height) {
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
view.wantsLayer = true;
return (jlong) view;
}
void destroyNativeSurface(jlong surface) {
NSView *view = reinterpret_cast<NSView*>(surface);
[view release];
}
}
#pragma clang diagnostic pop
@@ -1,116 +0,0 @@
/*
* Copyright (C) 2018 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 "JAWTUtils.h"
#include <vector>
static std::vector<int> jawtVersions = {
0x00010003,
0x00010004,
0x00010007,
0x00010009,
};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wuninitialized"
bool acquireDrawingSurface(JNIEnv* env, jobject surface,
JAWT_DrawingSurface** ods, JAWT_DrawingSurfaceInfo** odsi) {
JAWT awt;
JAWT_DrawingSurface* ds = nullptr;
JAWT_DrawingSurfaceInfo* dsi = nullptr;
// Search for a valid AWT
jboolean foundJawt = JNI_FALSE;
for (int jawtVersion : jawtVersions) {
awt.version = jawtVersion;
#if defined(__APPLE__) && defined(__aarch64__)
// FIXME: enable Apple Silicon build. The problem here is that we attempt to link an x86 jdk and that fails
// so JAWT_GetAWT doesn't exist at link time.
#warning "FIXME: JAWT_GetAWT() not supported"
foundJawt = {};
#else
foundJawt = JAWT_GetAWT(env, &awt);
#endif
if (foundJawt == JNI_TRUE) {
#ifndef NDEBUG
printf("Found valid AWT v%08x.\n", jawtVersion);
#endif
break;
} else {
#ifndef NDEBUG
printf("AWT v%08x not present.\n", jawtVersion);
#endif
}
}
#ifndef NDEBUG
fflush(stdout);
#endif
if (foundJawt == JNI_FALSE) {
printf("AWT Not found\n");
fflush(stdout);
return false;
}
// Get the drawing surface
ds = awt.GetDrawingSurface(env, surface);
if (ds == nullptr) {
#ifndef NDEBUG
printf("NULL drawing surface\n");
fflush(stdout);
#endif
return false;
}
// Lock the drawing
jint lock = ds->Lock(ds);
if ((lock & JAWT_LOCK_ERROR) != 0) {
#ifndef NDEBUG
printf("Error locking surface\n");
fflush(stdout);
#endif
awt.FreeDrawingSurface(ds);
return false;
}
// Get the drawing surface info
dsi = ds->GetDrawingSurfaceInfo(ds);
if (dsi == nullptr) {
#ifndef NDEBUG
printf("Error getting surface info\n");
fflush(stdout);
#endif
ds->Unlock(ds);
awt.FreeDrawingSurface(ds);
return false;
}
*odsi = dsi;
*ods = ds;
return true;
}
#pragma clang diagnostic pop
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi) {
// Free the drawing surface info
ds->FreeDrawingSurfaceInfo(dsi);
// Unlock the drawing surface
ds->Unlock(ds);
}
@@ -1,90 +0,0 @@
/*
* Copyright (C) 2018 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 <stdio.h>
#include <jawt.h>
#include <linux/jawt_md.h>
#include "JAWTUtils.h"
#include<GL/glx.h>
extern "C" {
void *getNativeWindow(JNIEnv* env, jclass, jobject surface) {
void* win = nullptr;
JAWT_DrawingSurface* ds = nullptr;
JAWT_DrawingSurfaceInfo* dsi = nullptr;
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
return win;
}
JAWT_X11DrawingSurfaceInfo* dsi_x11 = (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo;
win = (void*) dsi_x11->drawable;
releaseDrawingSurface(ds, dsi);
return win;
}
jlong createNativeSurface(jint width, jint height) {
Display* display = XOpenDisplay(nullptr);
int screen = DefaultScreen(display);
Window window = 0;
#ifndef NDEBUG
int major, minor;
glXQueryVersion(display, &major, &minor);
printf("Using GLX v%d.%d\n", major, minor); fflush(stdout);
#endif
static int visualAttributess[] = {
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DOUBLEBUFFER, True,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_DEPTH_SIZE, 24,
None
};
int numConfigs = 0;
GLXFBConfig* configs = glXChooseFBConfig( display, screen, visualAttributess, &numConfigs);
if (numConfigs == 0) {
printf("Unable to find a suitable Framebuffer Configuration.\n"); fflush(stdout);
return 0;
}
int pbufferAttributes[] = {
GLX_PBUFFER_WIDTH, width,
GLX_PBUFFER_HEIGHT, height,
None
};
window = glXCreatePbuffer( display, configs[0], pbufferAttributes );
XFree(configs);
// Make sure pbuffer creation has not been buffered in the event queue (we need it NOW).
XFlush(display);
// Camouflage the pbuffer as a window which are both XID anyway.
return (jlong) window;
}
void destroyNativeSurface(jlong surface) {
const char* displayName = nullptr;
Display* display = XOpenDisplay(displayName);
GLXPbuffer pBuffer = (GLXPbuffer)surface;
glXDestroyPbuffer(display, pBuffer);
}
}
@@ -1,67 +0,0 @@
/*
* Copyright (C) 2018 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 <stdio.h>
#include <jawt.h>
#include <win32/jawt_md.h>
#include <windows.h>
#include <utils/unwindows.h>
#include "JAWTUtils.h"
#include <filament/Engine.h>
extern "C" {
void* getNativeWindow(JNIEnv* env, jclass, jobject surface) {
JAWT_DrawingSurface* ds = nullptr;
JAWT_DrawingSurfaceInfo* dsi = nullptr;
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
return nullptr;
}
JAWT_Win32DrawingSurfaceInfo* dsi_win32 = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
HWND hWnd = dsi_win32->hwnd;
releaseDrawingSurface(ds, dsi);
return (void*) hWnd;
}
jlong createNativeSurface(jint width, jint height) {
// We need to adjust the window size so the "client area" matches width and height requested.
// Otherwise, the window itself will be of dimension width-height but the "client area" and the
// resulting surface will be smaller than requested.
RECT dimension = {0, 0, width, height};
AdjustWindowRect(&dimension, WS_OVERLAPPEDWINDOW, FALSE);
width = dimension.right - dimension.left;
height = dimension.bottom - dimension.top;
HWND window = CreateWindowA("STATIC", "dummy", 0, 0, 0, width, height, NULL, NULL, NULL, NULL);
SetWindowLong(window, GWL_STYLE, 0); //remove all window styles
return (jlong) window;
}
void destroyNativeSurface(jlong surface) {
HWND window = (HWND) surface;
DestroyWindow(window);
}
}
@@ -63,12 +63,27 @@ final class Asserts {
return out;
}
@NonNull @Size(min = 16)
static double[] assertMat4(@Nullable double[] out) {
if (out == null) out = new double[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
}
static void assertMat4fIn(@NonNull @Size(min = 16) float[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
static void assertMat4In(@NonNull @Size(min = 16) double[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
@NonNull @Size(min = 3)
static float[] assertFloat3(@Nullable float[] out) {
if (out == null) out = new float[3];
@@ -0,0 +1,210 @@
/*
* 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.
*/
package com.google.android.filament;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.nio.Buffer;
import java.nio.BufferOverflowException;
/**
* A generic GPU buffer containing data.
*
* Usage of this BufferObject is optional. For simple use cases it is not necessary. It is useful
* only when you need to share data between multiple VertexBuffer instances. It also allows you to
* efficiently swap-out the buffers in VertexBuffer.
*
* NOTE: For now this is only used for vertex data, but in the future we may use it for other things
* (e.g. compute).
*
* @see VertexBuffer
*/
public class BufferObject {
private long mNativeObject;
private BufferObject(long nativeBufferObject) {
mNativeObject = nativeBufferObject;
}
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
private final BuilderFinalizer mFinalizer;
private final long mNativeBuilder;
public enum BindingType {
VERTEX,
}
public Builder() {
mNativeBuilder = nCreateBuilder();
mFinalizer = new BuilderFinalizer(mNativeBuilder);
}
/**
* Size of the buffer in bytes.
*
* @param byteCount Maximum number of bytes the BufferObject can hold.
* @return A reference to this Builder for chaining calls.
*/
@NonNull
public Builder size(@IntRange(from = 1) int byteCount) {
nBuilderSize(mNativeBuilder, byteCount);
return this;
}
/**
* The binding type for this buffer object. (defaults to VERTEX)
*
* @param bindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX.
* @return A reference to this Builder for chaining calls.
*/
@NonNull
public Builder bindingType(@NonNull BindingType bindingType) {
nBuilderBindingType(mNativeBuilder, bindingType.ordinal());
return this;
}
/**
* Creates and returns the <code>BufferObject</code> object. After creation, the buffer
* is uninitialized. Use {@link #setBuffer} to initialize the <code>BufferObject</code>.
*
* @param engine reference to the {@link Engine} to associate this <code>BufferObject</code>
* with
*
* @return the newly created <code>BufferObject</code> object
*
* @exception IllegalStateException if the BufferObject could not be created
*
* @see #setBuffer
*/
@NonNull
public BufferObject build(@NonNull Engine engine) {
long nativeBufferObject = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
if (nativeBufferObject == 0)
throw new IllegalStateException("Couldn't create BufferObject");
return new BufferObject(nativeBufferObject);
}
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);
}
}
}
}
/**
* Returns the size of this <code>BufferObject</code> in elements.
*
* @return the number of bytes the <code>BufferObject</code> holds
*/
@IntRange(from = 0)
public int getByteCount() {
return nGetByteCount(getNativeObject());
}
/**
* Asynchronously copy-initializes this <code>BufferObject</code> from the data provided.
*
* @param engine reference to the {@link Engine} to associate this
* <code>BufferObject</code> with
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
* <code>BufferObject</code>.
*/
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer) {
setBuffer(engine, buffer, 0, 0, null, null);
}
/**
* Asynchronously copy-initializes a region of this <code>BufferObject</code> from the data
* provided.
*
* @param engine reference to the {@link Engine} to associate this
* <code>BufferObject</code> with
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
* <code>BufferObject</code>.
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>BufferObject</code>
* @param count number of bytes to consume, defaults to
* <code>buffer.remaining()</code>
*/
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count) {
setBuffer(engine, buffer, destOffsetInBytes, count, null, null);
}
/**
* Asynchronously copy-initializes a region of this <code>BufferObject</code> from the data
* provided.
*
* @param engine reference to the {@link Engine} to associate this
* <code>BufferObject</code> with
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
* <code>BufferObject</code>.
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>BufferObject</code>
* @param count number of bytes to consume, defaults to
* <code>buffer.remaining()</code>
* @param handler an {@link java.util.concurrent.Executor Executor}. On Android this
* can also be a {@link android.os.Handler Handler}.
* @param callback a callback executed by <code>handler</code> when <code>buffer</code>
* is no longer needed.
*/
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count,
@Nullable Object handler, @Nullable Runnable callback) {
int result = nSetBuffer(getNativeObject(), engine.getNativeObject(), buffer, buffer.remaining(),
destOffsetInBytes, count == 0 ? buffer.remaining() : count, handler, callback);
if (result < 0) {
throw new BufferOverflowException();
}
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed BufferObject");
}
return mNativeObject;
}
void clearNativeObject() {
mNativeObject = 0;
}
private static native long nCreateBuilder();
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderSize(long nativeBuilder, int byteCount);
private static native void nBuilderBindingType(long nativeBuilder, int bindingType);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetByteCount(long nativeBufferObject);
private static native int nSetBuffer(long nativeBufferObject, long nativeEngine,
Buffer buffer, int remaining,
int destOffsetInBytes, int count, Object handler, Runnable callback);
}
@@ -27,21 +27,17 @@ import androidx.annotation.Size;
*
* <h1><u>Creation and destruction</u></h1>
*
* Unlike most Filament objects, Camera doesn't require a builder and can be constructed directly
* using {@link Engine#createCamera}. At the very least, a projection must be defined
* using {@link #setProjection}. In most case, the camera position also needs to be set.
* <p>
* A Camera object is destroyed using {@link Engine#destroyCamera}.
* In Filament, Camera is a component that must be associated with an entity. To do so,
* use {@link Engine#createCamera(int)}. A Camera component is destroyed using
* {@link Engine#destroyCameraComponent(int Entity)} ()}.
*
* <pre>
* Engine engine = Engine.create();
*
* Camera myCamera = engine.createCamera();
* Camera myCamera = engine.createCamera(myCameraEntity);
* myCamera.setProjection(45, 16.0/9.0, 0.1, 1.0);
* myCamera.lookAt(0, 1.60, 1,
* 0, 0, 0,
* 0, 1, 0);
* engine.destroyCamera(myCamera);
* engine.destroyCameraComponent(myCameraEntity);
* </pre>
*
*
@@ -125,6 +121,9 @@ import androidx.annotation.Size;
public class Camera {
private long mNativeObject;
@Entity
private final int mEntity;
/**
* Denotes the projection type used by this camera.
* @see #setProjection
@@ -147,8 +146,9 @@ public class Camera {
HORIZONTAL
}
Camera(long nativeCamera) {
Camera(long nativeCamera, @Entity int entity) {
mNativeObject = nativeCamera;
mEntity = entity;
}
/**
@@ -252,9 +252,12 @@ public class Camera {
}
/**
* Sets the projection matrix.
* Sets a custom projection matrix.
*
* @param inMatrix custom projection matrix.
* <p>The projection matrix must define an NDC system that must match the OpenGL convention,
* that is all 3 axis are mapped to [-1, 1].</p>
*
* @param inProjection custom projection matrix for rendering and culling
*
* @param near distance in world units from the camera to the near plane.
* The near plane's position in view space is z = -<code>near</code>.
@@ -270,10 +273,74 @@ public class Camera {
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*/
public void setCustomProjection(@NonNull @Size(min = 16) double[] inMatrix,
public void setCustomProjection(@NonNull @Size(min = 16) double[] inProjection,
double near, double far) {
Asserts.assertMat4dIn(inMatrix);
nSetCustomProjection(getNativeObject(), inMatrix, near, far);
Asserts.assertMat4dIn(inProjection);
nSetCustomProjection(getNativeObject(), inProjection, inProjection, near, far);
}
/**
* Sets a custom projection matrix.
*
* <p>The projection matrices must define an NDC system that must match the OpenGL convention,
* that is all 3 axis are mapped to [-1, 1].</p>
*
* @param inProjection custom projection matrix for rendering.
*
* @param inProjectionForCulling custom projection matrix for culling.
*
* @param near distance in world units from the camera to the near plane.
* The near plane's position in view space is z = -<code>near</code>.
* Precondition:
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
*
* @param far distance in world units from the camera to the far plane.
* The far plane's position in view space is z = -<code>far</code>.
* Precondition:
* <code>far</code> > <code>near</code>
* for {@link Projection#PERSPECTIVE} or
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*/
public void setCustomProjection(
@NonNull @Size(min = 16) double[] inProjection,
@NonNull @Size(min = 16) double[] inProjectionForCulling,
double near, double far) {
Asserts.assertMat4dIn(inProjection);
Asserts.assertMat4dIn(inProjectionForCulling);
nSetCustomProjection(getNativeObject(), inProjection, inProjectionForCulling, near, far);
}
/**
* Sets an additional matrix that scales the projection matrix.
*
* <p>This is useful to adjust the aspect ratio of the camera independent from its projection.
* First, pass an aspect of 1.0 to setProjection. Then set the scaling with the desired aspect
* ratio:<br>
*
* <code>
* double aspect = width / height;
*
* // with Fov.HORIZONTAL passed to setProjection:
* camera.setScaling(1.0, aspect);
*
* // with Fov.VERTICAL passed to setProjection:
* camera.setScaling(1.0 / aspect, 1.0);
* </code>
*
* By default, this is an identity matrix.
* </p>
*
* @param xscaling horizontal scaling to be applied after the projection matrix.
* @param yscaling vertical scaling to be applied after the projection matrix.
*
* @see Camera#setProjection
* @see Camera#setLensProjection
* @see Camera#setCustomProjection
*/
public void setScaling(double xscaling, double yscaling) {
nSetScaling(getNativeObject(), xscaling, yscaling);
}
/**
@@ -303,10 +370,33 @@ public class Camera {
* @see Camera#setProjection
* @see Camera#setLensProjection
* @see Camera#setCustomProjection
*
* @deprecated use {@link #setScaling(double, double)}
*
*/
@Deprecated
public void setScaling(@NonNull @Size(min = 4) double[] inScaling) {
Asserts.assertDouble4In(inScaling);
nSetScaling(getNativeObject(), inScaling);
setScaling(inScaling[0], inScaling[1]);
}
/**
* Sets an additional matrix that shifts (translates) the projection matrix.
* <p>
* The shift parameters are specified in NDC coordinates, that is, if the translation must
* be specified in pixels, the xshift and yshift parameters be scaled by 1.0 / viewport.width
* and 1.0 / viewport.height respectively.
* </p>
*
* @param xshift horizontal shift in NDC coordinates applied after the projection
* @param yshift vertical shift in NDC coordinates applied after the projection
*
* @see Camera#setProjection
* @see Camera#setLensProjection
* @see Camera#setCustomProjection
*/
public void setShift(double xshift, double yshift) {
nSetShift(getNativeObject(), xshift, yshift);
}
/**
@@ -329,6 +419,20 @@ public class Camera {
nSetModelMatrix(getNativeObject(), viewMatrix);
}
/**
* Sets the camera's view matrix.
* <p>
* Helper method to set the camera's entity transform component.
* Remember that the Camera "looks" towards its -z axis.
* <p>
*
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
*/
public void setModelMatrix(@NonNull @Size(min = 16) double[] viewMatrix) {
Asserts.assertMat4In(viewMatrix);
nSetModelMatrixFp64(getNativeObject(), viewMatrix);
}
/**
* Sets the camera's view matrix.
*
@@ -348,6 +452,7 @@ public class Camera {
}
/**
* Gets the distance to the near plane
* @return Distance to the near plane
*/
public float getNear() {
@@ -355,6 +460,7 @@ public class Camera {
}
/**
* Gets the distance to the far plane
* @return Distance to the far plane
*/
public float getCullingFar() {
@@ -424,6 +530,22 @@ public class Camera {
return out;
}
/**
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
* orientation, or pose.
*
* @param out A 16-double array where the model matrix will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-double array containing the camera's pose as a column-major matrix.
*/
@NonNull @Size(min = 16)
public double[] getModelMatrix(@Nullable @Size(min = 16) double[] out) {
out = Asserts.assertMat4(out);
nGetModelMatrixFp64(getNativeObject(), out);
return out;
}
/**
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
*
@@ -439,6 +561,21 @@ public class Camera {
return out;
}
/**
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
*
* @param out A 16-double array where the model view will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-double array containing the camera's view as a column-major matrix.
*/
@NonNull @Size(min = 16)
public double[] getViewMatrix(@Nullable @Size(min = 16) double[] out) {
out = Asserts.assertMat4(out);
nGetViewMatrixFp64(getNativeObject(), out);
return out;
}
/**
* Retrieves the camera position in world space.
*
@@ -551,6 +688,7 @@ public class Camera {
}
/**
* Gets the aperture in f-stops
* @return Aperture in f-stops
*/
public float getAperture() {
@@ -558,6 +696,7 @@ public class Camera {
}
/**
* Gets the shutter speed in seconds
* @return Shutter speed in seconds
*/
public float getShutterSpeed() {
@@ -565,12 +704,69 @@ public class Camera {
}
/**
* Gets the focal length in meters
* @return focal length in meters [m]
*/
public double getFocalLength() {
return nGetFocalLength(getNativeObject());
}
/**
* Set the camera focus distance in world units
* @param distance Distance from the camera to the focus plane in world units. Must be
* positive and larger than the camera's near clipping plane.
*/
public void setFocusDistance(float distance) {
nSetFocusDistance(getNativeObject(), distance);
}
/**
* Gets the distance from the camera to the focus plane in world units
* @return Distance from the camera to the focus plane in world units
*/
public float getFocusDistance() {
return nGetFocusDistance(getNativeObject());
}
/**
* Gets the sensitivity in ISO
* @return Sensitivity in ISO
*/
public float getSensitivity() {
return nGetSensitivity(getNativeObject());
}
/**
* Gets the entity representing this Camera
* @return the entity this Camera component is attached to
*/
@Entity
public int getEntity() {
return mEntity;
}
/**
* Helper to compute the effective focal length taking into account the focus distance
*
* @param focalLength focal length in any unit (e.g. [m] or [mm])
* @param focusDistance focus distance in same unit as focalLength
* @return the effective focal length in same unit as focalLength
*/
static double computeEffectiveFocalLength(double focalLength, double focusDistance) {
return nComputeEffectiveFocalLength(focalLength, focusDistance);
}
/**
* Helper to compute the effective field-of-view taking into account the focus distance
*
* @param fovInDegrees full field of view in degrees
* @param focusDistance focus distance in meters [m]
* @return effective full field of view in degrees
*/
static double computeEffectiveFov(double fovInDegrees, double focusDistance) {
return nComputeEffectiveFov(fovInDegrees, focusDistance);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Camera");
@@ -585,9 +781,11 @@ public class Camera {
private static native void nSetProjection(long nativeCamera, int projection, double left, double right, double bottom, double top, double near, double far);
private static native void nSetProjectionFov(long nativeCamera, double fovInDegrees, double aspect, double near, double far, int fov);
private static native void nSetLensProjection(long nativeCamera, double focalLength, double aspect, double near, double far);
private static native void nSetCustomProjection(long nativeCamera, double[] inMatrix, double near, double far);
private static native void nSetScaling(long nativeCamera, double[] inScaling);
private static native void nSetCustomProjection(long nativeCamera, double[] inProjection, double[] inProjectionForCulling, double near, double far);
private static native void nSetScaling(long nativeCamera, double x, double y);
private static native void nSetShift(long nativeCamera, double x, double y);
private static native void nSetModelMatrix(long nativeCamera, float[] in);
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
private static native float nGetNear(long nativeCamera);
private static native float nGetCullingFar(long nativeCamera);
@@ -595,7 +793,9 @@ public class Camera {
private static native void nGetCullingProjectionMatrix(long nativeCamera, double[] out);
private static native void nGetScaling(long nativeCamera, double[] out);
private static native void nGetModelMatrix(long nativeCamera, float[] out);
private static native void nGetModelMatrixFp64(long nativeCamera, double[] out);
private static native void nGetViewMatrix(long nativeCamera, float[] out);
private static native void nGetViewMatrixFp64(long nativeCamera, double[] out);
private static native void nGetPosition(long nativeCamera, float[] out);
private static native void nGetLeftVector(long nativeCamera, float[] out);
private static native void nGetUpVector(long nativeCamera, float[] out);
@@ -604,4 +804,9 @@ public class Camera {
private static native float nGetAperture(long nativeCamera);
private static native float nGetShutterSpeed(long nativeCamera);
private static native float nGetSensitivity(long nativeCamera);
private static native void nSetFocusDistance(long nativeCamera, float distance);
private static native float nGetFocusDistance(long nativeCamera);
private static native double nGetFocalLength(long nativeCamera);
private static native double nComputeEffectiveFocalLength(double focalLength, double focusDistance);
private static native double nComputeEffectiveFov(double fovInDegrees, double focusDistance);
}
@@ -54,6 +54,8 @@ import static com.google.android.filament.Asserts.assertFloat4In;
*
* The various transforms held by ColorGrading are applied in the following order:
* <ul>
* <li>Exposure</li>
* <li>Night adaptation</li>
* <li>White balance</li>
* <li>Channel mixer</li>
* <li>Shadows/mid-tones/highlights</li>
@@ -63,12 +65,16 @@ import static com.google.android.filament.Asserts.assertFloat4In;
* <li>Saturation</li>
* <li>Curves</li>
* <li>Tone mapping</li>
* <li>Luminance scaling</li>
* <li>Gamut mapping</li>
* </ul>
*
* <h1>Defaults</h1>
*
* Here are the default color grading options:
* <ul>
* <li>Exposure: 0.0</li>
* <li>Night adaptation: 0.0</li>
* <li>White balance: temperature <code>0.0</code>, and tint <code>0.0</code></li>
* <li>Channel mixer: red <code>{1,0,0}</code>, green <code>{0,1,0}</code>, blue <code>{0,0,1}</code></li>
* <li>Shadows/mid-tones/highlights: shadows <code>{1,1,1,0}</code>, mid-tones <code>{1,1,1,0}</code>,
@@ -78,11 +84,13 @@ import static com.google.android.filament.Asserts.assertFloat4In;
* <li>Vibrance: <code>1.0</code></li>
* <li>Saturation: <code>1.0</code></li>
* <li>Curves: gamma <code>{1,1,1}</code>, midPoint <code>{1,1,1}</code>, and scale <code>{1,1,1}</code></li>
* <li>Tone mapping: {@link ToneMapping#ACES_LEGACY}</li>
* <li>Tone mapping: {@link ToneMapper.ACESLegacy}</li>
* <li>Luminance scaling: false</li>
* <li>Gamut mapping: false</li>
* </ul>
*
* @see View
* @see ToneMapping
* @see ToneMapper
*/
public class ColorGrading {
long mNativeObject;
@@ -99,6 +107,8 @@ public class ColorGrading {
/**
* List of available tone-mapping operators.
*
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
*/
public enum ToneMapping {
/** Linear tone mapping (i.e. no tone mapping). */
@@ -109,15 +119,12 @@ public class ColorGrading {
ACES,
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
FILMIC,
/** Filmic tone mapping, with more contrast and saturation. */
UCHIMURA,
/** Reinhard luma-based tone mapping. */
REINHARD,
/** Tone mapping used to validate/debug scene exposure. */
DISPLAY_RANGE,
}
ColorGrading(long colorGrading) {
// NOTE: This constructor is public only so that filament-utils can use it.
public ColorGrading(long colorGrading) {
mNativeObject = colorGrading;
}
@@ -155,6 +162,25 @@ public class ColorGrading {
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.
*
* The default tone mapping operator is {@link ToneMapper.ACESLegacy}.
*
* The specified tone mapper must have a lifecycle that exceeds the lifetime of
* this builder. Since the build(Engine&) method is synchronous, it is safe to
* delete the tone mapper object after that finishes executing.
*
* @param toneMapper The tone mapping operator to apply to the HDR color buffer
*
* @return This Builder, for chaining calls
*/
public Builder toneMapper(ToneMapper toneMapper) {
nBuilderToneMapper(mNativeBuilder, toneMapper.getNativeObject());
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.
@@ -164,12 +190,81 @@ public class ColorGrading {
* @param toneMapping The tone mapping operator to apply to the HDR color buffer
*
* @return This Builder, for chaining calls
*
* @deprecated Use {@link #toneMapper(ToneMapper)}
*/
public Builder toneMapping(ToneMapping toneMapping) {
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
return this;
}
/**
* Enables or disables the luminance scaling component (LICH) from the exposure value
* invariant luminance system (EVILS). When this setting is enabled, pixels with high
* chromatic values will roll-off to white to offer a more natural rendering. This step
* also helps avoid undesirable hue skews caused by out of gamut colors clipped
* to the destination color gamut.
*
* When luminance scaling is enabled, tone mapping is performed on the luminance of each
* pixel instead of per-channel.
*
* @param luminanceScaling Enables or disables EVILS post-tone mapping
*
* @return This Builder, for chaining calls
*/
public Builder luminanceScaling(boolean luminanceScaling) {
nBuilderLuminanceScaling(mNativeBuilder, luminanceScaling);
return this;
}
/**
* Enables or disables gamut mapping to the destination color space's gamut. When gamut
* mapping is turned off, out-of-gamut colors are clipped to the destination's gamut,
* which may produce hue skews (blue skewing to purple, green to yellow, etc.). When
* gamut mapping is enabled, out-of-gamut colors are brought back in gamut by trying to
* preserve the perceived chroma and lightness of the original values.
*
* @param gamutMapping Enables or disables gamut mapping
*
* @return This Builder, for chaining calls
*/
public Builder gamutMapping(boolean gamutMapping) {
nBuilderGamutMapping(mNativeBuilder, gamutMapping);
return this;
}
/**
* Adjusts the exposure of this image. The exposure is specified in stops:
* each stop brightens (positive values) or darkens (negative values) the image by
* a factor of 2. This means that an exposure of 3 will brighten the image 8 times
* more than an exposure of 0 (2^3 = 8 and 2^0 = 1). Contrary to the camera's exposure,
* this setting is applied after all post-processing (bloom, etc.) are applied.
*
* @param exposure Value in EV stops. Can be negative, 0, or positive.
*
* @return This Builder, for chaining calls
*/
public Builder exposure(float exposure) {
nBuilderExposure(mNativeBuilder, exposure);
return this;
}
/**
* Controls the amount of night adaptation to replicate a more natural representation of
* low-light conditions as perceived by the human vision system. In low-light conditions,
* peak luminance sensitivity of the eye shifts toward the blue end of the color spectrum:
* darker tones appear brighter, reducing contrast, and colors are blue shifted (the darker
* the more intense the effect).
*
* @param adaptation Amount of adaptation, between 0 (no adaptation) and 1 (full adaptation).
*
* @return This Builder, for chaining calls
*/
public Builder nightAdaptation(float adaptation) {
nBuilderNightAdaptation(mNativeBuilder, adaptation);
return this;
}
/**
* Adjusts the while balance of the image. This can be used to remove color casts
* and correct the appearance of the white point in the scene, or to alter the
@@ -462,7 +557,12 @@ public class ColorGrading {
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderQuality(long nativeBuilder, int quality);
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapper);
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);
private static native void nBuilderGamutMapping(long nativeBuilder, boolean gamutMapping);
private static native void nBuilderExposure(long nativeBuilder, float exposure);
private static native void nBuilderNightAdaptation(long nativeBuilder, float adaptation);
private static native void nBuilderWhiteBalance(long nativeBuilder, float temperature, float tint);
private static native void nBuilderChannelMixer(long nativeBuilder, float[] outRed, float[] outGreen, float[] outBlue);
private static native void nBuilderShadowsMidtonesHighlights(long nativeBuilder, float[] shadows, float[] midtones, float[] highlights, float[] ranges);
@@ -106,10 +106,14 @@ import com.google.android.filament.proguard.UsedByReflection;
* @see Renderer
*/
public class Engine {
private static final Backend[] sBackendValues = Backend.values();
private long mNativeObject;
@NonNull private final TransformManager mTransformManager;
@NonNull private final LightManager mLightManager;
@NonNull private final RenderableManager mRenderableManager;
@NonNull private final EntityManager mEntityManager;
/**
* Denotes a backend
@@ -142,6 +146,7 @@ public class Engine {
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
mLightManager = new LightManager(nGetLightManager(nativeEngine));
mRenderableManager = new RenderableManager(nGetRenderableManager(nativeEngine));
mEntityManager = new EntityManager(nGetEntityManager(nativeEngine));
}
/**
@@ -250,7 +255,7 @@ public class Engine {
*/
@NonNull
public Backend getBackend() {
return Backend.values()[(int) nGetBackend(getNativeObject())];
return sBackendValues[(int) nGetBackend(getNativeObject())];
}
// SwapChain
@@ -397,19 +402,6 @@ public class Engine {
// Camera
/**
* Creates a new <code>entity</code> and adds a {@link Camera} component to it.
*
* @return A newly created {@link Camera}
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
*/
@NonNull
public Camera createCamera() {
long nativeCamera = nCreateCamera(getNativeObject());
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
return new Camera(nativeCamera);
}
/**
* Creates and adds a {@link Camera} component to a given <code>entity</code>.
*
@@ -419,9 +411,9 @@ public class Engine {
*/
@NonNull
public Camera createCamera(@Entity int entity) {
long nativeCamera = nCreateCameraWithEntity(getNativeObject(), entity);
long nativeCamera = nCreateCamera(getNativeObject(), entity);
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
return new Camera(nativeCamera);
return new Camera(nativeCamera, entity);
}
/**
@@ -435,16 +427,16 @@ public class Engine {
public Camera getCameraComponent(@Entity int entity) {
long nativeCamera = nGetCameraComponent(getNativeObject(), entity);
if (nativeCamera == 0) return null;
return new Camera(nativeCamera);
return new Camera(nativeCamera, entity);
}
/**
* Destroys a {@link Camera} component and frees all its associated resources.
* @param camera the {@link Camera} to destroy
* Destroys the {@link Camera} component associated with the given entity.
*
* @param entity an entity
*/
public void destroyCamera(@NonNull Camera camera) {
nDestroyCamera(getNativeObject(), camera.getNativeObject());
camera.clearNativeObject();
public void destroyCameraComponent(@Entity int entity) {
nDestroyCameraComponent(getNativeObject(), entity);
}
// Scene
@@ -524,6 +516,15 @@ public class Engine {
vertexBuffer.clearNativeObject();
}
/**
* Destroys a {@link SkinningBuffer} and frees all its associated resources.
* @param skinningBuffer the {@link SkinningBuffer} to destroy
*/
public void destroySkinningBuffer(@NonNull SkinningBuffer skinningBuffer) {
assertDestroy(nDestroySkinningBuffer(getNativeObject(), skinningBuffer.getNativeObject()));
skinningBuffer.clearNativeObject();
}
/**
* Destroys a {@link IndirectLight} and frees all its associated resources.
* @param ibl the {@link IndirectLight} to destroy
@@ -632,9 +633,17 @@ public class Engine {
return mRenderableManager;
}
/**
* @return the {@link EntityManager} used by this {@link Engine}
*/
@NonNull
public EntityManager getEntityManager() {
return mEntityManager;
}
/**
* Kicks the hardware thread (e.g.: the OpenGL, Vulkan or Metal thread) and blocks until
* all commands to this point are executed. Note that this doesn't guarantee that the
* all commands to this point are executed. Note that this does guarantee that the
* hardware is actually finished.
*
* <p>This is typically used right after destroying the <code>SwapChain</code>,
@@ -683,10 +692,9 @@ public class Engine {
private static native boolean nDestroyView(long nativeEngine, long nativeView);
private static native long nCreateRenderer(long nativeEngine);
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
private static native long nCreateCamera(long nativeEngine);
private static native long nCreateCameraWithEntity(long nativeEngine, int entity);
private static native long nCreateCamera(long nativeEngine, int entity);
private static native long nGetCameraComponent(long nativeEngine, int entity);
private static native void nDestroyCamera(long nativeEngine, long nativeCamera);
private static native void nDestroyCameraComponent(long nativeEngine, int entity);
private static native long nCreateScene(long nativeEngine);
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
private static native long nCreateFence(long nativeEngine);
@@ -694,6 +702,7 @@ public class Engine {
private static native boolean nDestroyStream(long nativeEngine, long nativeStream);
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
@@ -707,4 +716,5 @@ public class Engine {
private static native long nGetLightManager(long nativeEngine);
private static native long nGetRenderableManager(long nativeEngine);
private static native long nGetJobSystem(long nativeEngine);
private static native long nGetEntityManager(long nativeEngine);
}
@@ -31,6 +31,10 @@ public class EntityManager {
private EntityManager() {
}
EntityManager(long nativeEntityManager) {
mNativeObject = nativeEntityManager;
}
@NonNull
public static EntityManager get() {
return Holder.INSTANCE;
@@ -21,8 +21,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import com.google.android.filament.proguard.UsedByReflection;
/**
* <code>IndirectLight</code> is used to simulate environment lighting, a form of global illumination.
*
@@ -86,11 +84,7 @@ import com.google.android.filament.proguard.UsedByReflection;
public class IndirectLight {
long mNativeObject;
public IndirectLight(Engine engine, long indirectLight) {
mNativeObject = indirectLight;
}
IndirectLight(long indirectLight) {
public IndirectLight(long indirectLight) {
mNativeObject = indirectLight;
}
@@ -288,7 +282,7 @@ public class IndirectLight {
* range can be adjusted with this method.</p>
*
* @param envIntensity Scale factor applied to the environment and irradiance such that
* the result is in cd/m^2 (lux) units (default = 30000)
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
*
* @return This Builder, for chaining calls.
*/
@@ -354,14 +348,14 @@ public class IndirectLight {
* range can be adjusted with this method.</p>
*
* @param intensity Scale factor applied to the environment and irradiance such that
* the result is in cd/m^2 units (default = 30000)
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
*/
public void setIntensity(float intensity) {
nSetIntensity(getNativeObject(), intensity);
}
/**
* Returns the environment's intensity in cd/m<sup>2</sup>.
* Returns the environment's intensity in <i>lux</i>, or <i>lumen/m^2</i>.
*/
public float getIntensity() {
return nGetIntensity(getNativeObject());
@@ -430,6 +424,7 @@ public class IndirectLight {
}
/** @deprecated */
@Deprecated
@NonNull @Size(min = 3)
public float[] getDirectionEstimate(@Nullable @Size(min = 3) float[] direction) {
direction = Asserts.assertFloat3(direction);
@@ -472,6 +467,7 @@ public class IndirectLight {
/** @deprecated */
@Deprecated
@NonNull @Size(min = 4)
public float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, float x, float y, float z) {
colorIntensity = Asserts.assertFloat4(colorIntensity);
@@ -117,6 +117,8 @@ import androidx.annotation.Size;
* </ul>
*/
public class LightManager {
private static final Type[] sTypeValues = Type.values();
private long mNativeObject;
LightManager(long nativeLightManager) {
@@ -188,7 +190,7 @@ public class LightManager {
* Control the quality / performance of the shadow map associated to this light
*/
public static class ShadowOptions {
/** Size of the shadow map in texels. Must be a power-of-two. */
/** Size of the shadow map in texels. Must be a power-of-two and larger or equal to 8. */
public int mapSize = 1024;
/**
@@ -242,15 +244,17 @@ public class LightManager {
/** Constant bias in world units (e.g. meters) by which shadows are moved away from the
* light. 1mm by default.
* This is ignored when the View's ShadowType is set to VSM.
*/
public float constantBias = 0.05f;
public float constantBias = 0.001f;
/** Amount by which the maximum sampling error is scaled. The resulting value is used
* to move the shadow away from the fragment normal. Should be 1.0.
* This is ignored when the View's ShadowType is set to VSM.
*/
public float normalBias = 0.4f;
public float normalBias = 1.0f;
/** Distance from the camera after which shadows are clipped. this is used to clip
/** Distance from the camera after which shadows are clipped. This is used to clip
* shadows that are too far and wouldn't contribute to the scene much, improving
* performance and quality. This value is always positive.
* Use 0.0f to use the camera far distance.
@@ -277,7 +281,24 @@ public class LightManager {
* When set to true, all resolution enhancing features that can affect stability are
* disabling, resulting in significantly lower resolution shadows, albeit stable ones.
*/
public boolean stable = true;
public boolean stable = false;
/**
* Constant bias in depth-resolution units by which shadows are moved away from the
* light. The default value of 0.5 is used to round depth values up.
* Generally this value shouldn't be changed or at least be small and positive.
* This is ignored when the View's ShadowType is set to VSM.
*/
float polygonOffsetConstant = 0.5f;
/**
* Bias based on the change in depth in depth-resolution units by which shadows are moved
* away from the light. The default value of 2.0 works well with SHADOW_SAMPLING_PCF_LOW.
* Generally this value is between 0.5 and the size in texel of the PCF filter.
* Setting this value correctly is essential for LISPSM shadow-maps.
* This is ignored when the View's ShadowType is set to VSM.
*/
float polygonOffsetSlope = 2.0f;
/**
* Whether screen-space contact shadows are used. This applies regardless of whether a
@@ -324,6 +345,18 @@ public class LightManager {
*/
@IntRange(from = 1)
public int vsmMsaaSamples = 1;
/**
* Blur width for the VSM blur. Zero do disable.
* The maximum value is 125.
*/
public float blurWidth = 0.0f;
/**
* Light bulb radius used for soft shadows. Currently this is only used when DPCF is
* enabled. (2cm by default).
*/
public float shadowBulbRadius = 0.02f;
}
public static class ShadowCascades {
@@ -422,6 +455,18 @@ public class LightManager {
mFinalizer = new BuilderFinalizer(mNativeBuilder);
}
/**
* Enables or disables a light channel. Light channel 0 is enabled by default.
*
* @param channel Light channel to enable or disable, between 0 and 7.
* @param enable Whether to enable or disable the light channel.
*/
@NonNull
public Builder lightChannel(@IntRange(from = 0, to = 7) int channel, boolean enable) {
nBuilderLightChannel(mNativeBuilder, channel, enable);
return this;
}
/**
* Whether this Light casts shadows (disabled by default)
*
@@ -451,8 +496,11 @@ public class LightManager {
nBuilderShadowOptions(mNativeBuilder,
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
options.shadowFarHint, options.stable, options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples);
options.shadowFarHint, options.stable,
options.polygonOffsetConstant, options.polygonOffsetSlope,
options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
options.blurWidth, options.shadowBulbRadius);
return this;
}
@@ -741,7 +789,7 @@ public class LightManager {
@NonNull
public Type getType(@EntityInstance int i) {
return Type.values()[nGetType(mNativeObject, i)];
return sTypeValues[nGetType(mNativeObject, i)];
}
/**
@@ -776,6 +824,30 @@ public class LightManager {
return type == Type.SPOT || type == Type.FOCUSED_SPOT;
}
/**
* Enables or disables a light channel.
* Light channel 0 is enabled by default.
*
* @param i Instance of the component obtained from getInstance().
* @param channel Light channel to set
* @param enable true to enable, false to disable
*
* @see Builder#lightChannel
*/
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
nSetLightChannel(mNativeObject, i, channel, enable);
}
/**
* Returns whether a light channel is enabled on a specified renderable.
* @param i Instance of the component obtained from getInstance().
* @param channel Light channel to query
* @return true if the light channel is enabled, false otherwise
*/
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
return nGetLightChannel(mNativeObject, i, channel);
}
/**
* Dynamically updates the light's position.
*
@@ -1065,6 +1137,14 @@ public class LightManager {
return nIsShadowCaster(mNativeObject, i);
}
public float getOuterConeAngle(@EntityInstance int i) {
return nGetOuterConeAngle(mNativeObject, i);
}
public float getInnerConeAngle(@EntityInstance int i) {
return nGetInnerConeAngle(mNativeObject, i);
}
public long getNativeObject() {
return mNativeObject;
}
@@ -1078,7 +1158,7 @@ public class LightManager {
private static native void nDestroyBuilder(long nativeBuilder);
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, float polygonOffsetConstant, float polygonOffsetSlope, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth, float shadowBulbRadius);
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
@@ -1091,6 +1171,7 @@ public class LightManager {
private static native void nBuilderAngularRadius(long nativeBuilder, float angularRadius);
private static native void nBuilderHaloSize(long nativeBuilder, float haloSize);
private static native void nBuilderHaloFalloff(long nativeBuilder, float haloFalloff);
private static native void nBuilderLightChannel(long nativeBuilder, int channel, boolean enable);
private static native void nComputeUniformSplits(float[] splitPositions, int cascades);
private static native void nComputeLogSplits(float[] splitPositions, int cascades, float near, float far);
@@ -1118,4 +1199,8 @@ public class LightManager {
private static native float nGetSunHaloFalloff(long nativeLightManager, int i);
private static native void nSetShadowCaster(long nativeLightManager, int i, boolean shadowCaster);
private static native boolean nIsShadowCaster(long nativeLightManager, int i);
private static native float nGetOuterConeAngle(long nativeLightManager, int i);
private static native float nGetInnerConeAngle(long nativeLightManager, int i);
private static native void nSetLightChannel(long nativeLightManager, int i, int channel, boolean enable);
private static native boolean nGetLightChannel(long nativeLightManager, int i, int channel);
}
@@ -37,6 +37,20 @@ import java.util.Set;
* @see <a href="https://google.github.io/filament/Materials.html">Filament Materials Guide</a>
*/
public class Material {
static final class EnumCache {
private EnumCache() { }
static final Shading[] sShadingValues = Shading.values();
static final Interpolation[] sInterpolationValues = Interpolation.values();
static final BlendingMode[] sBlendingModeValues = BlendingMode.values();
static final RefractionMode[] sRefractionModeValues = RefractionMode.values();
static final RefractionType[] sRefractionTypeValues = RefractionType.values();
static final VertexDomain[] sVertexDomainValues = VertexDomain.values();
static final CullingMode[] sCullingModeValues = CullingMode.values();
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
VertexBuffer.VertexAttribute.values();
}
private long mNativeObject;
private final MaterialInstance mDefaultInstance;
@@ -210,6 +224,8 @@ public class Material {
@UsedByNative("Material.cpp")
public static class Parameter {
private static final Type[] sTypeValues = Type.values();
public enum Type {
BOOL,
BOOL2,
@@ -275,11 +291,11 @@ public class Material {
@IntRange(from = 0) int type, @IntRange(from = 0) int precision,
@IntRange(from = 1) int count) {
parameters.add(
new Parameter(name, Type.values()[type], Precision.values()[precision], count));
new Parameter(name, sTypeValues[type], Precision.values()[precision], count));
}
}
Material(long nativeMaterial) {
public Material(long nativeMaterial) {
mNativeObject = nativeMaterial;
long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial);
mDefaultInstance = new MaterialInstance(this, nativeDefaultInstance);
@@ -373,7 +389,7 @@ public class Material {
* Material Models</a>
*/
public Shading getShading() {
return Shading.values()[nGetShading(getNativeObject())];
return EnumCache.sShadingValues[nGetShading(getNativeObject())];
}
/**
@@ -384,7 +400,7 @@ public class Material {
* Vertex and attributes: interpolation</a>
*/
public Interpolation getInterpolation() {
return Interpolation.values()[nGetInterpolation(getNativeObject())];
return EnumCache.sInterpolationValues[nGetInterpolation(getNativeObject())];
}
/**
@@ -395,7 +411,7 @@ public class Material {
* Blending and transparency: blending</a>
*/
public BlendingMode getBlendingMode() {
return BlendingMode.values()[nGetBlendingMode(getNativeObject())];
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
}
/**
@@ -406,7 +422,7 @@ public class Material {
* Blending and transparency: refraction</a>
*/
public RefractionMode getRefractionMode() {
return RefractionMode.values()[nGetRefractionMode(getNativeObject())];
return EnumCache.sRefractionModeValues[nGetRefractionMode(getNativeObject())];
}
/**
@@ -417,10 +433,9 @@ public class Material {
* Blending and transparency: refractionType</a>
*/
public RefractionType getRefractionType() {
return RefractionType.values()[nGetRefractionType(getNativeObject())];
return EnumCache.sRefractionTypeValues[nGetRefractionType(getNativeObject())];
}
/**
* Returns the vertex domain of this material.
*
@@ -429,7 +444,7 @@ public class Material {
* Vertex and attributes: vertexDomain</a>
*/
public VertexDomain getVertexDomain() {
return VertexDomain.values()[nGetVertexDomain(getNativeObject())];
return EnumCache.sVertexDomainValues[nGetVertexDomain(getNativeObject())];
}
/**
@@ -440,7 +455,7 @@ public class Material {
* Rasterization: culling</a>
*/
public CullingMode getCullingMode() {
return CullingMode.values()[nGetCullingMode(getNativeObject())];
return EnumCache.sCullingModeValues[nGetCullingMode(getNativeObject())];
}
/**
@@ -531,7 +546,7 @@ public class Material {
if (mRequiredAttributes == null) {
int bitSet = nGetRequiredAttributes(getNativeObject());
mRequiredAttributes = EnumSet.noneOf(VertexBuffer.VertexAttribute.class);
VertexBuffer.VertexAttribute[] values = VertexBuffer.VertexAttribute.values();
VertexBuffer.VertexAttribute[] values = EnumCache.sVertexAttributeValues;
for (int i = 0; i < values.length; i++) {
if ((bitSet & (1 << i)) != 0) {
mRequiredAttributes.add(values[i]);
@@ -760,7 +775,7 @@ public class Material {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 bool4s:
@@ -768,11 +783,6 @@ public class Material {
* boolean[] a = new boolean[4 * 4];
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* boolean[] a = new boolean[4 * 3];
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
* }</pre>
* </p>
*
* @see Material#getDefaultInstance()
@@ -789,7 +799,7 @@ public class Material {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 int4s:
@@ -797,11 +807,6 @@ public class Material {
* int[] a = new int[4 * 4];
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* int[] a = new int[4 * 3];
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
* }</pre>
* </p>
*
* @see Material#getDefaultInstance()
@@ -818,7 +823,7 @@ public class Material {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 float4s:
@@ -826,11 +831,6 @@ public class Material {
* float[] a = new float[4 * 4];
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* float[] a = new float[4 * 3];
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
* }</pre>
* </p>
*
* @see Material#getDefaultInstance()
@@ -56,6 +56,7 @@ public class MaterialInstance {
MaterialInstance(@NonNull Material material, long nativeMaterialInstance) {
mMaterial = material;
mNativeMaterial = material.getNativeObject();
mNativeObject = nativeMaterialInstance;
}
@@ -64,6 +65,22 @@ public class MaterialInstance {
mNativeMaterial = nGetMaterial(mNativeObject);
}
/**
* Creates a new {@link #MaterialInstance} using another {@link #MaterialInstance} as a template for initialization.
* The new {@link #MaterialInstance} is an instance of the same {@link Material} of the template instance and
* must be destroyed just like any other {@link #MaterialInstance}.
*
* @param other A {@link #MaterialInstance} to use as a template for initializing a new instance
* @param name A name for the new {@link #MaterialInstance} or nullptr to use the template's name
* @return A new {@link #MaterialInstance}
*/
@NonNull
public static MaterialInstance duplicate(@NonNull MaterialInstance other, String name) {
long nativeInstance = nDuplicate(other.mNativeObject, name);
if (nativeInstance == 0) throw new IllegalStateException("Couldn't duplicate MaterialInstance");
return new MaterialInstance(other.getMaterial(), nativeInstance);
}
/** @return the {@link Material} associated with this instance */
@NonNull
public Material getMaterial() {
@@ -238,7 +255,7 @@ public class MaterialInstance {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 bool4s:
@@ -246,11 +263,6 @@ public class MaterialInstance {
* boolean[] a = new boolean[4 * 4];
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* boolean[] a = new boolean[4 * 3];
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
* }</pre>
* </p>
*/
public void setParameter(@NonNull String name,
@@ -265,7 +277,7 @@ public class MaterialInstance {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 int4s:
@@ -273,11 +285,6 @@ public class MaterialInstance {
* int[] a = new int[4 * 4];
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* int[] a = new int[4 * 3];
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
* }</pre>
* </p>
*/
public void setParameter(@NonNull String name,
@@ -292,7 +299,7 @@ public class MaterialInstance {
* @param name name of the parameter array as defined by this Material
* @param type the number of components for each individual parameter
* @param v array of values to set to the named parameter array
* @param offset the number of elements to skip
* @param offset the number of elements in <code>v</code> to skip
* @param count the number of elements in the parameter array to set
*
* <p>For example, to set a parameter array of 4 float4s:
@@ -300,11 +307,6 @@ public class MaterialInstance {
* float[] a = new float[4 * 4];
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
* }</pre>
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
* <pre>{@code
* float[] a = new float[4 * 3];
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
* }</pre>
* </p>
*/
public void setParameter(@NonNull String name,
@@ -452,7 +454,7 @@ public class MaterialInstance {
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorWrite">
* Rasterization: colorWrite</a>
*/
void setColorWrite(boolean enable) {
public void setColorWrite(boolean enable) {
nSetColorWrite(getNativeObject(), enable);
}
@@ -463,7 +465,7 @@ public class MaterialInstance {
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthWrite">
* Rasterization: depthWrite</a>
*/
void setDepthWrite(boolean enable) {
public void setDepthWrite(boolean enable) {
nSetDepthWrite(getNativeObject(), enable);
}
@@ -474,7 +476,7 @@ public class MaterialInstance {
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthCulling">
* Rasterization: depthCulling</a>
*/
void setDepthCulling(boolean enable) {
public void setDepthCulling(boolean enable) {
nSetDepthCulling(getNativeObject(), enable);
}
@@ -554,4 +556,6 @@ public class MaterialInstance {
private static native String nGetName(long nativeMaterialInstance);
private static native long nGetMaterial(long nativeMaterialInstance);
private static native long nDuplicate(long otherNativeMaterialInstance, String name);
}
@@ -31,13 +31,15 @@ import androidx.annotation.Nullable;
* @see View
*/
public class RenderTarget {
private static final int ATTACHMENT_COUNT = AttachmentPoint.values().length;
private static final Texture.CubemapFace[] sCubemapFaceValues = Texture.CubemapFace.values();
private long mNativeObject;
private final Texture[] mTextures = new Texture[2];
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
private RenderTarget(long nativeRenderTarget, Builder builder) {
mNativeObject = nativeRenderTarget;
mTextures[0] = builder.mTextures[0];
mTextures[1] = builder.mTextures[1];
System.arraycopy(builder.mTextures, 0, mTextures, 0, ATTACHMENT_COUNT);
}
public long getNativeObject() {
@@ -52,7 +54,14 @@ public class RenderTarget {
*/
public enum AttachmentPoint {
COLOR,
DEPTH,
COLOR1,
COLOR2,
COLOR3,
COLOR4,
COLOR5,
COLOR6,
COLOR7,
DEPTH
}
/**
@@ -62,7 +71,7 @@ public class RenderTarget {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
private final BuilderFinalizer mFinalizer;
private final long mNativeBuilder;
private final Texture[] mTextures = new Texture[2];
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
public Builder() {
mNativeBuilder = nCreateBuilder();
@@ -187,7 +196,7 @@ public class RenderTarget {
* a cubemap.
*/
public Texture.CubemapFace getFace(AttachmentPoint attachment) {
return Texture.CubemapFace.values()[nGetFace(getNativeObject(), attachment.ordinal())];
return sCubemapFaceValues[nGetFace(getNativeObject(), attachment.ordinal())];
}
/**
@@ -107,12 +107,12 @@ public class Renderer {
/**
* Rate at which the scale will change to reach the target frame rate.
*/
public float scaleRate = 0.125f;
public float scaleRate = 1.0f / 15.0f;
/**
* History size. higher values, tend to filter more (clamped to 30).
* History size. higher values, tend to filter more (clamped to 31).
*/
public int history = 9;
public int history = 15;
}
/**
@@ -309,13 +309,13 @@ public class Renderer {
*
* <p><code>render()</code> generates commands for each of the following stages:</p>
* <ul>
* <li>Shadow map pass, if needed (currently only a single shadow map is supported)</li>
* <li>Shadow map passes, if needed</li>
* <li>Depth pre-pass</li>
* <li>SSAO pass, if enabled</li>
* <li>Color pass</li>
* <li>Post-processing pass</li>
* </ul>
*
* <p>
* A typical render loop looks like this:
*
* <pre>
@@ -331,31 +331,58 @@ public class Renderer {
* </pre>
*
* <ul>
*<li><code>render()</code> must be called <b>after</b> {@link #beginFrame} and <b>before</b>
*{@link #endFrame}.</li>
* <li><code>render()</code> must be called <b>after</b> {@link #beginFrame} and <b>before</b>
* {@link #endFrame}.</li>
*
*<li><code>render()</code> must be called from the {@link Engine}'s main thread
*(or external synchronization must be provided). In particular, calls to <code>render()</code>
*on different <code>Renderer</code> instances <b>must</b> be synchronized.</li>
* <li><code>render()</code> must be called from the {@link Engine}'s main thread
* (or external synchronization must be provided). In particular, calls to <code>render()</code>
* on different <code>Renderer</code> instances <b>must</b> be synchronized.</li>
*
*<li><code>render()</code> performs potentially heavy computations and cannot be multi-threaded.
*However, internally, it is highly multi-threaded to both improve performance and mitigate
*the call's latency.</li>
* <li><code>render()</code> performs potentially heavy computations and cannot be multi-threaded.
* However, internally, it is highly multi-threaded to both improve performance and mitigate
* the call's latency.</li>
*
*<li><code>render()</code> is typically called once per frame (but not necessarily).</li>
* <li><code>render()</code> is typically called once per frame (but not necessarily).</li>
* </ul>
*
* @param view the {@link View} to render
*
* @see #beginFrame
* @see #endFrame
* @see View
*
*/
public void render(@NonNull View view) {
nRender(getNativeObject(), view.getNativeObject());
}
/**
* Renders a standalone {@link View} into its associated <code>RenderTarget</code>.
*
* <p>
* This call is mostly equivalent to calling {@link #render(View)} inside a
* {@link #beginFrame} / {@link #endFrame} block, but incurs less overhead. It can be used
* as a poor man's compute API.
* </p>
*
* <ul>
* <li><code>renderStandaloneView()</code> must be called <b>outside</b> of
* {@link #beginFrame} / {@link #endFrame}.</li>
*
* <li><code>renderStandaloneView()</code> must be called from the {@link Engine}'s main thread
* (or external synchronization must be provided). In particular, calls to
* <code>renderStandaloneView()</code> on different <code>Renderer</code> instances <b>must</b>
* be synchronized.</li>
*
* <li><code>renderStandaloneView()</code> performs potentially heavy computations and cannot be
* multi-threaded. However, internally, it is highly multi-threaded to both improve performance
* and mitigate the call's latency.</li>
*
* @param view the {@link View} to render. This View must have an associated {@link RenderTarget}
* @see View
*/
public void renderStandaloneView(@NonNull View view) {
nRenderStandaloneView(getNativeObject(), view.getNativeObject());
}
/**
* Copies the currently rendered {@link View} to the indicated {@link SwapChain}, using the
* indicated source and destination rectangle.
@@ -410,8 +437,9 @@ public class Renderer {
*</pre>
*
*
* <p>Typically <code>readPixels</code> will be called after {@link #render} and before
* {@link #endFrame}.</p>
* <p><code>readPixels</code> must be called within a frame, meaning after {@link #beginFrame}
* and before {@link #endFrame}. Typically, <code>readPixels</code> will be called after
* {@link #render}.</p>
* <br>
* <p>After calling this method, the callback associated with <code>buffer</code>
* will be invoked on the main thread, indicating that the read-back has completed.
@@ -635,6 +663,7 @@ public class Renderer {
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
private static native void nEndFrame(long nativeRenderer);
private static native void nRender(long nativeRenderer, long nativeView);
private static native void nRenderStandaloneView(long nativeRenderer, long nativeView);
private static native void nCopyFrame(long nativeRenderer, long nativeDstSwapChain,
int dstLeft, int dstBottom, int dstWidth, int dstHeight,
int srcLeft, int srcBottom, int srcWidth, int srcHeight,
@@ -128,6 +128,7 @@ public class Scene {
/**
* @deprecated See {@link #removeEntity(int)}
*/
@Deprecated
public void remove(@Entity int entity) {
removeEntity(entity);
}
@@ -0,0 +1,177 @@
/*
* 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.
*/
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 SkinningBuffer {
private long mNativeObject;
private SkinningBuffer(long nativeSkinningBuffer) {
mNativeObject = nativeSkinningBuffer;
}
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
private final SkinningBuffer.Builder.BuilderFinalizer mFinalizer;
private final long mNativeBuilder;
public Builder() {
mNativeBuilder = nCreateBuilder();
mFinalizer = new SkinningBuffer.Builder.BuilderFinalizer(mNativeBuilder);
}
/**
* Size of the skinning buffer in bones.
*
* <p>Due to limitation in the GLSL, the SkinningBuffer must always by a multiple of
* 256, this adjustment is done automatically, but can cause
* some memory overhead. This memory overhead can be mitigated by using the same
* {@link SkinningBuffer} to store the bone information for multiple RenderPrimitives.</p>
*
* @param boneCount Number of bones the skinning buffer can hold.
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder boneCount(@IntRange(from = 1) int boneCount) {
nBuilderBoneCount(mNativeBuilder, boneCount);
return this;
}
/**
* The new buffer is created with identity bones
*
* @param initialize true to initializing the buffer, false to not.
* @return A reference to this Builder for chaining calls.
*/
@NonNull
public Builder initialize(boolean initialize) {
nBuilderInitialize(mNativeBuilder, initialize);
return this;
}
/**
* Creates and returns the <code>SkinningBuffer</code> object.
*
* @param engine reference to the {@link Engine} to associate this <code>SkinningBuffer</code>
* with.
*
* @return the newly created <code>SkinningBuffer</code> object
*
* @exception IllegalStateException if the SkinningBuffer could not be created
*
* @see #setBonesAsMatrices
* @see #setBonesAsQuaternions
*/
@NonNull
public SkinningBuffer build(@NonNull Engine engine) {
long nativeSkinningBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
if (nativeSkinningBuffer == 0)
throw new IllegalStateException("Couldn't create SkinningBuffer");
return new SkinningBuffer(nativeSkinningBuffer);
}
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 the bone transforms in the range [offset, offset + boneCount).
*
* @param engine {@link Engine} instance
* @param matrices A {@link FloatBuffer} containing boneCount 4x4 packed matrices (i.e. 16 floats each matrix and no gap between matrices)
* @param boneCount Number of bones to set
* @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) {
int result = nSetBonesAsMatrices(mNativeObject, engine.getNativeObject(),
matrices, matrices.remaining(), boneCount, offset);
if (result < 0) {
throw new BufferOverflowException();
}
}
/**
* Updates the bone transforms in the range [offset, offset + boneCount).
*
* @param engine {@link Engine} instance
* @param quaternions A {@link FloatBuffer} containing boneCount transforms. Each transform consists of 8 float.
* float 0 to 3 encode a unit quaternion <code>w+ix+jy+kz</code> stored as <code>x,y,z,w</code>.
* float 4 to 7 encode a translation stored as <code>x,y,z,1</code>.
* @param boneCount Number of bones to set
* @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) {
int result = nSetBonesAsQuaternions(mNativeObject, engine.getNativeObject(),
quaternions, quaternions.remaining(), boneCount, offset);
if (result < 0) {
throw new BufferOverflowException();
}
}
/**
* @return number of bones in this {@link SkinningBuffer}
*/
public int getBoneCount() {
return nGetBoneCount(mNativeObject);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IndexBuffer");
}
return mNativeObject;
}
void clearNativeObject() {
mNativeObject = 0;
}
private static native long nCreateBuilder();
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderBoneCount(long nativeBuilder, int boneCount);
private static native void nBuilderInitialize(long nativeBuilder, boolean initialize);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nSetBonesAsMatrices(long nativeObject, long nativeEngine, Buffer matrices, int remaining, int boneCount, int offset);
private static native int nSetBonesAsQuaternions(long nativeObject, long nativeEngine, Buffer quaternions, int remaining, int boneCount, int offset);
private static native int nGetBoneCount(long nativeObject);
}
@@ -23,8 +23,6 @@ import androidx.annotation.Size;
import static com.google.android.filament.Colors.LinearColor;
import com.google.android.filament.proguard.UsedByReflection;
/**
* Skybox
* <p>When added to a {@link Scene}, the <code>Skybox</code> fills all untouched pixels.</p>
@@ -53,11 +51,7 @@ import com.google.android.filament.proguard.UsedByReflection;
public class Skybox {
private long mNativeObject;
public Skybox(Engine engine, long nativeSkybox) {
mNativeObject = nativeSkybox;
}
Skybox(long nativeSkybox) {
public Skybox(long nativeSkybox) {
mNativeObject = nativeSkybox;
}
@@ -115,13 +109,14 @@ public class Skybox {
}
/**
* Sets the <code>Skybox</code> intensity when no {@link IndirectLight} is set
* Sets the <code>Skybox</code> intensity when no {@link IndirectLight} is set on the
* {@link Scene}.
*
* <p>This call is ignored when an {@link IndirectLight} is set, otherwise it is used in
* its place.</p>
* <p>This call is ignored when an {@link IndirectLight} is set on the {@link Scene}, and
* the intensity of the {@link IndirectLight} is used instead.</p>
*
* @param envIntensity Scale factor applied to the skybox texel values such that
* the result is in cd/m<sup>2</sup> (lux) units (default = 30000)
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
*
* @return This Builder, for chaining calls.
*
@@ -237,7 +232,7 @@ public class Skybox {
}
/**
* Returns the <code>Skybox</code>'s intensity in cd/m<sup>2</sup>.
* Returns the <code>Skybox</code>'s intensity in <i>lux</i>, or <i>lumen/m^2</i>.
*/
public float getIntensity() { return nGetIntensity(getNativeObject()); }
@@ -26,10 +26,73 @@ import java.nio.ReadOnlyBufferException;
/**
* <code>Stream</code> is used to attach a native video stream to a filament {@link Texture}.
*
* Stream supports three different configurations:
*
* <dl>
* <dt>TEXTURE_ID</dt> <dd>takes an OpenGL texture ID and incurs a copy</dd>
* <dt>ACQUIRED</dt> <dd>connects to an Android AHardwareBuffer</dd>
* <dt>NATIVE</dt> <dd>connects to an Android SurfaceTexture</dd>
* </dl>
*
* <p>
* Before explaining these different configurations, let's review the high-level structure of an
* AR or video application that uses Filament.
* </p>
*
* <pre>
* while (true) {
*
* // Misc application work occurs here, such as:
* // - Writing the image data for a video frame into a Stream
* // - Moving the Filament Camera
*
* if (renderer.beginFrame(swapChain)) {
* renderer.render(view);
* renderer.endFrame();
* }
* }
* </pre>
*
* <p>
* Let's say that the video image data at the time of a particular invocation of beginFrame
* becomes visible to users at time A. The 3D scene state (including the camera) at the time of
* that same invocation becomes apparent to users at time B.
* </p>
*
* <ul>
* <li>If time A matches time B, we say that the stream is <em>synchronized</em>.</li>
* <li>Filament invokes low-level graphics commands on the <em>driver thread</em>.</li>
* <li>The thread that calls beginFrame is called the <em>main thread</em>.</li>
* </ul>
*
* <p>
* The <b>TEXTURE_ID</b> configuration achieves synchronization automatically. In this mode,
* Filament performs a copy on the main thread during beginFrame by blitting the external image into
* an internal round-robin queue of images. This copy has a run-time cost.
* </p>
*
* <p>
* For <b>ACQUIRED</b> streams, there is no need to perform the copy because Filament explictly
* acquires the stream, then releases it later via a callback function. This configuration is
* especially useful when the Vulkan backend is enabled.
* </p>
*
* <p>
* For <b>NATIVE</b> streams, Filament does not make any synchronization guarantee. However they are
* simple to use and do not incur a copy. These are often appropriate in video applications.
* </p>
*
* <p>
* Please see <code>sample-stream-test</code> and <code>sample-hello-camera</code> for usage
* examples.
* </p>
*
* @see Texture#setExternalStream
* @see Engine#destroyStream
*/
public class Stream {
private static final StreamType[] sStreamTypeValues = StreamType.values();
private long mNativeObject;
private long mNativeEngine;
@@ -105,7 +168,9 @@ public class Stream {
* <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);
@@ -173,14 +238,23 @@ public class Stream {
* Indicates whether this <code>Stream</code> is NATIVE, TEXTURE_ID, or ACQUIRED.
*/
public StreamType getStreamType() {
return StreamType.values()[nGetStreamType(getNativeObject())];
return sStreamTypeValues[nGetStreamType(getNativeObject())];
}
/**
* Updates an <pre>ACQUIRED</pre> stream with an image that is guaranteed to be used in the next frame.
*
* This method should be called on the same thread that calls {#link Renderer#beginFrame}, which is
* also where the callback is invoked.
* This method tells Filament to immediately "acquire" the image and trigger a callback
* when it is done with it. This should be called by the user outside of beginFrame / endFrame,
* and should be called only once per frame. If the user pushes images to the same stream
* multiple times in a single frame, only the final image is honored, but all callbacks are
* invoked.
*
* This method should be called on the same thread that calls {@link Renderer#beginFrame}, which is
* also where the callback is invoked. This method can only be used for streams that were
* constructed without calling the {@link Builder.stream} method.
*
* See {@link Stream} for more information about NATIVE, TEXTURE_ID, and ACQUIRED configurations.
*
* @param hwbuffer {@link android.hardware.HardwareBuffer HardwareBuffer} (requires API level 26)
* @param handler {@link java.util.concurrent.Executor Executor} or {@link android.os.Handler Handler}.
@@ -71,13 +71,12 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
*/
public class Texture {
private static final Sampler[] sSamplerValues = Sampler.values();
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
private long mNativeObject;
Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
public Texture(Engine engine, long nativeTexture) {
public Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
@@ -220,7 +219,38 @@ public class Texture {
ETC2_EAC_RGBA8, ETC2_EAC_SRGBA8,
// Available everywhere except Android/iOS
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
// ASTC formats are available with a GLES extension
RGBA_ASTC_4x4,
RGBA_ASTC_5x4,
RGBA_ASTC_5x5,
RGBA_ASTC_6x5,
RGBA_ASTC_6x6,
RGBA_ASTC_8x5,
RGBA_ASTC_8x6,
RGBA_ASTC_8x8,
RGBA_ASTC_10x5,
RGBA_ASTC_10x6,
RGBA_ASTC_10x8,
RGBA_ASTC_10x10,
RGBA_ASTC_12x10,
RGBA_ASTC_12x12,
SRGB8_ALPHA8_ASTC_4x4,
SRGB8_ALPHA8_ASTC_5x4,
SRGB8_ALPHA8_ASTC_5x5,
SRGB8_ALPHA8_ASTC_6x5,
SRGB8_ALPHA8_ASTC_6x6,
SRGB8_ALPHA8_ASTC_8x5,
SRGB8_ALPHA8_ASTC_8x6,
SRGB8_ALPHA8_ASTC_8x8,
SRGB8_ALPHA8_ASTC_10x5,
SRGB8_ALPHA8_ASTC_10x6,
SRGB8_ALPHA8_ASTC_10x8,
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12
}
/**
@@ -235,7 +265,38 @@ public class Texture {
ETC2_EAC_RGBA8, ETC2_EAC_SRGBA8,
// Available everywhere except Android/iOS
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
// ASTC formats are available with a GLES extension
RGBA_ASTC_4x4,
RGBA_ASTC_5x4,
RGBA_ASTC_5x5,
RGBA_ASTC_6x5,
RGBA_ASTC_6x6,
RGBA_ASTC_8x5,
RGBA_ASTC_8x6,
RGBA_ASTC_8x8,
RGBA_ASTC_10x5,
RGBA_ASTC_10x6,
RGBA_ASTC_10x8,
RGBA_ASTC_10x10,
RGBA_ASTC_12x10,
RGBA_ASTC_12x12,
SRGB8_ALPHA8_ASTC_4x4,
SRGB8_ALPHA8_ASTC_5x4,
SRGB8_ALPHA8_ASTC_5x5,
SRGB8_ALPHA8_ASTC_6x5,
SRGB8_ALPHA8_ASTC_6x6,
SRGB8_ALPHA8_ASTC_8x5,
SRGB8_ALPHA8_ASTC_8x6,
SRGB8_ALPHA8_ASTC_8x8,
SRGB8_ALPHA8_ASTC_10x5,
SRGB8_ALPHA8_ASTC_10x6,
SRGB8_ALPHA8_ASTC_10x8,
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12
}
/**
@@ -509,12 +570,15 @@ public class Texture {
case RGBA_INTEGER:
n = 4;
break;
default: throw new IllegalStateException("unsupported format enum");
}
int bpp = n;
switch (type) {
case UBYTE:
case BYTE:
case COMPRESSED:
// nothing to do
break;
case USHORT:
@@ -531,6 +595,9 @@ public class Texture {
// Special case, format must be RGB and uses 4 bytes
bpp = 4;
break;
case USHORT_565:
bpp = 2;
break;
}
int bpr = bpp * stride;
@@ -562,6 +629,17 @@ public class Texture {
return nIsTextureFormatSupported(engine.getNativeObject(), format.ordinal());
}
/**
* Checks whether texture swizzling is supported in this {@link Engine}.
* This depends on the selected backend.
*
* @param engine {@link Engine}
* @return <code>true</code> if texture swizzling.
*/
public static boolean isTextureSwizzleSupported(@NonNull Engine engine) {
return nIsTextureSwizzleSupported(engine.getNativeObject());
}
/**
* Use <code>Builder</code> to construct a <code>Texture</code> object instance.
*/
@@ -678,6 +756,26 @@ public class Texture {
return this;
}
/**
* Specify a native texture to import as a Filament texture.
* <p>
* The texture id is backend-specific:
* <ul>
* <li> OpenGL: GLuint texture ID </li>
* </ul>
* </p>
*
*
* @param id a backend specific texture identifier
*
* @return This Builder, for chaining calls.
*/
@NonNull
public Builder importTexture(long id) {
nBuilderImportTexture(mNativeBuilder, id);
return this;
}
/**
* Creates a new <code>Texture</code> instance.
* @param engine The {@link Engine} to associate this <code>Texture</code> with.
@@ -772,7 +870,7 @@ public class Texture {
*/
@NonNull
public Sampler getTarget() {
return Sampler.values()[nGetTarget(getNativeObject())];
return sSamplerValues[nGetTarget(getNativeObject())];
}
/**
@@ -780,7 +878,7 @@ public class Texture {
*/
@NonNull
public InternalFormat getFormat() {
return InternalFormat.values()[nGetInternalFormat(getNativeObject())];
return sInternalFormatValues[nGetInternalFormat(getNativeObject())];
}
// TODO: add a setImage() version that takes an android Bitmap
@@ -882,7 +980,7 @@ public class Texture {
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
* @param xoffset x-offset in texel of the region to modify
* @param yoffset y-offset in texel of the region to modify
* @param yoffset z-offset in texel of the region to modify
* @param zoffset z-offset in texel of the region to modify
* @param width width in texel of the region to modify
* @param height height in texel of the region to modify
* @param depth depth in texel or index of the region to modify
@@ -1137,6 +1235,7 @@ public class Texture {
}
private static native boolean nIsTextureFormatSupported(long nativeEngine, int internalFormat);
private static native boolean nIsTextureSwizzleSupported(long nativeEngine);
private static native long nCreateBuilder();
private static native void nDestroyBuilder(long nativeBuilder);
@@ -1149,6 +1248,7 @@ public class Texture {
private static native void nBuilderFormat(long nativeBuilder, int format);
private static native void nBuilderUsage(long nativeBuilder, int flags);
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
private static native void nBuilderImportTexture(long nativeBuilder, long id);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetWidth(long nativeTexture, int level);
@@ -1160,35 +1260,35 @@ public class Texture {
private static native int nSetImage(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int stride, int format,
Object handler, Runnable callback);
private static native int nSetImageCompressed(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int compressedSizeInBytes, int compressedFormat,
Object handler, Runnable callback);
private static native int nSetImage3D(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int stride, int format,
Object handler, Runnable callback);
private static native int nSetImage3DCompressed(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int compressedSizeInBytes, int compressedFormat,
Object handler, Runnable callback);
private static native int nSetImageCubemap(long nativeTexture, long nativeEngine,
int level, Buffer storage, int remaining, int left, int bottom, int type,
int level, Buffer storage, int remaining, int left, int top, int type,
int alignment, int stride, int format,
int[] faceOffsetsInBytes, Object handler, Runnable callback);
private static native int nSetImageCubemapCompressed(long nativeTexture, long nativeEngine,
int level, Buffer storage, int remaining, int left, int bottom, int type,
int level, Buffer storage, int remaining, int left, int top, int type,
int alignment, int compressedSizeInBytes, int compressedFormat,
int[] faceOffsetsInBytes, Object handler, Runnable callback);
@@ -22,6 +22,14 @@ import androidx.annotation.NonNull;
* <code>TextureSampler</code> defines how a texture is accessed.
*/
public class TextureSampler {
static final class EnumCache {
static final MinFilter[] sMinFilterValues = MinFilter.values();
static final MagFilter[] sMagFilterValues = MagFilter.values();
static final WrapMode[] sWrapModeValues = WrapMode.values();
static final CompareMode[] sCompareModeValues = CompareMode.values();
static final CompareFunction[] sCompareFunctionValues = CompareFunction.values();
}
public enum WrapMode {
/**
* The edge of the texture extends to infinity.
@@ -202,7 +210,7 @@ public class TextureSampler {
* @return the minification filter
*/
public MinFilter getMinFilter() {
return MinFilter.values()[nGetMinFilter(mSampler)];
return EnumCache.sMinFilterValues[nGetMinFilter(mSampler)];
}
/**
@@ -218,7 +226,7 @@ public class TextureSampler {
* @return the magnification filter
*/
public MagFilter getMagFilter() {
return MagFilter.values()[nGetMagFilter(mSampler)];
return EnumCache.sMagFilterValues[nGetMagFilter(mSampler)];
}
/**
@@ -234,7 +242,7 @@ public class TextureSampler {
* @return the wrapping mode in the s (horizontal) direction
*/
public WrapMode getWrapModeS() {
return WrapMode.values()[nGetWrapModeS(mSampler)];
return EnumCache.sWrapModeValues[nGetWrapModeS(mSampler)];
}
/**
@@ -249,7 +257,7 @@ public class TextureSampler {
* @return the wrapping mode in the t (vertical) direction
*/
public WrapMode getWrapModeT() {
return WrapMode.values()[nGetWrapModeT(mSampler)];
return EnumCache.sWrapModeValues[nGetWrapModeT(mSampler)];
}
/**
@@ -264,7 +272,7 @@ public class TextureSampler {
* @return the wrapping mode in the r (depth) direction
*/
public WrapMode getWrapModeR() {
return WrapMode.values()[nGetWrapModeR(mSampler)];
return EnumCache.sWrapModeValues[nGetWrapModeR(mSampler)];
}
/**
@@ -297,7 +305,7 @@ public class TextureSampler {
* @return the comparison mode
*/
public CompareMode getCompareMode() {
return CompareMode.values()[nGetCompareMode(mSampler)];
return EnumCache.sCompareModeValues[nGetCompareMode(mSampler)];
}
/**
@@ -313,7 +321,7 @@ public class TextureSampler {
* @return the comparison function
*/
public CompareFunction getCompareFunction() {
return CompareFunction.values()[nGetCompareFunction(mSampler)];
return EnumCache.sCompareFunctionValues[nGetCompareFunction(mSampler)];
}
/**
@@ -0,0 +1,210 @@
package com.google.android.filament;
/**
* Interface for tone mapping operators. A tone mapping operator, or tone mapper,
* is responsible for compressing the dynamic range of the rendered scene to a
* dynamic range suitable for display.
*
* In Filament, tone mapping is a color grading step. ToneMapper instances are
* created and passed to the ColorGrading::Builder to produce a 3D LUT that will
* be used during post-processing to prepare the final color buffer for display.
*
* Filament provides several default tone mapping operators that fall into three
* categories:
*
* <ul>
* <li>Configurable tone mapping operators</li>
* <ul>
* <li>GenericToneMapper</li>
* </ul>
* <li>Fixed-aesthetic tone mapping operators</li>
* <ul>
* <li>ACESToneMapper</li>
* <li>ACESLegacyToneMapper</li>
* <li>FilmicToneMapper</li>
* </ul>
* <li>Debug/validation tone mapping operators</li>
* <ul>
* <li>LinearToneMapper</li>
* <li>DisplayRangeToneMapper</li>
* </ul>
* </ul>
*
* You can create custom tone mapping operators by subclassing ToneMapper.
*/
public class ToneMapper {
private final long mNativeObject;
private ToneMapper(long nativeObject) {
mNativeObject = nativeObject;
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed ToneMapper");
}
return mNativeObject;
}
@Override
protected void finalize() throws Throwable {
try {
super.finalize();
} finally {
nDestroyToneMapper(mNativeObject);
}
}
/**
* Linear tone mapping operator that returns the input color but clamped to
* the 0..1 range. This operator is mostly useful for debugging.
*/
public static class Linear extends ToneMapper {
public Linear() {
super(nCreateLinearToneMapper());
}
}
/**
* ACES tone mapping operator. This operator is an implementation of the
* ACES Reference Rendering Transform (RRT) combined with the Output Device
* Transform (ODT) for sRGB monitors (dim surround, 100 nits).
*/
public static class ACES extends ToneMapper {
public ACES() {
super(nCreateACESToneMapper());
}
}
/**
* ACES tone mapping operator, modified to match the perceived brightness
* of FilmicToneMapper. This operator is the same as ACESToneMapper but
* applies a brightness multiplier of ~1.6 to the input color value to
* target brighter viewing environments.
*/
public static class ACESLegacy extends ToneMapper {
public ACESLegacy() {
super(nCreateACESLegacyToneMapper());
}
}
/**
* "Filmic" tone mapping operator. This tone mapper was designed to
* approximate the aesthetics of the ACES RRT + ODT for Rec.709
* and historically Filament's default tone mapping operator. It exists
* only for backward compatibility purposes and is not otherwise recommended.
*/
public static class Filmic extends ToneMapper {
public Filmic() {
super(nCreateFilmicToneMapper());
}
}
/**
* Generic tone mapping operator that gives control over the tone mapping
* curve. This operator can be used to control the aesthetics of the final
* image. This operator also allows to control the dynamic range of the
* scene referred values.
*
* The tone mapping curve is defined by 5 parameters:
* <ul>
* <li>contrast: controls the contrast of the curve</li>
* referred values map to output white</li>
* <li>midGrayIn: sets the input middle gray</li>
* <li>midGrayOut: sets the output middle gray</li>
* <li>hdrMax: defines the maximum input value that will be mapped to
* output white</li>
* </ul>
*/
public static class Generic extends ToneMapper {
/**
* Builds a new generic tone mapper parameterized to closely approximate
* the {@link ACESLegacy} tone mapper. The default values are:
*
* <ul>
* <li>contrast = 1.55f</li>
* <li>midGrayIn = 0.18f</li>
* <li>midGrayOut = 0.215f</li>
* <li>hdrMax = 10.0f</li>
* </ul>
*/
public Generic() {
this(1.55f, 0.18f, 0.215f, 10.0f);
}
/**
* Builds a new generic tone mapper.
*
* @param contrast: controls the contrast of the curve, must be > 0.0, values
* in the range 0.5..2.0 are recommended.
* @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 midGrayIn, float midGrayOut, float hdrMax) {
super(nCreateGenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax));
}
/** Returns the contrast of the curve as a strictly positive value. */
public float getContrast() {
return nGenericGetContrast(getNativeObject());
}
/** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */
public void setContrast(float contrast) {
nGenericSetContrast(getNativeObject(), contrast);
}
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
public float getMidGrayIn() {
return nGenericGetMidGrayIn(getNativeObject());
}
/** Sets the input middle gray, between 0.0 and 1.0. */
public void setMidGrayIn(float midGrayIn) {
nGenericSetMidGrayIn(getNativeObject(), midGrayIn);
}
/** Returns the middle gray point for output values as a value between 0.0 and 1.0. */
public float getMidGrayOut() {
return nGenericGetMidGrayOut(getNativeObject());
}
/** Sets the output middle gray, between 0.0 and 1.0. */
public void setMidGrayOut(float midGrayOut) {
nGenericSetMidGrayOut(getNativeObject(), midGrayOut);
}
/** Returns the maximum input value that will map to output white, as a value >= 1.0. */
public float getHdrMax() {
return nGenericGetHdrMax(getNativeObject());
}
/** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */
public void setHdrMax(float hdrMax) {
nGenericSetHdrMax(getNativeObject(), hdrMax);
}
}
private static native void nDestroyToneMapper(long nativeObject);
private static native long nCreateLinearToneMapper();
private static native long nCreateACESToneMapper();
private static native long nCreateACESLegacyToneMapper();
private static native long nCreateFilmicToneMapper();
private static native long nCreateGenericToneMapper(
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
// Generic tone mappper
private static native float nGenericGetContrast(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 nGenericSetMidGrayIn(long nativeObject, float midGrayIn);
private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut);
private static native void nGenericSetHdrMax(long nativeObject, float hdrMax);
}
@@ -83,6 +83,35 @@ import androidx.annotation.Size;
return nGetInstance(mNativeObject, entity);
}
/**
* Enables or disable the accurate translation mode. Disabled by default.
*
* When accurate translation mode is active, the translation component of all transforms is
* maintained at double precision. This is only useful if the mat4 version of setTransform()
* is used, as well as getTransformAccurate().
*
* @param enable true to enable the accurate translation mode, false to disable.
*
* @see #isAccurateTranslationsEnabled
* @see #create(int, int, double[])
* @see #setTransform(int, double[])
* @see #getTransform(int, double[])
* @see #getWorldTransform(int, double[])
*/
public void setAccurateTranslationsEnabled(boolean enable) {
nSetAccurateTranslationsEnabled(mNativeObject, enable);
}
/**
* Returns whether the high precision translation mode is active.
*
* @return true if accurate translations mode is active, false otherwise
* @see #setAccurateTranslationsEnabled
*/
public boolean isAccurateTranslationsEnabled() {
return nIsAccurateTranslationsEnabled(mNativeObject);
}
/**
* Creates a transform component and associates it with the given entity. The component is
* initialized with the identity transform.
@@ -114,6 +143,23 @@ import androidx.annotation.Size;
return nCreateArray(mNativeObject, entity, parent, localTransform);
}
/**
* Creates a transform component with a parent and associates it with the given entity.
* If this component already exists on the given entity, it is first
* destroyed as if {@link #destroy} was called.
*
* @param entity an {@link Entity} to associate a transform component to.
* @param parent the {@link EntityInstance} of the parent transform
* @param localTransform the transform, relative to the parent, to initialize the transform
* component with.
* @see #destroy
*/
@EntityInstance
public int create(@Entity int entity, @EntityInstance int parent,
@Nullable @Size(min = 16) double[] localTransform) {
return nCreateArrayFp64(mNativeObject, entity, parent, localTransform);
}
/**
* Destroys this component from the given entity, children are orphaned.
*
@@ -140,6 +186,19 @@ import androidx.annotation.Size;
nSetParent(mNativeObject, i, newParent);
}
/**
* Returns the actual parent entity of an {@link EntityInstance} originally defined
* by {@link #setParent(int, int)}.
*
* @param i the {@link EntityInstance} of the transform component to get the parent from.
* @return the parent {@link Entity}.
* @see #getInstance
*/
@Entity
public int getParent(@EntityInstance int i) {
return nGetParent(mNativeObject, i);
}
/**
* Sets a local transform of a transform component.
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
@@ -157,6 +216,24 @@ import androidx.annotation.Size;
nSetTransform(mNativeObject, i, localTransform);
}
/**
* Sets a local transform of a transform component.
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
* will be particularly bad when updating a lot of transforms. In that case,
* consider using {@link #openLocalTransformTransaction} / {@link #commitLocalTransformTransaction}.</p>
*
* @param i the {@link EntityInstance} of the transform component to set the local
* transform to.
* @param localTransform the local transform (i.e. relative to the parent).
* @see #getTransform(int, double[])
* @see #getWorldTransform(int, double[])
*/
public void setTransform(@EntityInstance int i,
@NonNull @Size(min = 16) double[] localTransform) {
Asserts.assertMat4In(localTransform);
nSetTransformFp64(mNativeObject, i, localTransform);
}
/**
* Returns the local transform of a transform component.
*
@@ -177,6 +254,26 @@ import androidx.annotation.Size;
return outLocalTransform;
}
/**
* Returns the local transform of a transform component.
*
* @param i the {@link EntityInstance} of the transform component to query the
* local transform from.
* @param outLocalTransform a 16 <code>float</code> array to receive the result.
* If <code>null</code> is given, a new suitable array is allocated.
* @return the local transform of the component (i.e. relative to the parent). This always
* returns the value set by setTransform().
* @see #setTransform
*/
@NonNull
@Size(min = 16)
public double[] getTransform(@EntityInstance int i,
@Nullable @Size(min = 16) double[] outLocalTransform) {
outLocalTransform = Asserts.assertMat4(outLocalTransform);
nGetTransformFp64(mNativeObject, i, outLocalTransform);
return outLocalTransform;
}
/**
* Returns the world transform of a transform component.
*
@@ -197,6 +294,26 @@ import androidx.annotation.Size;
return outWorldTransform;
}
/**
* Returns the world transform of a transform component.
*
* @param i the {@link EntityInstance} of the transform component to query the
* world transform from.
* @param outWorldTransform a 16 <code>float</code> array to receive the result.
* If <code>null</code> is given, a new suitable array is allocated
* @return The world transform of the component (i.e. relative to the root). This is the
* composition of this component's local transform with its parent's world transform.
* @see #setTransform
*/
@NonNull
@Size(min = 16)
public double[] getWorldTransform(@EntityInstance int i,
@Nullable @Size(min = 16) double[] outWorldTransform) {
outWorldTransform = Asserts.assertMat4(outWorldTransform);
nGetWorldTransformFp64(mNativeObject, i, outWorldTransform);
return outWorldTransform;
}
/**
* Opens a local transform transaction. During a transaction, {@link #getWorldTransform} can
* return an invalid transform until {@link #commitLocalTransformTransaction} is called.
@@ -239,11 +356,18 @@ import androidx.annotation.Size;
private static native int nGetInstance(long nativeTransformManager, int entity);
private static native int nCreate(long nativeTransformManager, int entity);
private static native int nCreateArray(long mNativeObject, int entity, int parent, float[] localTransform);
private static native int nCreateArrayFp64(long mNativeObject, int entity, int parent, double[] localTransform);
private static native void nDestroy(long nativeTransformManager, int entity);
private static native void nSetParent(long nativeTransformManager, int i, int newParent);
private static native int nGetParent(long nativeTransformManager, int i);
private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform);
private static native void nSetTransformFp64(long nativeTransformManager, int i, double[] localTransform);
private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);
private static native void nGetTransformFp64(long nativeTransformManager, int i, double[] outLocalTransform);
private static native void nGetWorldTransform(long nativeTransformManager, int i, float[] outWorldTransform);
private static native void nGetWorldTransformFp64(long nativeTransformManager, int i, double[] outWorldTransform);
private static native void nOpenLocalTransformTransaction(long nativeTransformManager);
private static native void nCommitLocalTransformTransaction(long nativeTransformManager);
private static native void nSetAccurateTranslationsEnabled(long nativeTransformManager, boolean enable);
private static native boolean nIsAccurateTranslationsEnabled(long nativeTransformManager);
}
@@ -66,14 +66,14 @@ public class VertexBuffer {
BONE_INDICES, // indices of 4 bones (uvec4)
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
UNUSED, // reserved for future use
CUSTOM0, // custom or MORPH_POSITION_0
CUSTOM1, // custom or MORPH_POSITION_1
CUSTOM2, // custom or MORPH_POSITION_2
CUSTOM3, // custom or MORPH_POSITION_3
CUSTOM4, // custom or MORPH_TANGENTS_0
CUSTOM5, // custom or MORPH_TANGENTS_1
CUSTOM6, // custom or MORPH_TANGENTS_2
CUSTOM7 // custom or MORPH_TANGENTS_3
CUSTOM0, // custom
CUSTOM1, // custom
CUSTOM2, // custom
CUSTOM3, // custom
CUSTOM4, // custom
CUSTOM5, // custom
CUSTOM6, // custom
CUSTOM7 // custom
}
public enum AttributeType {
@@ -104,48 +104,6 @@ public class VertexBuffer {
HALF3,
HALF4,
}
/**
* Specifies the quaternion type for the {@link #populateTangentQuaternions} utility.
*/
public enum QuatType {
/** 2 bytes per component as half-floats (8 bytes per quat) */
HALF4,
/** 2 bytes per component as normalized integers (8 bytes per quat) */
SHORT4,
/** 4 bytes per component as floats (16 bytes per quat) */
FLOAT4,
}
/**
* Specifies the parameters for the {@link #populateTangentQuaternions} utility.
*/
public static class QuatTangentContext {
/** desired quaternion type (required) */
public QuatType quatType;
/** number of quaternions (required) */
public int quatCount;
/** pre-allocated output buffer (required) */
public Buffer outBuffer;
/** desired stride in bytes (optional) */
public int outStride;
/** source normals (required) */
public Buffer normals;
/** normals stride in bytes (optional) */
public int normalsStride;
/** source tangents (optional) */
public Buffer tangents;
/** tangents stride in bytes (optional) */
public int tangentsStride;
}
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
@@ -170,6 +128,21 @@ public class VertexBuffer {
return this;
}
/**
* Allows buffers to be swapped out and shared using BufferObject.
*
* If buffer objects mode is enabled, clients must call setBufferObjectAt rather than
* setBufferAt. This allows sharing of data between VertexBuffer objects, but it may
* slightly increase the memory footprint of Filament's internal bookkeeping.
*
* @param enabled If true, enables buffer object mode. False by default.
*/
@NonNull
public Builder enableBufferObjects(boolean enabled) {
nBuilderEnableBufferObjects(mNativeBuilder, enabled);
return this;
}
/**
* Defines how many buffers will be created in this vertex buffer set. These buffers are
* later referenced by index from 0 to <code>bufferCount</code> - 1.
@@ -397,36 +370,21 @@ public class VertexBuffer {
throw new BufferOverflowException();
}
}
/**
* Convenience function that consumes normal vectors (and, optionally, tangent vectors) and
* produces quaternions that can be passed into a TANGENTS buffer.
* Swaps in the given buffer object.
*
* <p>
* The given output buffer must be preallocated with at least quatCount * outStride bytes.
* <p>
* To use this, you must first call enableBufferObjects() on the Builder.
*
* <p>
* Normals are required but tangents are optional, in which case this function tries to generate
* reasonable tangents. The given normals should be unit length.
* </p>
*
* <p>
* If supplied, the tangent vectors should be unit length and should be orthogonal to the
* normals. The w component of the tangent is a sign (-1 or +1) indicating handedness of the
* basis.
* </p>
*
* @deprecated Instead please use SurfaceOrientation since it has additional capabilities and a
* builder-style API.
*
* @param context an initialized QuatTangentContext object
* @param engine Reference to the filament::Engine to associate this VertexBuffer with.
* @param bufferIndex Index of the buffer to initialize. Must be between 0
* and Builder::bufferCount() - 1.
* @param bufferObject The handle to the GPU data that will be used in this buffer slot.
*/
public static void populateTangentQuaternions(@NonNull QuatTangentContext context) {
nPopulateTangentQuaternions(context.quatType.ordinal(), context.quatCount,
context.outBuffer, context.outBuffer.remaining(), context.outStride,
context.normals, context.normals.remaining(), context.normalsStride,
context.tangents, context.tangents != null ? context.tangents.remaining() : 0,
context.tangentsStride);
public void setBufferObjectAt(@NonNull Engine engine, int bufferIndex,
@NonNull BufferObject bufferObject) {
nSetBufferObjectAt(getNativeObject(), engine.getNativeObject(), bufferIndex,
bufferObject.getNativeObject());
}
public long getNativeObject() {
@@ -443,6 +401,7 @@ public class VertexBuffer {
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 nBuilderEnableBufferObjects(long nativeBuilder, boolean enabled);
private static native void nBuilderBufferCount(long nativeBuilder, int bufferCount);
private static native void nBuilderAttribute(long nativeBuilder, int attribute,
int bufferIndex, int attributeType, int byteOffset, int byteStride);
@@ -455,7 +414,6 @@ public class VertexBuffer {
int bufferIndex, Buffer buffer, int remaining, int destOffsetInBytes, int count,
Object handler, Runnable callback);
private static native void nPopulateTangentQuaternions(int quatType, int quatCount,
Buffer outBuffer, int outRemaining, int outStride, Buffer normals, int normalsRemaining,
int normalsStride, Buffer tangents, int tangentsRemaining, int tangentsStride);
private static native void nSetBufferObjectAt(long nativeVertexBuffer, long nativeEngine,
int bufferIndex, long nativeBufferObject);
}
@@ -59,6 +59,10 @@ import static com.google.android.filament.Colors.LinearColor;
* @see RenderTarget
*/
public class View {
private static final AntiAliasing[] sAntiAliasingValues = AntiAliasing.values();
private static final Dithering[] sDitheringValues = Dithering.values();
private static final AmbientOcclusion[] sAmbientOcclusionValues = AmbientOcclusion.values();
private long mNativeObject;
private String mName;
private Scene mScene;
@@ -75,7 +79,9 @@ public class View {
private VignetteOptions mVignetteOptions;
private ColorGrading mColorGrading;
private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions;
private MultiSampleAntiAliasingOptions mMultiSampleAntiAliasingOptions;
private VsmShadowOptions mVsmShadowOptions;
private SoftShadowOptions mSoftShadowOptions;
/**
* Generic quality level.
@@ -131,8 +137,20 @@ public class View {
public float maxScale = 1.0f;
/**
* Upscaling quality. LOW: 1 bilinear tap, MEDIUM: 4 bilinear taps, HIGH: 9 bilinear taps.
* If minScale needs to be very low, it might help to use MEDIUM or HIGH here.
* Sharpness when QualityLevel.MEDIUM or higher is used [0, 1].
* 0 is disabled, 1 is the sharpest setting.
* The default is set to 0.9
*/
public float sharpness = 0.9f;
/**
* Upscaling quality
* LOW: bilinear filtered blit. Fastest, poor quality
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations no RCAS sharpening pass
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations + RCAS
* ULTRA: AMD FidelityFX FSR1
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
*
* The default upscaling quality is set to LOW.
*/
@NonNull
@@ -169,6 +187,16 @@ public class View {
*/
public float intensity = 1.0f;
/**
* Depth distance that constitute an edge for filtering. Must be positive.
* Default is 5cm.
* This must be adjusted with the scene's scale and/or units.
* A value too low will result in high frequency noise, while a value too high will
* result in the loss of geometry edges. For AO, it is generally better to be too
* blurry than not enough.
*/
public float bilateralThreshold = 0.05f;
/**
* The quality setting controls the number of samples used for evaluating Ambient
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
@@ -198,6 +226,11 @@ public class View {
*/
public boolean enabled = false;
/**
* enables bent normals computation from AO, and specular AO
*/
public boolean bentNormals = false;
/**
* Minimal angle to consider in radian. This is used to reduce the creases that can
* appear due to insufficiently tessellated geometry.
@@ -264,9 +297,32 @@ public class View {
public boolean ssctEnabled = false;
}
/**
* Options for Multi-sample Anti-aliasing (MSAA)
* @see View#setMultiSampleAntiAliasingOptions
*/
public static class MultiSampleAntiAliasingOptions {
/** enables or disables temporal anti-aliasing */
public boolean enabled = false;
/**
* number of samples to use for multi-sampled anti-aliasing.\n
* 0: treated as 1
* 1: no anti-aliasing
* n: sample count. Effective sample could be different depending on the
* GPU capabilities.
*/
public int sampleCount = 4;
/**
* custom resolve improves quality for HDR scenes, but may impact performance.
*/
public boolean customResolve = false;
};
/**
* Options for Temporal Anti-aliasing (TAA)
* @see View#setTemporalAntiAliasingOptions()
* @see View#setTemporalAntiAliasingOptions
*/
public static class TemporalAntiAliasingOptions {
/** reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother) */
@@ -284,11 +340,11 @@ public class View {
*
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* maximum is 12. This value together with resolution influences the spread of the
* maximum is 11. This value together with resolution influences the spread of the
* blur effect. This value can be silently reduced to accommodate the original
* image size.
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 4096. This parameter is
* resolution: Resolution of bloom's vertical axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 2048. This parameter is
* silently clamped to the minimum and maximum.
* It is highly recommended that this value be smaller than the target resolution
* after dynamic resolution is applied (horizontally and vertically).
@@ -329,7 +385,7 @@ public class View {
public float strength = 0.10f;
/**
* Resolution of minor axis (2^levels to 4096)
* Resolution of minor axis (2^levels to 2048)
*/
public int resolution = 360;
@@ -339,7 +395,7 @@ public class View {
public float anamorphism = 1.0f;
/**
* Number of blur levels (3 to 12)
* Number of blur levels (3 to 11)
*/
public int levels = 6;
@@ -363,6 +419,52 @@ public class View {
* minimum value is 10.0.
*/
public float highlight = 1000.0f;
/**
* enable screen-space lens flare
*/
public boolean lensFlare = false;
/**
* enable starburst effect on lens flare
*/
public boolean starburst = true;
/**
* amount of chromatic aberration
*/
public float chromaticAberration = 0.005f;
/**
* number of flare "ghosts"
*/
public int ghostCount = 4;
/**
* spacing of the ghost in screen units [0, 1[
*/
public float ghostSpacing = 0.6f;
/**
* hdr threshold for the ghosts
*/
public float ghostThreshold = 10.0f;
/**
* thickness of halo in vertical screen units, 0 to disable
*/
public float haloThickness = 0.1f;
/**
* radius of halo in vertical screen units [0, 0.5]
*/
public float haloRadius = 0.4f;
/**
* hdr threshold for the halo
*/
public float haloThreshold = 10.0f;
}
/**
@@ -431,8 +533,10 @@ public class View {
*/
public static class DepthOfFieldOptions {
/** focus distance in world units */
public float focusDistance = 10.0f;
public enum Filter {
NONE,
MEDIAN
}
/**
* circle of confusion scale factor (amount of blur)
@@ -451,6 +555,59 @@ public class View {
/** enable or disable Depth of field effect */
public boolean enabled = false;
/** filter to use for filling gaps in the kernel */
@NonNull
public Filter filter = Filter.MEDIAN;
/** perform DoF processing at native resolution */
public boolean nativeResolution = false;
/**
* <p>Number of of rings used by the foreground kernel. The number of rings affects quality
* and performance. The actual number of sample per pixel is defined
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:</p>
* 3 rings : 25 ( 5x 5 grid)
* 4 rings : 49 ( 7x 7 grid)
* 5 rings : 81 ( 9x 9 grid)
* 17 rings : 1089 (33x33 grid)
*
* <p>With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.</p>
*
* <p>Usually all three settings below are set to the same value, however, it is often
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
* Fast tiles are regions of the screen where every pixels have a similar
* circle-of-confusion radius.</p>
*
* <p>A value of 0 means default, which is 5 on desktop and 3 on mobile.</p>
*/
public int foregroundRingCount = 0;
/**
* Number of of rings used by the background kernel. The number of rings affects quality
* and performance.
* @see #foregroundRingCount
*/
public int backgroundRingCount = 0;
/**
* Number of of rings used by the fast gather kernel. The number of rings affects quality
* and performance.
* @see #foregroundRingCount
*/
public int fastGatherRingCount = 0;
/**
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
*/
public int maxForegroundCOC = 0;
/**
* maximum circle-of-confusion in pixels for the background, must be in [0, 32] range.
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
*/
public int maxBackgroundCOC = 0;
};
/**
@@ -580,26 +737,76 @@ public class View {
/**
* Variance shadows.
*/
VSM
VSM,
/**
* Percentage-closer filtered shadows, with contact hardening simulation.
*/
DPCF,
/**
* Percentage-closer soft shadows
*/
PCSS
}
/**
* View-level options for VSM shadowing.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @see View#setVsmShadowOptions
*/
public static class VsmShadowOptions {
/**
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
* than 0, mipmaps will automatically be generated each frame for all lights.
* This implies mipmapping below.
*
* <p>
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
* </p>
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*/
public int anisotropy = 0;
/**
* Whether to generate mipmaps for all VSM shadow maps.
*/
public boolean mipmapping = false;
/**
* VSM minimum variance scale, must be positive.
*/
public float minVarianceScale = 1.0f;
/**
* VSM light bleeding reduction amount, between 0 and 1.
*/
public float lightBleedReduction = 0.2f;
}
/**
* View-level options for DPCF and PCSS Shadowing.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @see View#setSoftShadowOptions
*/
public static class SoftShadowOptions {
/**
* Globally scales the penumbra of all DPCF and PCSS shadows
* Acceptable values are greater than 0
*/
public float penumbraScale = 1.0f;
/**
* Globally scales the computed penumbra ratio of all DPCF and PCSS shadows.
* This effectively controls the strength of contact hardening effect and is useful for
* artistic purposes. Higher values make the shadows become softer faster.
* Acceptable values are equal to or greater than 1.
*/
public float penumbraRatioScale = 1.0f;
}
/**
@@ -830,16 +1037,6 @@ public class View {
nSetShadowingEnabled(getNativeObject(), enabled);
}
/**
* Enables or disables shadow mapping. Enabled by default.
*
* @deprecated Use {@link #setShadowingEnabled}
*/
@Deprecated
public void setShadowsEnabled(boolean enabled) {
setShadowingEnabled(enabled);
}
/**
* @return whether shadowing is enabled
*/
@@ -905,7 +1102,10 @@ public class View {
* </p>
*
* @param count number of samples to use for multi-sampled anti-aliasing.
*
* @deprecated use setMultiSampleAntiAliasingOptions instead
*/
@Deprecated
public void setSampleCount(int count) {
nSetSampleCount(getNativeObject(), count);
}
@@ -918,7 +1118,10 @@ public class View {
* </p>
*
* @return value set by {@link #setSampleCount}
*
* @deprecated use getMultiSampleAntiAliasingOptions instead
*/
@Deprecated
public int getSampleCount() {
return nGetSampleCount(getNativeObject());
}
@@ -944,7 +1147,31 @@ public class View {
*/
@NonNull
public AntiAliasing getAntiAliasing() {
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
return sAntiAliasingValues[nGetAntiAliasing(getNativeObject())];
}
/**
* Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default.
*
* @param options multi-sample anti-aliasing options
*/
public void setMultiSampleAntiAliasingOptions(@NonNull MultiSampleAntiAliasingOptions options) {
mMultiSampleAntiAliasingOptions = options;
nSetMultiSampleAntiAliasingOptions(getNativeObject(),
options.enabled, options.sampleCount, options.customResolve);
}
/**
* Returns multi-sample anti-aliasing options.
*
* @return multi-sample anti-aliasing options
*/
@NonNull
public MultiSampleAntiAliasingOptions getMultiSampleAntiAliasingOptions() {
if (mMultiSampleAntiAliasingOptions == null) {
mMultiSampleAntiAliasingOptions = new MultiSampleAntiAliasingOptions();
}
return mMultiSampleAntiAliasingOptions;
}
/**
@@ -1033,7 +1260,7 @@ public class View {
*/
@NonNull
public Dithering getDithering() {
return Dithering.values()[nGetDithering(getNativeObject())];
return sDitheringValues[nGetDithering(getNativeObject())];
}
/**
@@ -1058,6 +1285,7 @@ public class View {
options.homogeneousScaling,
options.minScale,
options.maxScale,
options.sharpness,
options.quality.ordinal());
}
@@ -1109,21 +1337,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
@@ -1217,7 +1450,8 @@ public class View {
*/
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
mVsmShadowOptions = options;
nSetVsmShadowOptions(getNativeObject(), options.anisotropy);
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
options.minVarianceScale, options.lightBleedReduction);
}
/**
@@ -1233,6 +1467,37 @@ public class View {
return mVsmShadowOptions;
}
/**
* Sets soft shadowing options that apply across the entire View.
*
* Additional light-specific VSM options can be set with
* {@link LightManager.Builder#shadowOptions}.
*
* Only applicable when shadow type is set to ShadowType.DPCF.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @param options Options for shadowing.
* @see #setShadowType
*/
public void setSoftShadowOptions(@NonNull SoftShadowOptions options) {
mSoftShadowOptions = options;
nSetSoftShadowOptions(getNativeObject(), options.penumbraScale, options.penumbraRatioScale);
}
/**
* Gets soft shadowing options associated with this View.
* @see #setSoftShadowOptions
* @return soft shadow options currently set.
*/
@NonNull
public SoftShadowOptions getSoftShadowOptions() {
if (mSoftShadowOptions == null) {
mSoftShadowOptions = new SoftShadowOptions();
}
return mSoftShadowOptions;
}
/**
* Activates or deactivates ambient occlusion.
* @see #setAmbientOcclusionOptions
@@ -1251,7 +1516,7 @@ public class View {
@Deprecated
@NonNull
public AmbientOcclusion getAmbientOcclusion() {
return AmbientOcclusion.values()[nGetAmbientOcclusion(getNativeObject())];
return sAmbientOcclusionValues[nGetAmbientOcclusion(getNativeObject())];
}
/**
@@ -1262,9 +1527,11 @@ public class View {
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
mAmbientOcclusionOptions = options;
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
options.resolution, options.intensity, options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
options.enabled, options.minHorizonAngleRad);
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance, options.ssctContactDistanceMax, options.ssctIntensity,
options.resolution, options.intensity, options.bilateralThreshold,
options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
options.enabled, options.bentNormals, options.minHorizonAngleRad);
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance,
options.ssctContactDistanceMax, options.ssctIntensity,
options.ssctLightDirection[0], options.ssctLightDirection[1], options.ssctLightDirection[2],
options.ssctDepthBias, options.ssctDepthSlopeBias, options.ssctSampleCount,
options.ssctRayCount, options.ssctEnabled);
@@ -1294,7 +1561,10 @@ public class View {
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
options.dirtStrength, options.strength, options.resolution,
options.anamorphism, options.levels, options.blendingMode.ordinal(),
options.threshold, options.enabled, options.highlight);
options.threshold, options.enabled, options.highlight,
options.lensFlare, options.starburst, options.chromaticAberration,
options.ghostCount, options.ghostSpacing, options.ghostThreshold,
options.haloThickness, options.haloRadius, options.haloThreshold);
}
/**
@@ -1379,7 +1649,10 @@ public class View {
*/
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
mDepthOfFieldOptions = options;
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale, options.maxApertureDiameter, options.enabled);
nSetDepthOfFieldOptions(getNativeObject(), options.cocScale,
options.maxApertureDiameter, options.enabled, options.filter.ordinal(),
options.nativeResolution, options.foregroundRingCount, options.backgroundRingCount,
options.fastGatherRingCount, options.maxForegroundCOC, options.maxBackgroundCOC);
}
/**
@@ -1396,6 +1669,71 @@ public class View {
return mDepthOfFieldOptions;
}
/**
* A class containing the result of a picking query
*/
public static class PickingQueryResult {
/** The entity of the renderable at the picking query location */
@Entity public int renderable;
/** The value of the depth buffer at the picking query location */
public float depth;
/** The fragment coordinate in GL convention at the picking query location */
@NonNull public float[] fragCoords = new float[3];
};
/**
* An interface to implement a custom class to receive results of picking queries.
*/
public interface OnPickCallback {
/**
* onPick() is called by the specified Handler in {@link View#pick} when the picking query
* result is available.
* @param result An instance of {@link PickingQueryResult}.
*/
void onPick(@NonNull PickingQueryResult result);
}
/**
* Creates a picking query. Multiple queries can be created (e.g.: multi-touch).
* Picking queries are all executed when {@link Renderer#render} is called on this View.
* The provided callback is guaranteed to be called at some point in the future.
*
* Typically it takes a couple frames to receive the result of a picking query.
*
* @param x Horizontal coordinate to query in the viewport with origin on the left.
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
* @param handler An {@link java.util.concurrent.Executor Executor}.
* On Android this can also be a {@link android.os.Handler Handler}.
* @param callback User callback executed by <code>handler</code> when the picking query
* result is available.
*/
public void pick(int x, int y,
@Nullable Object handler, @Nullable OnPickCallback callback) {
InternalOnPickCallback internalCallback = new InternalOnPickCallback(callback);
nPick(getNativeObject(), x, y, handler, internalCallback);
}
private static class InternalOnPickCallback implements Runnable {
public InternalOnPickCallback(OnPickCallback mUserCallback) {
this.mUserCallback = mUserCallback;
}
@Override
public void run() {
mPickingQueryResult.renderable = mRenderable;
mPickingQueryResult.depth = mDepth;
mPickingQueryResult.fragCoords[0] = mFragCoordsX;
mPickingQueryResult.fragCoords[1] = mFragCoordsY;
mPickingQueryResult.fragCoords[2] = mFragCoordsZ;
mUserCallback.onPick(mPickingQueryResult);
}
private final OnPickCallback mUserCallback;
private final PickingQueryResult mPickingQueryResult = new PickingQueryResult();
@Entity int mRenderable;
float mDepth;
float mFragCoordsX;
float mFragCoordsY;
float mFragCoordsZ;
}
public long getNativeObject() {
if (mNativeObject == 0) {
@@ -1421,11 +1759,12 @@ public class View {
private static native int nGetAntiAliasing(long nativeView);
private static native void nSetDithering(long nativeView, int dithering);
private static native int nGetDithering(long nativeView);
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, int quality);
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, float sharpness, int quality);
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetShadowType(long nativeView, int type);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float minVarianceScale, float lightBleedReduction);
private static native void nSetSoftShadowOptions(long nativeView, float penumbraScale, float penumbraRatioScale);
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
private static native boolean nIsPostProcessingEnabled(long nativeView);
@@ -1433,15 +1772,19 @@ public class View {
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
private static native int nGetAmbientOcclusion(long nativeView);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int lowPassFilter, int upsampling, boolean enabled, float minHorizonAngleRad);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, float minHorizonAngleRad);
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled);
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
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 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);
private static native boolean nIsScreenSpaceRefractionEnabled(long nativeView);
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
}
@@ -23,8 +23,6 @@ import androidx.annotation.NonNull;
import com.google.android.filament.Engine;
import com.google.android.filament.Texture;
import java.lang.reflect.Method;
public final class TextureHelper {
// Keep in sync with Texture.cpp
private static final int BITMAP_CONFIG_ALPHA_8 = 0;
+34 -4
View File
@@ -1,6 +1,8 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.19)
project(filament-utils-android)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(IMAGEIO_DIR ../../libs/imageio)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gltfio-android ${CMAKE_CURRENT_BINARY_DIR}/gltfio-android)
@@ -12,27 +14,55 @@ add_library(image STATIC IMPORTED)
set_target_properties(image PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
include_directories(${FILAMENT_DIR}/include
..
../../libs/utils/include)
add_library(viewer STATIC IMPORTED)
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
add_library(civetweb STATIC IMPORTED)
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
add_library(iblprefilter STATIC IMPORTED)
set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
add_library(filament-utils-jni SHARED
src/main/cpp/AutomationEngine.cpp
src/main/cpp/Bookmark.cpp
src/main/cpp/HDRLoader.cpp
src/main/cpp/IBLPrefilterContext.cpp
src/main/cpp/Utils.cpp
src/main/cpp/Manipulator.cpp
src/main/cpp/RemoteServer.cpp
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
${IMAGEIO_DIR}/include/imageio/HDRDecoder.h
${IMAGEIO_DIR}/src/HDRDecoder.cpp
../common/CallbackUtils.cpp
../common/NioUtils.cpp
)
target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
target_include_directories(filament-utils-jni PRIVATE
${FILAMENT_DIR}/include
..
../../filament/backend/include
${IMAGEIO_DIR}/include
../../libs/utils/include)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
# The ordering in the following list is important because CMake does not have dependency information.
target_link_libraries(filament-utils-jni
gltfio-jni
civetweb
camutils
iblprefilter
image
viewer
)
+13 -5
View File
@@ -9,6 +9,13 @@ android {
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")
}
}
}
}
@@ -43,13 +50,14 @@ configurations.all { config ->
dependencies {
implementation deps.kotlin
implementation deps.androidx.annotations
implementation project(':filament-android')
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
implementation deps.coroutines.core
implementation deps.coroutines.android
fullImplementation module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
liteImplementation module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
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}")
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
@@ -0,0 +1,213 @@
/*
* 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 <viewer/AutomationEngine.h>
using namespace filament;
using namespace filament::viewer;
using namespace utils;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nCreateAutomationEngine(JNIEnv* env, jclass,
jstring spec_) {
const char* spec = env->GetStringUTFChars(spec_, 0);
jlong result = (jlong) AutomationEngine::createFromJSON(spec, strlen(spec));
env->ReleaseStringUTFChars(spec_, spec);
return result;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nCreateDefaultAutomationEngine(JNIEnv* env,
jclass klass) {
return (jlong) AutomationEngine::createDefault();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nSetOptions(JNIEnv* env, jclass klass,
jlong nativeAutomation, jfloat sleepDuration, jint minFrameCount, jboolean verbose) {
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
AutomationEngine::Options options = {
.sleepDuration = sleepDuration,
.minFrameCount = minFrameCount,
.verbose = (bool) verbose,
// Since they write to the filesystem, we do not currently support exporting screenshots
// and JSON files on Android.
.exportScreenshots = false,
.exportSettings = false,
};
automation->setOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nStartRunning(JNIEnv* env, jclass klass,
jlong nativeAutomation) {
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
automation->startRunning();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nStartBatchMode(JNIEnv* env, jclass klass,
jlong nativeAutomation) {
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
automation->startBatchMode();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
jlong nativeAutomation, jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
using MaterialPointer = MaterialInstance*;
jsize materialCount = 0;
jlong* longMaterials = nullptr;
MaterialPointer* ptrMaterials = nullptr;
if (materials) {
materialCount = env->GetArrayLength(materials);
ptrMaterials = new MaterialPointer[materialCount];
longMaterials = env->GetLongArrayElements(materials, nullptr);
for (jsize i = 0; i < materialCount; i++) {
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
}
}
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
AutomationEngine::ViewerContent content = {
.view = (View*) view,
.renderer = (Renderer*) renderer,
.materials = ptrMaterials,
.materialCount = (size_t) materialCount,
};
automation->tick(content, deltaTime);
if (longMaterials) {
env->ReleaseLongArrayElements(materials, longMaterials, 0);
delete[] ptrMaterials;
}
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* env, jclass klass,
jlong nativeAutomation, jstring json, jlong view, jlongArray materials, jlong nativeIbl,
jint sunlightEntity, jintArray assetLights, jlong nativeLm, jlong scene, jlong renderer) {
using MaterialPointer = MaterialInstance*;
jsize materialCount = 0;
jlong* longMaterials = nullptr;
MaterialPointer* ptrMaterials = nullptr;
if (materials) {
materialCount = env->GetArrayLength(materials);
ptrMaterials = new MaterialPointer[materialCount];
longMaterials = env->GetLongArrayElements(materials, nullptr);
for (jsize i = 0; i < materialCount; i++) {
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
}
}
jsize lightCount = 0;
jint* intLights = nullptr;
if (assetLights) {
lightCount = env->GetArrayLength(assetLights);
intLights = env->GetIntArrayElements(assetLights, nullptr);
}
static_assert(sizeof(jint) == sizeof(Entity));
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
const char* nativeJson = env->GetStringUTFChars(json, 0);
size_t jsonLength = env->GetStringUTFLength(json);
AutomationEngine::ViewerContent content = {
.view = (View*) view,
.renderer = (Renderer*) renderer,
.materials = ptrMaterials,
.materialCount = (size_t) materialCount,
.lightManager = (LightManager*) nativeLm,
.scene = (Scene*) scene,
.indirectLight = (IndirectLight*) nativeIbl,
.sunlight = (Entity&) sunlightEntity,
.assetLights = (Entity*) intLights,
.assetLightCount = (size_t) lightCount,
};
automation->applySettings(nativeJson, jsonLength, content);
env->ReleaseStringUTFChars(json, nativeJson);
if (longMaterials) {
env->ReleaseLongArrayElements(materials, longMaterials, 0);
delete[] ptrMaterials;
}
if (intLights) {
env->ReleaseIntArrayElements(assetLights, intLights, 0);
}
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
jlong nativeObject, jobject result) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
auto options = automation->getViewerOptions();
const jclass klass = env->GetObjectClass(result);
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
env->SetFloatField(result, cameraAperture, options.cameraAperture);
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
env->SetFloatField(result, cameraISO, options.cameraISO);
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
jlong nativeObject, jlong nativeEngine) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
return (jlong) automation->getColorGrading((Engine*) nativeEngine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nSignalBatchMode(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
automation->signalBatchMode();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nStopRunning(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
automation->stopRunning();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nShouldClose(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
return automation->shouldClose();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nDestroy(JNIEnv*, jclass, jlong native) {
AutomationEngine* automation = (AutomationEngine*) native;
delete automation;
}
@@ -0,0 +1,91 @@
/*
* 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 <filament/Engine.h>
#include <filament/Texture.h>
#include <imageio/HDRDecoder.h>
#include <utils/Log.h>
#include <sstream>
#include "common/NioUtils.h"
using namespace filament;
using namespace image;
using namespace utils;
using PixelBufferDescriptor = Texture::PixelBufferDescriptor;
jlong nCreateHDRTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
Texture::InternalFormat textureFormat = (Texture::InternalFormat) internalFormat;
auto dataPtr = (char const*) buffer.getData();
const size_t byteCount = buffer.getSize();
// This creates a copy but it's the easest way to create a memory stream.
std::string ins(dataPtr, byteCount);
std::istringstream in(ins);
LinearImage* image = new LinearImage(ImageDecoder::decode(in, "memory.hdr"));
// This can happen if a decoding error occurs.
if (image->getChannels() != 3) {
delete image;
return 0;
}
Texture* texture = Texture::Builder()
.width(image->getWidth())
.height(image->getHeight())
.levels(0xff)
.sampler(Texture::Sampler::SAMPLER_2D)
.format(textureFormat)
.build(*engine);
if (texture == nullptr) {
slog.e << "Unable to create Filament Texture from HDR image." << io::endl;
delete image;
return 0;
}
PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* userdata) {
delete (LinearImage*) userdata;
};
PixelBufferDescriptor pbd(
(void const* ) image->getPixelRef(),
image->getWidth() * image->getHeight() * 3 * sizeof(float),
PixelBufferDescriptor::PixelDataFormat::RGB,
PixelBufferDescriptor::PixelDataType::FLOAT,
freeCallback,
image);
// Note that the setImage call could fail (e.g. due to an invalid combination of internal format
// and PixelDataFormat) but there is no way of detecting such a failure.
texture->setImage(*engine, 0, std::move(pbd));
texture->generateMipmaps(*engine);
return (jlong) texture;
}
@@ -0,0 +1,75 @@
/*
* 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 <filament-iblprefilter/IBLPrefilterContext.h>
#include <filament/Engine.h>
#include <filament/Texture.h>
using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreate(JNIEnv* env, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) new IBLPrefilterContext(*engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroy(JNIEnv*, jclass, jlong native) {
IBLPrefilterContext* context = (IBLPrefilterContext*) native;
delete context;
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateEquirectHelper(JNIEnv* env, jclass, jlong nativeContext) {
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
return (long) new IBLPrefilterContext::EquirectangularToCubemap(*context);
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nEquirectHelperRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeEquirect) {
auto helper = (IBLPrefilterContext::EquirectangularToCubemap*) nativeHelper;
auto texture = (filament::Texture*) nativeEquirect;
auto result = (*helper)(texture);
return (long) result;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroyEquirectHelper(JNIEnv* env, jclass, jlong nativeObject) {
delete (IBLPrefilterContext::EquirectangularToCubemap*) nativeObject;
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateSpecularFilter(JNIEnv* env, jclass, jlong nativeContext) {
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
return (long) new IBLPrefilterContext::SpecularFilter(*context);
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nSpecularFilterRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeSkybox) {
auto helper = (IBLPrefilterContext::SpecularFilter*) nativeHelper;
auto texture = (filament::Texture*) nativeSkybox;
auto result = (*helper)(texture);
return (long) result;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroySpecularFilter(JNIEnv* env, jclass, jlong nativeObject) {
delete (IBLPrefilterContext::SpecularFilter*) nativeObject;
}
@@ -0,0 +1,77 @@
/*
* 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 <viewer/RemoteServer.h>
using namespace filament::viewer;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_RemoteServer_nCreate(JNIEnv* env, jclass, jint port) {
RemoteServer* server = new RemoteServer(port);
if (!server->isValid()) {
delete server;
return 0;
}
return (jlong) server;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_RemoteServer_nDestroy(JNIEnv*, jclass, jlong native) {
RemoteServer* server = (RemoteServer*) native;
delete server;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_utils_RemoteServer_nPeekIncomingLabel(JNIEnv* env, jclass, jlong native) {
RemoteServer* server = (RemoteServer*) native;
char const* label = server->peekIncomingLabel();
return label ? env->NewStringUTF(label) : nullptr;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_utils_RemoteServer_nPeekReceivedLabel(JNIEnv* env, jclass, jlong native) {
RemoteServer* server = (RemoteServer*) native;
ReceivedMessage const* msg = server->peekReceivedMessage();
return msg ? env->NewStringUTF(msg->label) : nullptr;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_utils_RemoteServer_nPeekReceivedBufferLength(JNIEnv* env, jclass, jlong native) {
RemoteServer* server = (RemoteServer*) native;
ReceivedMessage const* msg = server->peekReceivedMessage();
return msg ? msg->bufferByteCount : 0;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_RemoteServer_nAcquireReceivedMessage(JNIEnv* env, jclass, jlong native, jobject buffer, jint length) {
RemoteServer* server = (RemoteServer*) native;
ReceivedMessage const* msg = server->acquireReceivedMessage();
if (msg == nullptr) {
return;
}
void* address = env->GetDirectBufferAddress(buffer);
if (address == nullptr) {
// This should never happen because the Java layer does allocateDirect.
return;
}
memcpy(address, msg->buffer, length);
server->releaseReceivedMessage(msg);
}
@@ -28,7 +28,10 @@ using namespace filament;
using namespace filament::math;
using namespace image;
static jlong nCreateTexture(JNIEnv* env, jclass,
jlong nCreateHDRTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
static jlong nCreateKTXTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
@@ -73,6 +76,19 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
}
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());
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
const auto success = bundle.getSphericalHarmonics(
reinterpret_cast<filament::math::float3*>(outSphericalHarmonics)
);
env->ReleaseFloatArrayElements(outSphericalHarmonics_, outSphericalHarmonics, JNI_ABORT);
return success ? JNI_TRUE : JNI_FALSE;
}
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
@@ -80,15 +96,27 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
return -1;
}
jclass c = env->FindClass("com/google/android/filament/utils/KtxLoader");
if (c == nullptr) return JNI_ERR;
int rc;
static const JNINativeMethod methods[] = {
{"nCreateTexture", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateTexture)},
{"nCreateIndirectLight", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
{"nCreateSkybox", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
// KTXLoader
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
if (ktxloaderClass == nullptr) return JNI_ERR;
static const JNINativeMethod ktxMethods[] = {
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
{(char*)"nCreateIndirectLight", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
{(char*)"nCreateSkybox", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
{(char*)"nGetSphericalHarmonics", (char*)"(Ljava/nio/Buffer;I[F)Z", reinterpret_cast<void*>(nGetSphericalHarmonics)},
};
int rc = env->RegisterNatives(c, methods, sizeof(methods) / sizeof(JNINativeMethod));
rc = env->RegisterNatives(ktxloaderClass, ktxMethods, sizeof(ktxMethods) / sizeof(JNINativeMethod));
if (rc != JNI_OK) return rc;
// HDRLoader
jclass hdrloaderClass = env->FindClass("com/google/android/filament/utils/HDRLoader");
if (hdrloaderClass == nullptr) return JNI_ERR;
static const JNINativeMethod hdrMethods[] = {
{(char*)"nCreateHDRTexture", (char*)"(JLjava/nio/Buffer;II)J", reinterpret_cast<void*>(nCreateHDRTexture)},
};
rc = env->RegisterNatives(hdrloaderClass, hdrMethods, sizeof(hdrMethods) / sizeof(JNINativeMethod));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
@@ -0,0 +1,280 @@
/*
* 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.
*/
package com.google.android.filament.utils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.filament.ColorGrading;
import com.google.android.filament.Engine;
import com.google.android.filament.Entity;
import com.google.android.filament.IndirectLight;
import com.google.android.filament.LightManager;
import com.google.android.filament.Scene;
import com.google.android.filament.View;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Renderer;
/**
* The AutomationEngine makes it easy to push a bag of settings values to Filament.
* It can also be used to iterate through settings permutations for testing purposes.
*
* When creating an automation engine for testing purposes, clients give it a JSON string that
* tells it how to generate permutations of settings. Automation is always in one of two states:
* running or idle. The running state can be entered immediately (startRunning) or by requesting
* batch mode (startBatchMode).
*
* 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.
*
* 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.
*
* Batch mode is meant for non-interactive applications. In batch mode, automation defers applying
* the first test case until the client unblocks it via signalBatchMode(). This is useful when
* waiting for a large model file to become fully loaded. Batch mode also offers a query
* (shouldClose) that is triggered after the last test has been invoked.
*/
public class AutomationEngine {
private final long mNativeObject;
private ColorGrading mColorGrading;
/**
* Allows users to toggle screenshots, change the sleep duration between tests, etc.
*/
public static class Options {
/**
* Minimum time that automation waits between applying a settings object and advancing
* to the next test case. Specified in seconds.
*/
public float sleepDuration = 0.2f;
/**
* Similar to sleepDuration, but expressed as a frame count. Both the minimum sleep time
* and the minimum frame count must be elapsed before automation advances to the next test.
*/
public int minFrameCount = 2;
/**
* If true, test progress is dumped to the utils Log (info priority).
*/
public boolean verbose = true;
}
/**
* Collection of Filament objects that can be modified by the automation engine.
*/
public static class ViewerContent {
public View view;
public Renderer renderer;
public MaterialInstance[] materials;
public LightManager lightManager;
public Scene scene;
public IndirectLight indirectLight;
public @Entity int sunlight;
public @Entity int[] assetLights;
}
/**
* Allows remote control for the viewer.
*/
public static class ViewerOptions {
public float cameraAperture = 16.0f;
public float cameraSpeed = 125.0f;
public float cameraISO = 100.0f;
public float groundShadowStrength = 0.75f;
public boolean groundPlaneEnabled = false;
public boolean skyboxEnabled = true;
public float cameraFocalLength = 28.0f;
public float cameraFocusDistance = 0.0f;
public boolean autoScaleEnabled = true;
}
/**
* Creates an automation engine from a JSON specification.
*
* An example of a JSON spec can be found by searching the repo for DEFAULT_AUTOMATION.
* This is documented using a JSON schema (look for viewer/schemas/automation.json).
*
* @param jsonSpec Valid JSON string that conforms to the automation schema.
*/
public AutomationEngine(@NonNull String jsonSpec) {
mNativeObject = nCreateAutomationEngine(jsonSpec);
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create AutomationEngine");
}
/**
* Creates an automation engine for the sole purpose of pushing settings, or for executing
* the default test sequence.
*
* To see how the default test sequence is generated, search for DEFAULT_AUTOMATION.
*/
public AutomationEngine() {
mNativeObject = nCreateDefaultAutomationEngine();
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create AutomationEngine");
}
/**
* Configures the automation engine for users who wish to set up a custom sleep time
* between tests, etc.
*/
public void setOptions(@NonNull Options options) {
nSetOptions(mNativeObject, options.sleepDuration, options.minFrameCount, options.verbose);
}
/**
* Activates the automation test. During the subsequent call to tick(), the first test is
* applied and automation enters the running state.
*/
public void startRunning() { nStartRunning(mNativeObject); }
/**
* Activates the automation test, but enters a paused state until the user calls
* signalBatchMode().
*/
public void startBatchMode() { nStartBatchMode(mNativeObject); }
/**
* Notifies the automation engine that time has passed and a new frame has been rendered.
*
* This is when settings get applied, screenshots are (optionally) exported, and the internal
* test counter is potentially incremented.
*
* @param content Contains the Filament View, Materials, and Renderer that get modified.
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
*/
public void tick(@NonNull ViewerContent content, float deltaTime) {
if (content.view == null || content.renderer == null) {
throw new IllegalStateException("Must provide a View and Renderer");
}
long[] nativeMaterialInstances = null;
if (content.materials != null) {
nativeMaterialInstances = new long[content.materials.length];
for (int i = 0; i < nativeMaterialInstances.length; i++) {
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
}
}
long nativeView = content.view.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
}
/**
* Mutates a set of client-owned Filament objects according to a JSON string.
*
* This method is an alternative to tick(). It allows clients to use the automation engine as a
* remote control, as opposed to iterating through a predetermined test sequence.
*
* This updates the stashed Settings object, then pushes those settings to the given
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
*
* @param settingsJson Contains the JSON string with a set of changes that need to be pushed.
* @param content Contains a set of Filament objects that you want to mutate.
*/
public void applySettings(@NonNull String settingsJson, @NonNull ViewerContent content) {
if (content.view == null || content.renderer == null) {
throw new IllegalStateException("Must provide a View and Renderer");
}
long[] nativeMaterialInstances = null;
if (content.lightManager == null || content.scene == null) {
throw new IllegalStateException("Must provide a LightManager and Scene");
}
if (content.materials != null) {
nativeMaterialInstances = new long[content.materials.length];
for (int i = 0; i < nativeMaterialInstances.length; i++) {
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
}
}
long nativeView = content.view.getNativeObject();
long nativeIbl = content.indirectLight == null ? 0 : content.indirectLight.getNativeObject();
long nativeLm = content.lightManager.getNativeObject();
long nativeScene = content.scene.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nApplySettings(mNativeObject, settingsJson, nativeView, nativeMaterialInstances,
nativeIbl, content.sunlight, content.assetLights, nativeLm, nativeScene,
nativeRenderer);
}
/**
* Gets the current viewer options.
*
* NOTE: Focal length here might be different from the user-specified value, due to DoF options.
*/
@NonNull
public ViewerOptions getViewerOptions() {
ViewerOptions result = new ViewerOptions();
nGetViewerOptions(mNativeObject, result);
return result;
}
/**
* Gets a color grading object that corresponds to the latest settings.
*
* This method either returns a cached instance, or it destroys the cached instance and creates
* a new one.
*/
@NonNull
public ColorGrading getColorGrading(@NonNull Engine engine) {
// The native layer automatically destroys the old color grading instance,
// so there is no need to call Engine#destroyColorGrading here.
long nativeCg = nGetColorGrading(mNativeObject, engine.getNativeObject());
if (mColorGrading == null || mColorGrading.getNativeObject() != nativeCg) {
mColorGrading = nativeCg == 0 ? null : new ColorGrading(nativeCg);
}
return mColorGrading;
}
/**
* Signals that batch mode can begin. Call this after all meshes and textures finish loading.
*/
public void signalBatchMode() { nSignalBatchMode(mNativeObject); }
/**
* Cancels an in-progress automation session.
*/
public void stopRunning() { nStopRunning(mNativeObject); }
/**
* Returns true if automation is in batch mode and all tests have finished.
*/
public boolean shouldClose() { return nShouldClose(mNativeObject); }
@Override
protected void finalize() throws Throwable {
nDestroy(mNativeObject);
super.finalize();
}
private static native long nCreateAutomationEngine(String jsonSpec);
private static native long nCreateDefaultAutomationEngine();
private static native void nSetOptions(long nativeObject, float sleepDuration,
int minFrameCount, boolean verbose);
private static native void nStartRunning(long nativeObject);
private static native void nStartBatchMode(long nativeObject);
private static native void nTick(long nativeObject, long view, long[] materials, long renderer,
float deltaTime);
private static native void nApplySettings(long nativeObject, String jsonSettings, long view,
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
long scene, long renderer);
private static native void nGetViewerOptions(long nativeObject, Object result);
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
private static native void nSignalBatchMode(long nativeObject);
private static native void nStopRunning(long nativeObject);
private static native boolean nShouldClose(long nativeObject);
private static native void nDestroy(long nativeObject);
}
@@ -0,0 +1,50 @@
/*
* 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.
*/
package com.google.android.filament.utils
import com.google.android.filament.Engine
import com.google.android.filament.Texture
import java.nio.Buffer
/**
* Utility for decoding an HDR file and producing a Filament texture.
*/
object HDRLoader {
class Options {
var desiredFormat = Texture.InternalFormat.RGB16F
}
/**
* Consumes the content of an HDR file and produces a [Texture] object.
*
* @param engine Gets passed to the builder.
* @param buffer The content of the HDR File.
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture? {
val nativeEngine = engine.nativeObject
val nativeTexture = nCreateHDRTexture(nativeEngine, buffer, buffer.remaining(), options.desiredFormat.ordinal)
if (nativeTexture == 0L) {
return null;
}
return Texture(nativeTexture)
}
private external fun nCreateHDRTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, format: Int): Long
}
@@ -0,0 +1,130 @@
/*
* 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.
*/
package com.google.android.filament.utils;
import com.google.android.filament.Engine;
import com.google.android.filament.Texture;
/**
* IBLPrefilterContext creates and initializes GPU state common to all environment map filters
* supported. Typically, only one instance per filament Engine of this object needs to exist.
*
* Java usage example:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* context = new IBLPrefilterContext(engine);
* equirectangularToCubemap = new IBLPrefilterContext.EquirectangularToCubemap(context);
*
* Texture equirect = HDRLoader.createTexture("foo.hdr");
* Texture skyboxTexture = equirectangularToCubemap.run(equirect);
* engine.destroy(equirect);
* equirectangularToCubemap.destroy();
*
* specularFilter = new IBLPrefilterContext.SpecularFilter(context);
* Texture reflections = specularFilter.run(skyboxTexture);
* specularFilter.destroy();
*
* context.destroy();
*
* IndirectLight ibl = IndirectLight.Builder()
* .reflections(reflections)
* .intensity(30000.0f)
* .build(engine);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public class IBLPrefilterContext {
private long mNativeObject;
public IBLPrefilterContext(Engine engine) {
mNativeObject = nCreate(engine.getNativeObject());
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create IBLPrefilterContext");
}
public void destroy() {
nDestroy(getNativeObject());
mNativeObject = 0;
}
public static class EquirectangularToCubemap {
private long mNativeObject;
public EquirectangularToCubemap(IBLPrefilterContext context) {
mNativeObject = nCreateEquirectHelper(context.getNativeObject());
}
public Texture run(Texture equirect) {
long nativeTexture = nEquirectHelperRun(getNativeObject(), equirect.getNativeObject());
return new Texture(nativeTexture);
}
public void destroy() {
nDestroyEquirectHelper(getNativeObject());
mNativeObject = 0;
}
protected long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed EquirectangularToCubemap");
}
return mNativeObject;
}
}
public static class SpecularFilter {
private long mNativeObject;
public SpecularFilter(IBLPrefilterContext context) {
mNativeObject = nCreateSpecularFilter(context.getNativeObject());
}
public Texture run(Texture skybox) {
long nativeTexture = nSpecularFilterRun(getNativeObject(), skybox.getNativeObject());
return new Texture(nativeTexture);
}
public void destroy() {
nDestroySpecularFilter(getNativeObject());
mNativeObject = 0;
}
protected long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SpecularFilter");
}
return mNativeObject;
}
}
protected long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IBLPrefilterContext");
}
return mNativeObject;
}
private static native long nCreate(long nativeEngine);
private static native void nDestroy(long nativeObject);
private static native long nCreateEquirectHelper(long nativeContext);
private static native long nEquirectHelperRun(long nativeHelper, long nativeEquirect);
private static native void nDestroyEquirectHelper(long nativeObject);
private static native long nCreateSpecularFilter(long nativeContext);
private static native long nSpecularFilterRun(long nativeHelper, long nativeSkybox);
private static native void nDestroySpecularFilter(long nativeObject);
}
@@ -29,7 +29,7 @@ import java.nio.Buffer
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
* into a single file.
*/
object KtxLoader {
object KTXLoader {
class Options {
var srgb = false
}
@@ -44,8 +44,8 @@ object KtxLoader {
*/
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture {
val nativeEngine = engine.nativeObject
val nativeTexture = nCreateTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
return Texture(engine, nativeTexture)
val nativeTexture = nCreateKTXTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
return Texture(nativeTexture)
}
/**
@@ -59,7 +59,7 @@ object KtxLoader {
fun createIndirectLight(engine: Engine, buffer: Buffer, options: Options = Options()): IndirectLight {
val nativeEngine = engine.nativeObject
val nativeIndirectLight = nCreateIndirectLight(nativeEngine, buffer, buffer.remaining(), options.srgb)
return IndirectLight(engine, nativeIndirectLight)
return IndirectLight(nativeIndirectLight)
}
/**
@@ -73,10 +73,23 @@ object KtxLoader {
fun createSkybox(engine: Engine, buffer: Buffer, options: Options = Options()): Skybox {
val nativeEngine = engine.nativeObject
val nativeSkybox = nCreateSkybox(nativeEngine, buffer, buffer.remaining(), options.srgb)
return Skybox(engine, nativeSkybox)
return Skybox(nativeSkybox)
}
private external fun nCreateTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
/**
* Retrieves spherical harmonics from the content of a KTX file.
*
* @param buffer The content of the KTX File.
* @return The resulting array of 9 * 3 floats, or null on failure.
*/
fun getSphericalHarmonics(buffer: Buffer): FloatArray? {
val sphericalHarmonics = FloatArray(9 * 3)
val success = nGetSphericalHarmonics(buffer, buffer.remaining(), sphericalHarmonics)
return if (success) sphericalHarmonics else null
}
private external fun nCreateKTXTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
private external fun nCreateIndirectLight(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
private external fun nGetSphericalHarmonics(buffer: Buffer, remaining: Int, outSphericalHarmonics: FloatArray): Boolean
private external fun nCreateSkybox(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
}
@@ -32,7 +32,9 @@ import androidx.annotation.Size;
* @see Bookmark
*/
public class Manipulator {
private long mNativeObject;
private static final Mode[] sModeValues = Mode.values();
private final long mNativeObject;
private Manipulator(long nativeIndexBuffer) {
mNativeObject = nativeIndexBuffer;
@@ -199,7 +201,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightStartPosition(float x, float y, float z) {
nFlightStartPosition(mNativeBuilder, x, y, z);
nBuilderFlightStartPosition(mNativeBuilder, x, y, z);
return this;
}
@@ -209,7 +211,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightStartOrientation(float pitch, float yaw) {
nFlightStartOrientation(mNativeBuilder, pitch, yaw);
nBuilderFlightStartOrientation(mNativeBuilder, pitch, yaw);
return this;
}
@@ -220,7 +222,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightMaxMoveSpeed(float maxSpeed) {
nFlightMaxMoveSpeed(mNativeBuilder, maxSpeed);
nBuilderFlightMaxMoveSpeed(mNativeBuilder, maxSpeed);
return this;
}
@@ -231,7 +233,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightSpeedSteps(int steps) {
nFlightSpeedSteps(mNativeBuilder, steps);
nBuilderFlightSpeedSteps(mNativeBuilder, steps);
return this;
}
@@ -242,7 +244,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightPanSpeed(float x, float y) {
nFlightPanSpeed(mNativeBuilder, x, y);
nBuilderFlightPanSpeed(mNativeBuilder, x, y);
return this;
}
@@ -255,7 +257,7 @@ public class Manipulator {
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightMoveDamping(float damping) {
nFlightMoveDamping(mNativeBuilder, damping);
nBuilderFlightMoveDamping(mNativeBuilder, damping);
return this;
}
@@ -320,7 +322,7 @@ public class Manipulator {
/**
* Gets the immutable mode of the manipulator.
*/
public Mode getMode() { return Mode.values()[nGetMode(mNativeObject)]; }
public Mode getMode() { return sModeValues[nGetMode(mNativeObject)]; }
/**
* Sets the viewport dimensions in terms of pixels.
@@ -474,12 +476,12 @@ public class Manipulator {
private static native void nBuilderFarPlane(long nativeBuilder, float distance);
private static native void nBuilderMapExtent(long nativeBuilder, float width, float height);
private static native void nBuilderMapMinDistance(long nativeBuilder, float arg);
private static native void nFlightStartPosition(long nativeBuilder, float x, float y, float z);
private static native void nFlightStartOrientation(long nativeBuilder, float pitch, float yaw);
private static native void nFlightMaxMoveSpeed(long nativeBuilder, float maxSpeed);
private static native void nFlightSpeedSteps(long nativeBuilder, int steps);
private static native void nFlightPanSpeed(long nativeBuilder, float x, float y);
private static native void nFlightMoveDamping(long nativeBuilder, float damping);
private static native void nBuilderFlightStartPosition(long nativeBuilder, float x, float y, float z);
private static native void nBuilderFlightStartOrientation(long nativeBuilder, float pitch, float yaw);
private static native void nBuilderFlightMaxMoveSpeed(long nativeBuilder, float maxSpeed);
private static native void nBuilderFlightSpeedSteps(long nativeBuilder, int steps);
private static native void nBuilderFlightPanSpeed(long nativeBuilder, float x, float y);
private static native void nBuilderFlightMoveDamping(long nativeBuilder, float damping);
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
private static native long nBuilderBuild(long nativeBuilder, int mode);
@@ -80,18 +80,22 @@ data class Mat2(
operator fun times(v: Float) = Mat2(x * v, y * v)
operator fun div(v: Float) = Mat2(x / v, y / v)
operator fun times(m: Mat2): Mat2 {
val t = transpose(this)
return Mat2(
Float2(dot(t.x, m.x), dot(t.y, m.x)),
Float2(dot(t.x, m.y), dot(t.y, m.y))
)
}
operator fun times(m: Mat2) = Mat2(
Float2(
x.x * m.x.x + y.x * m.x.y,
x.y * m.x.x + y.y * m.x.y,
),
Float2(
x.x * m.y.x + y.x * m.y.y,
x.y * m.y.x + y.y * m.y.y,
)
)
operator fun times(v: Float2) = Float2(
x.x * v.x + y.x * v.y,
x.y * v.x + y.y * v.y,
)
operator fun times(v: Float2): Float2 {
val t = transpose(this)
return Float2(dot(t.x, v), dot(t.y, v))
}
fun toFloatArray() = floatArrayOf(
x.x, y.x,
@@ -171,19 +175,29 @@ data class Mat3(
operator fun times(v: Float) = Mat3(x * v, y * v, z * v)
operator fun div(v: Float) = Mat3(x / v, y / v, z / v)
operator fun times(m: Mat3): Mat3 {
val t = transpose(this)
return Mat3(
Float3(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x)),
Float3(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y)),
Float3(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z))
)
}
operator fun times(m: Mat3) = Mat3(
Float3(
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z,
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z,
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z,
),
Float3(
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z,
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z,
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z,
),
Float3(
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z,
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z,
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z,
)
)
operator fun times(v: Float3): Float3 {
val t = transpose(this)
return Float3(dot(t.x, v), dot(t.y, v), dot(t.z, v))
}
operator fun times(v: Float3) = Float3(
x.x * v.x + y.x * v.y + z.x * v.z,
x.y * v.x + y.y * v.y + z.y * v.z,
x.z * v.x + y.z * v.y + z.z * v.z,
)
fun toFloatArray() = floatArrayOf(
x.x, y.x, z.x,
@@ -313,20 +327,39 @@ data class Mat4(
operator fun times(v: Float) = Mat4(x * v, y * v, z * v, w * v)
operator fun div(v: Float) = Mat4(x / v, y / v, z / v, w / v)
operator fun times(m: Mat4): Mat4 {
val t = transpose(this)
return Mat4(
Float4(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x), dot(t.w, m.x)),
Float4(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y), dot(t.w, m.y)),
Float4(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z), dot(t.w, m.z)),
Float4(dot(t.x, m.w), dot(t.y, m.w), dot(t.z, m.w), dot(t.w, m.w))
)
}
operator fun times(m: Mat4) = Mat4(
Float4(
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z + w.x * m.x.w,
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z + w.y * m.x.w,
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z + w.z * m.x.w,
x.w * m.x.x + y.w * m.x.y + z.w * m.x.z + w.w * m.x.w,
),
Float4(
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z + w.x * m.y.w,
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z + w.y * m.y.w,
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z + w.z * m.y.w,
x.w * m.y.x + y.w * m.y.y + z.w * m.y.z + w.w * m.y.w,
),
Float4(
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z + w.x * m.z.w,
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z + w.y * m.z.w,
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z + w.z * m.z.w,
x.w * m.z.x + y.w * m.z.y + z.w * m.z.z + w.w * m.z.w,
),
Float4(
x.x * m.w.x + y.x * m.w.y + z.x * m.w.z + w.x * m.w.w,
x.y * m.w.x + y.y * m.w.y + z.y * m.w.z + w.y * m.w.w,
x.z * m.w.x + y.z * m.w.y + z.z * m.w.z + w.z * m.w.w,
x.w * m.w.x + y.w * m.w.y + z.w * m.w.z + w.w * m.w.w,
)
)
operator fun times(v: Float4): Float4 {
val t = transpose(this)
return Float4(dot(t.x, v), dot(t.y, v), dot(t.z, v), dot(t.w, v))
}
operator fun times(v: Float4) = Float4(
x.x * v.x + y.x * v.y + z.x * v.z+ w.x * v.w,
x.y * v.x + y.y * v.y + z.y * v.z+ w.y * v.w,
x.z * v.x + y.z * v.y + z.z * v.z+ w.z * v.w,
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
)
fun toFloatArray() = floatArrayOf(
x.x, y.x, z.x, w.x,
@@ -355,6 +388,8 @@ fun transpose(m: Mat3) = Mat3(
Float3(m.x.y, m.y.y, m.z.y),
Float3(m.x.z, m.y.z, m.z.z)
)
@Suppress("LocalVariableName")
fun inverse(m: Mat3): Mat3 {
val a = m.x.x
val b = m.x.y
@@ -385,6 +420,7 @@ fun transpose(m: Mat4) = Mat4(
Float4(m.x.z, m.y.z, m.z.z, m.w.z),
Float4(m.x.w, m.y.w, m.z.w, m.w.w)
)
fun inverse(m: Mat4): Mat4 {
val result = Mat4()
@@ -462,8 +498,8 @@ 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) })
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,
@@ -27,9 +27,8 @@ import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
private const val kNearPlane = 0.5
private const val kFarPlane = 10000.0
private const val kFovDegrees = 45.0
private const val kNearPlane = 0.05 // 5 cm
private const val kFarPlane = 1000.0 // 1 km
private const val kAperture = 16f
private const val kShutterSpeed = 1f / 125f
private const val kSensitivity = 100f
@@ -59,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
@@ -72,13 +74,20 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
var normalizeSkinningWeights = true
var recomputeBoundingBoxes = false
var ignoreBindTransform = false
var cameraFocalLength = 28f
set(value) {
field = value
updateCameraProjection()
}
val scene: Scene
val view: View
val camera: Camera
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
@@ -87,7 +96,6 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
private var fetchResourcesJob: Job? = null
private val renderer: Renderer
private var swapChain: SwapChain? = null
private var assetLoader: AssetLoader
private var resourceLoader: ResourceLoader
@@ -100,13 +108,13 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
init {
renderer = engine.createRenderer()
scene = engine.createScene()
camera = engine.createCamera().apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
camera = engine.createCamera(engine.entityManager.create()).apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
view = engine.createView()
view.scene = scene
view.camera = camera
assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
assetLoader = AssetLoader(engine, UbershaderLoader(engine), 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.
@@ -124,7 +132,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)
@@ -139,7 +152,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)
@@ -171,12 +189,17 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
*
* The given callback is triggered for each requested resource.
*/
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer) {
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer?) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
asset?.let { asset ->
for (uri in asset.resourceUris) {
resourceLoader.addResourceData(uri, callback(uri))
val resourceBuffer = callback(uri)
if (resourceBuffer == null) {
this.asset = null
return
}
resourceLoader.addResourceData(uri, resourceBuffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
@@ -205,8 +228,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
@@ -215,12 +238,23 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
}
}
/**
* Removes the transformation that was set up via transformToUnitCube.
*/
fun clearRootTransform() {
asset?.let {
val tm = engine.transformManager
tm.setTransform(tm.getInstance(it.root), Mat4().toFloatArray())
}
}
/**
* Frees all entities associated with the most recently-loaded model.
*/
fun destroyModel() {
fetchResourcesJob?.cancel()
resourceLoader.asyncCancelLoad()
resourceLoader.evictResourceData()
asset?.let { asset ->
this.scene.removeEntities(asset.entities)
assetLoader.destroyAsset(asset)
@@ -261,9 +295,14 @@ 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) {
val ri = rcm.getInstance(readyRenderables[i])
rcm.setScreenSpaceContactShadows(ri, true)
}
scene.addEntities(readyRenderables.take(count).toIntArray())
}
scene.addEntities(asset.lightEntities)
@@ -283,7 +322,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
engine.destroyRenderer(renderer)
engine.destroyView(this@ModelViewer.view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
EntityManager.get().destroy(camera.entity)
EntityManager.get().destroy(light)
@@ -322,6 +362,13 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
}
}
private fun updateCameraProjection() {
val width = view.viewport.width
val height = view.viewport.height
val aspect = width.toDouble() / height.toDouble()
camera.setLensProjection(cameraFocalLength.toDouble(), aspect, kNearPlane, kFarPlane)
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
@@ -341,13 +388,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
override fun onResized(width: Int, height: Int) {
view.viewport = Viewport(0, 0, width, height)
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(kFovDegrees, aspect, kNearPlane, kFarPlane, Camera.Fov.VERTICAL)
cameraManipulator.setViewport(width, height)
updateCameraProjection()
}
}
companion object {
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
}
}
}
@@ -0,0 +1,106 @@
/*
* 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.
*/
package com.google.android.filament.utils;
import androidx.annotation.Nullable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Manages a tiny WebSocket server that can receive model data and viewer settings.
*
* Client apps can call acquireReceivedMessage to check for new data and pop it off the small
* internal queue.
*/
public class RemoteServer {
private long mNativeObject;
/**
* Encapsulates a message sent from the web client.
*/
public static class ReceivedMessage {
public String label;
public ByteBuffer buffer;
}
public RemoteServer(int port) {
mNativeObject = nCreate(port);
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create RemoteServer");
}
/**
* Checks if a download is currently in progress and returns its label.
* Returns null if nothing is being downloaded.
*/
public @Nullable String peekIncomingLabel() {
return nPeekIncomingLabel(mNativeObject);
}
/**
* Checks if a peeked message has JSON content.
*/
public static boolean isJson(@Nullable String label) {
return label != null && label.endsWith(".json");
}
/**
* Checks if a peeked message has binary content.
*/
public static boolean isBinary(@Nullable String label) {
return label != null && !label.endsWith(".json");
}
/**
* Pops a message off the incoming queue or returns null if there are no unread messages.
*/
public @Nullable ReceivedMessage acquireReceivedMessage() {
int length = nPeekReceivedBufferLength(mNativeObject);
if (length == 0) {
return null;
}
ReceivedMessage message = new ReceivedMessage();
message.label = nPeekReceivedLabel(mNativeObject);
message.buffer = ByteBuffer.allocateDirect(length);
message.buffer.order(ByteOrder.LITTLE_ENDIAN);
nAcquireReceivedMessage(mNativeObject, message.buffer, length);
return message;
}
/*
* Destroys the native WebSocket server and frees up the port.
*
* This might need to be done explicitly (as opposed to waiting for gc) to free up the port.
*/
public void close() {
nDestroy(mNativeObject);
mNativeObject = 0;
}
@Override
protected void finalize() throws Throwable {
nDestroy(mNativeObject);
super.finalize();
}
private static native long nCreate(int port);
private static native String nPeekIncomingLabel(long nativeObject);
private static native String nPeekReceivedLabel(long nativeObject);
private static native int nPeekReceivedBufferLength(long nativeObject);
private static native void nAcquireReceivedMessage(long nativeObject, ByteBuffer buffer, int length);
private static native void nDestroy(long nativeObject);
}
+11 -2
View File
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.6)
cmake_minimum_required(VERSION 3.19)
project(gltfio-android)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(GLTFIO_DIR ../../libs/gltfio)
@@ -44,7 +45,11 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/src/FilamentInstance.cpp
${GLTFIO_DIR}/src/GltfEnums.h
${GLTFIO_DIR}/src/MaterialProvider.cpp
${GLTFIO_DIR}/src/MorphHelper.h
${GLTFIO_DIR}/src/MorphHelper.cpp
${GLTFIO_DIR}/src/ResourceLoader.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
@@ -56,7 +61,9 @@ set(GLTFIO_SRCS
src/main/cpp/AssetLoader.cpp
src/main/cpp/FilamentAsset.cpp
src/main/cpp/FilamentInstance.cpp
src/main/cpp/MaterialProvider.cpp
src/main/cpp/MaterialKey.cpp
src/main/cpp/MaterialKey.h
src/main/cpp/UbershaderLoader.cpp
src/main/cpp/ResourceLoader.cpp
${FILAMENT_DIR}/include/gltfio/resources/gltfresources_lite.h
@@ -69,6 +76,8 @@ set(GLTFIO_INCLUDE_DIRS
..
${FILAMENT_DIR}/include
${FILAMENT_DIR}/include/gltfio/resources
../../filament/backend/include
../../libs/gltfio/include
../../third_party/cgltf
../../third_party/robin-map
../../third_party/hat-trie
+2 -1
View File
@@ -27,7 +27,8 @@ android {
dependencies {
implementation deps.androidx.annotations
implementation project(':filament-android')
api project(':filament-android')
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* 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.
@@ -23,27 +23,178 @@
#include <gltfio/AssetLoader.h>
#include <gltfio/MaterialProvider.h>
#include <utils/debug.h>
#include "common/NioUtils.h"
#include "MaterialKey.h"
using namespace filament;
using namespace gltfio;
using namespace utils;
class JavaMaterialProvider : public MaterialProvider {
JNIEnv* const mEnv;
const jobject mJavaProvider;
mutable Material** mPreviousMaterials = nullptr;
jclass mMaterialKeyClass;
jmethodID mMaterialKeyConstructor;
jmethodID mCreateMaterialInstance;
jmethodID mGetMaterials;
jmethodID mNeedsDummyData;
jmethodID mDestroyMaterials;
jmethodID mMaterialInstanceGetNativeObject;
jmethodID mMaterialGetNativeObject;
public:
JavaMaterialProvider(JNIEnv* env, jobject provider) : mEnv(env),
mJavaProvider(env->NewGlobalRef(provider)) {
mMaterialKeyClass = env->FindClass(JAVA_MATERIAL_KEY);
mMaterialKeyClass = (jclass) env->NewGlobalRef(mMaterialKeyClass);
assert_invariant(mMaterialKeyClass);
mMaterialKeyConstructor = env->GetMethodID(mMaterialKeyClass, "<init>", "()V");
assert_invariant(mMaterialKeyConstructor);
jclass materialInstanceClass = env->FindClass("com/google/android/filament/MaterialInstance");
mMaterialInstanceGetNativeObject = env->GetMethodID(materialInstanceClass, "getNativeObject", "()J");
assert_invariant(mMaterialInstanceGetNativeObject);
jclass materialClass = env->FindClass("com/google/android/filament/Material");
mMaterialGetNativeObject = env->GetMethodID(materialClass, "getNativeObject", "()J");
assert_invariant(mMaterialGetNativeObject);
jclass providerClass = env->GetObjectClass(provider);
mCreateMaterialInstance = env->GetMethodID(providerClass, "createMaterialInstance",
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
assert_invariant(mCreateMaterialInstance);
mGetMaterials = env->GetMethodID(providerClass, "getMaterials",
"()[Lcom/google/android/filament/Material;");
assert_invariant(mGetMaterials);
mNeedsDummyData = env->GetMethodID(providerClass, "needsDummyData","(I)Z");
assert_invariant(mNeedsDummyData);
mDestroyMaterials = env->GetMethodID(providerClass, "destroyMaterials", "()V");
assert_invariant(mDestroyMaterials);
}
~JavaMaterialProvider() override {
mEnv->DeleteGlobalRef(mMaterialKeyClass);
mEnv->DeleteGlobalRef(mJavaProvider);
delete mPreviousMaterials;
}
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label) override {
// Create a Java object for the material key and copy the native fields into it.
jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor);
auto& helper = MaterialKeyHelper::get();
helper.copy(mEnv, javaKey, *config);
// Convert the optional label into a Java string.
jstring stringLabel = label ? mEnv->NewStringUTF(label) : 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);
// Copy the UvMap results from the JVM array into the native array.
if (uvmap) {
jint* elements = mEnv->GetIntArrayElements(uvMapArray, nullptr);
for (size_t i = 0; i < uvmap->size(); i++) {
(*uvmap)[i] = (UvSet) elements[i];
}
mEnv->ReleaseIntArrayElements(uvMapArray, elements, JNI_ABORT);
}
// The config parameter is an in-out parameter so we need to copy the results from Java.
helper.copy(mEnv, *config, javaKey);
mEnv->DeleteLocalRef(javaKey);
mEnv->DeleteLocalRef(uvMapArray);
if (stringLabel) {
mEnv->DeleteLocalRef(stringLabel);
}
if (materialInstance == nullptr) {
return nullptr;
}
return (MaterialInstance*) mEnv->CallLongMethod(materialInstance, mMaterialInstanceGetNativeObject);
}
const Material* const* getMaterials() const noexcept override {
jobjectArray javaMaterials = (jobjectArray) mEnv->CallObjectMethod(mJavaProvider, mGetMaterials);
const size_t count = mEnv->GetArrayLength(javaMaterials);
delete mPreviousMaterials;
using MaterialPointer = Material*;
mPreviousMaterials = new MaterialPointer[count];
// Call "getNativeObject" on each material in order to pass them up into the native layer.
for (size_t i = 0; i < count; ++i) {
jobject javaMaterial = mEnv->GetObjectArrayElement(javaMaterials, i);
jlong matPointer = mEnv->CallLongMethod(javaMaterial, mMaterialGetNativeObject);
mPreviousMaterials[i] = (Material*) matPointer;
}
return mPreviousMaterials;
}
size_t getMaterialsCount() const noexcept override {
jobjectArray javaMaterials = (jobjectArray) mEnv->CallObjectMethod(mJavaProvider, mGetMaterials);
return mEnv->GetArrayLength(javaMaterials);
}
void destroyMaterials() override {
mEnv->CallObjectMethod(mJavaProvider, mDestroyMaterials);
}
bool needsDummyData(VertexAttribute attrib) const noexcept override {
return mEnv->CallBooleanMethod(mJavaProvider, mNeedsDummyData, (int) attrib);
}
};
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeProvider, jlong nativeEntities) {
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv* env, jclass,
jlong nativeEngine, jobject provider, jlong nativeEntities) {
Engine* engine = (Engine*) nativeEngine;
MaterialProvider* materials = (MaterialProvider*) nativeProvider;
MaterialProvider* materialProvider = nullptr;
// First check for a fast path that passes a native MaterialProvider into the loader.
// This drastically reduces the number of JNI calls while the asset is being loaded.
jclass klass = env->GetObjectClass(provider);
jmethodID getNativeObject = env->GetMethodID(klass, "getNativeObject", "()J");
if (getNativeObject) {
materialProvider = (MaterialProvider*) env->CallLongMethod(provider, getNativeObject);
} else {
env->ExceptionClear();
}
if (materialProvider == nullptr) {
materialProvider = new JavaMaterialProvider(env, provider);
}
EntityManager* entities = (EntityManager*) nativeEntities;
NameComponentManager* names = new NameComponentManager(*entities);
return (jlong) AssetLoader::create({engine, materials, names, entities});
return (jlong) AssetLoader::create({engine, materialProvider, names, entities});
}
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;
@@ -88,6 +239,14 @@ Java_com_google_android_filament_gltfio_AssetLoader_nCreateInstancedAsset(JNIEnv
return asset;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateInstance(JNIEnv* env, jclass,
jlong nativeLoader, jlong nativeAsset) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
FilamentAsset* primary = (FilamentAsset*) nativeAsset;
return (jlong) loader->createInstance(primary);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nEnableDiagnostics(JNIEnv*, jclass,
jlong nativeLoader, jboolean enable) {
@@ -192,6 +192,15 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetName(JNIEnv* env, jcla
return val ? env->NewStringUTF(val) : nullptr;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jclass,
jlong nativeAsset, jint entityId) {
Entity entity = Entity::import(entityId);
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const auto val = asset->getExtras(entity);
return val ? env->NewStringUTF(val) : nullptr;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
jlong nativeAsset) {
@@ -0,0 +1,177 @@
/*
* 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 <gltfio/MaterialProvider.h>
#include "MaterialKey.h"
using namespace gltfio;
MaterialKeyHelper& MaterialKeyHelper::get() {
static MaterialKeyHelper helper;
return helper;
}
void MaterialKeyHelper::init(JNIEnv* env) {
const jclass materialKeyClass = env->FindClass(JAVA_MATERIAL_KEY);
auto field = [materialKeyClass, env](const char* fieldName, const char* signature) {
return env->GetFieldID(materialKeyClass, fieldName, signature);
};
doubleSided = field("doubleSided", "Z");
unlit = field("unlit", "Z");
hasVertexColors = field("hasVertexColors", "Z");
hasBaseColorTexture = field("hasBaseColorTexture", "Z");
hasNormalTexture = field("hasNormalTexture", "Z");
hasOcclusionTexture = field("hasOcclusionTexture", "Z");
hasEmissiveTexture = field("hasEmissiveTexture", "Z");
useSpecularGlossiness = field("useSpecularGlossiness", "Z");
alphaMode = field("alphaMode", "I");
enableDiagnostics = field("enableDiagnostics", "Z");
hasMetallicRoughnessTexture = field("hasMetallicRoughnessTexture", "Z");
metallicRoughnessUV = field("metallicRoughnessUV", "I");
baseColorUV = field("baseColorUV", "I");
hasClearCoatTexture = field("hasClearCoatTexture", "Z");
clearCoatUV = field("clearCoatUV", "I");
hasClearCoatRoughnessTexture = field("hasClearCoatRoughnessTexture", "Z");
clearCoatRoughnessUV = field("clearCoatRoughnessUV", "I");
hasClearCoatNormalTexture = field("hasClearCoatNormalTexture", "Z");
clearCoatNormalUV = field("clearCoatNormalUV", "I");
hasClearCoat = field("hasClearCoat", "Z");
hasTransmission = field("hasTransmission", "Z");
hasTextureTransforms = field("hasTextureTransforms", "Z");
emissiveUV = field("emissiveUV", "I");
aoUV = field("aoUV", "I");
normalUV = field("normalUV", "I");
hasTransmissionTexture = field("hasTransmissionTexture", "Z");
transmissionUV = field("transmissionUV", "I");
hasSheenColorTexture = field("hasSheenColorTexture", "Z");
sheenColorUV = field("sheenColorUV", "I");
hasSheenRoughnessTexture = field("hasSheenRoughnessTexture", "Z");
sheenRoughnessUV = field("sheenRoughnessUV", "I");
hasVolumeThicknessTexture = field("hasVolumeThicknessTexture", "Z");
volumeThicknessUV = field("volumeThicknessUV", "I");
hasSheen = field("hasSheen", "Z");
hasIOR = field("hasIOR", "Z");
}
void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) {
dst.doubleSided = env->GetBooleanField(src, doubleSided);
dst.unlit = env->GetBooleanField(src, unlit);
dst.hasVertexColors = env->GetBooleanField(src, hasVertexColors);
dst.hasBaseColorTexture = env->GetBooleanField(src, hasBaseColorTexture);
dst.hasNormalTexture = env->GetBooleanField(src, hasNormalTexture);
dst.hasOcclusionTexture = env->GetBooleanField(src, hasOcclusionTexture);
dst.hasEmissiveTexture = env->GetBooleanField(src, hasEmissiveTexture);
dst.useSpecularGlossiness = env->GetBooleanField(src, useSpecularGlossiness);
dst.alphaMode = (AlphaMode) env->GetIntField(src, alphaMode);
dst.enableDiagnostics = env->GetBooleanField(src, enableDiagnostics);
dst.hasMetallicRoughnessTexture = env->GetBooleanField(src, hasMetallicRoughnessTexture);
dst.metallicRoughnessUV = env->GetIntField(src, metallicRoughnessUV);
dst.baseColorUV = env->GetIntField(src, baseColorUV);
dst.hasClearCoatTexture = env->GetBooleanField(src, hasClearCoatTexture);
dst.clearCoatUV = env->GetIntField(src, clearCoatUV);
dst.hasClearCoatRoughnessTexture = env->GetBooleanField(src, hasClearCoatRoughnessTexture);
dst.clearCoatRoughnessUV = env->GetIntField(src, clearCoatRoughnessUV);
dst.hasClearCoatNormalTexture = env->GetBooleanField(src, hasClearCoatNormalTexture);
dst.clearCoatNormalUV = env->GetIntField(src, clearCoatNormalUV);
dst.hasClearCoat = env->GetBooleanField(src, hasClearCoat);
dst.hasTransmission = env->GetBooleanField(src, hasTransmission);
dst.hasTextureTransforms = env->GetBooleanField(src, hasTextureTransforms);
dst.emissiveUV = env->GetIntField(src, emissiveUV);
dst.aoUV = env->GetIntField(src, aoUV);
dst.normalUV = env->GetIntField(src, normalUV);
dst.hasTransmissionTexture = env->GetBooleanField(src, hasTransmissionTexture);
dst.transmissionUV = env->GetIntField(src, transmissionUV);
dst.hasSheenColorTexture = env->GetBooleanField(src, hasSheenColorTexture);
dst.sheenColorUV = env->GetIntField(src, sheenColorUV);
dst.hasSheenRoughnessTexture = env->GetBooleanField(src, hasSheenRoughnessTexture);
dst.sheenRoughnessUV = env->GetIntField(src, sheenRoughnessUV);
dst.hasVolumeThicknessTexture = env->GetBooleanField(src, hasVolumeThicknessTexture);
dst.volumeThicknessUV = env->GetIntField(src, volumeThicknessUV);
dst.hasSheen = env->GetBooleanField(src, hasSheen);
dst.hasIOR = env->GetBooleanField(src, hasIOR);
}
void MaterialKeyHelper::copy(JNIEnv* env, jobject dst, const MaterialKey& src) {
env->SetBooleanField(dst, doubleSided, src.doubleSided);
env->SetBooleanField(dst, unlit, src.unlit);
env->SetBooleanField(dst, hasVertexColors, src.hasVertexColors);
env->SetBooleanField(dst, hasBaseColorTexture, src.hasBaseColorTexture);
env->SetBooleanField(dst, hasNormalTexture, src.hasNormalTexture);
env->SetBooleanField(dst, hasOcclusionTexture, src.hasOcclusionTexture);
env->SetBooleanField(dst, hasEmissiveTexture, src.hasEmissiveTexture);
env->SetBooleanField(dst, useSpecularGlossiness, src.useSpecularGlossiness);
env->SetIntField(dst, alphaMode, (int) src.alphaMode);
env->SetBooleanField(dst, enableDiagnostics, src.enableDiagnostics);
env->SetBooleanField(dst, hasMetallicRoughnessTexture, src.hasMetallicRoughnessTexture);
env->SetIntField(dst, metallicRoughnessUV, src.metallicRoughnessUV);
env->SetIntField(dst, baseColorUV, src.baseColorUV);
env->SetBooleanField(dst, hasClearCoatTexture, src.hasClearCoatTexture);
env->SetIntField(dst, clearCoatUV, src.clearCoatUV);
env->SetBooleanField(dst, hasClearCoatRoughnessTexture, src.hasClearCoatRoughnessTexture);
env->SetIntField(dst, clearCoatRoughnessUV, src.clearCoatRoughnessUV);
env->SetBooleanField(dst, hasClearCoatNormalTexture, src.hasClearCoatNormalTexture);
env->SetIntField(dst, clearCoatNormalUV, src.clearCoatNormalUV);
env->SetBooleanField(dst, hasClearCoat, src.hasClearCoat);
env->SetBooleanField(dst, hasTransmission, src.hasTransmission);
env->SetBooleanField(dst, hasTextureTransforms, src.hasTextureTransforms);
env->SetIntField(dst, emissiveUV, src.emissiveUV);
env->SetIntField(dst, aoUV, src.aoUV);
env->SetIntField(dst, normalUV, src.normalUV);
env->SetBooleanField(dst, hasTransmissionTexture, src.hasTransmissionTexture);
env->SetIntField(dst, transmissionUV, src.transmissionUV);
env->SetBooleanField(dst, hasSheenColorTexture, src.hasSheenColorTexture);
env->SetIntField(dst, sheenColorUV, src.sheenColorUV);
env->SetBooleanField(dst, hasSheenRoughnessTexture, src.hasSheenRoughnessTexture);
env->SetIntField(dst, sheenRoughnessUV, src.sheenRoughnessUV);
env->SetBooleanField(dst, hasVolumeThicknessTexture, src.hasVolumeThicknessTexture);
env->SetIntField(dst, volumeThicknessUV, src.volumeThicknessUV);
env->SetBooleanField(dst, hasSheen, src.hasSheen);
env->SetBooleanField(dst, hasIOR, src.hasIOR);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) {
MaterialKeyHelper::get().init(env);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nConstrainMaterial(JNIEnv* env, jclass,
jobject materialKey, jintArray uvMap) {
MaterialKey nativeMaterialKey = {};
auto& helper = MaterialKeyHelper::get();
helper.copy(env, nativeMaterialKey, materialKey);
UvMap nativeUvMap = {};
constrainMaterial(&nativeMaterialKey, &nativeUvMap);
// Copy the UvMap results from the native array into the JVM array.
jint* elements = env->GetIntArrayElements(uvMap, nullptr);
if (elements) {
const size_t javaSize = env->GetArrayLength(uvMap);
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
elements[i] = nativeUvMap[i];
}
env->ReleaseIntArrayElements(uvMap, elements, 0);
}
// The config parameter is an in-out parameter so we need to copy the results back to Java.
helper.copy(env, materialKey, nativeMaterialKey);
}
@@ -0,0 +1,68 @@
/*
* 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 <gltfio/MaterialProvider.h>
#define JAVA_MATERIAL_KEY "com/google/android/filament/gltfio/MaterialProvider$MaterialKey"
class MaterialKeyHelper {
public:
static MaterialKeyHelper& get();
void copy(JNIEnv* env, gltfio::MaterialKey& dst, jobject src);
void copy(JNIEnv* env, jobject dst, const gltfio::MaterialKey& src);
void init(JNIEnv* env); // called only from the Java static class constructor
private:
jfieldID doubleSided;
jfieldID unlit;
jfieldID hasVertexColors;
jfieldID hasBaseColorTexture;
jfieldID hasNormalTexture;
jfieldID hasOcclusionTexture;
jfieldID hasEmissiveTexture;
jfieldID useSpecularGlossiness;
jfieldID alphaMode;
jfieldID enableDiagnostics;
jfieldID hasMetallicRoughnessTexture;
jfieldID metallicRoughnessUV;
jfieldID baseColorUV;
jfieldID hasClearCoatTexture;
jfieldID clearCoatUV;
jfieldID hasClearCoatRoughnessTexture;
jfieldID clearCoatRoughnessUV;
jfieldID hasClearCoatNormalTexture;
jfieldID clearCoatNormalUV;
jfieldID hasClearCoat;
jfieldID hasTransmission;
jfieldID hasTextureTransforms;
jfieldID emissiveUV;
jfieldID aoUV;
jfieldID normalUV;
jfieldID hasTransmissionTexture;
jfieldID transmissionUV;
jfieldID hasSheenColorTexture;
jfieldID sheenColorUV;
jfieldID hasSheenRoughnessTexture;
jfieldID sheenRoughnessUV;
jfieldID hasVolumeThicknessTexture;
jfieldID volumeThicknessUV;
jfieldID hasSheen;
jfieldID hasIOR;
};
@@ -1,43 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <gltfio/MaterialProvider.h>
using namespace filament;
using namespace gltfio;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nCreateMaterialProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createUbershaderLoader(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterialProvider(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
delete provider;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterials(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
provider->destroyMaterials();
}
@@ -35,10 +35,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
@@ -70,6 +71,13 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nHasResourceData(JNIEnv*
return status;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nEvictResourceData(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->evictResourceData();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nLoadResources(JNIEnv*, jclass,
jlong nativeLoader, jlong nativeAsset) {
@@ -0,0 +1,102 @@
/*
* 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 <gltfio/MaterialProvider.h>
#include <utils/debug.h>
#include "MaterialKey.h"
using namespace filament;
using namespace gltfio;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateUbershaderLoader(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createUbershaderLoader(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyUbershaderLoader(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
delete provider;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyMaterials(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
provider->destroyMaterials();
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance(JNIEnv* env, jclass,
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) {
MaterialKey nativeKey = {};
auto& helper = MaterialKeyHelper::get();
helper.copy(env, nativeKey, materialKey);
const char* nativeLabel = label ? env->GetStringUTFChars(label, nullptr) : nullptr;
UvMap nativeUvMap = {};
auto provider = (MaterialProvider*) nativeProvider;
MaterialInstance* instance = provider->createMaterialInstance(&nativeKey, &nativeUvMap, nativeLabel);
// Copy the UvMap results from the native array into the JVM array.
jint* elements = env->GetIntArrayElements(uvmap, nullptr);
if (elements) {
const size_t javaSize = env->GetArrayLength(uvmap);
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
elements[i] = nativeUvMap[i];
}
env->ReleaseIntArrayElements(uvmap, elements, 0);
}
// The config parameter is an in-out parameter so we need to copy the results back to Java.
helper.copy(env, materialKey, nativeKey);
if (label) {
env->ReleaseStringUTFChars(label, nativeLabel);
}
return (long) instance;
}
extern "C" JNIEXPORT int JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterialCount(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
return provider->getMaterialsCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterials(JNIEnv* env, jclass,
jlong nativeProvider, jlongArray result) {
auto provider = (MaterialProvider *) nativeProvider;
auto materials = provider->getMaterials();
jlong *resultElements = env->GetLongArrayElements(result, nullptr);
if (resultElements) {
const size_t javaSize = env->GetArrayLength(result);
for (int i = 0, n = std::min(javaSize, provider->getMaterialsCount()); i < n; ++i) {
resultElements[i] = (jlong) materials[i];
}
env->ReleaseLongArrayElements(result, resultElements, JNI_ABORT);
}
}
@@ -45,7 +45,7 @@ import java.nio.Buffer;
*
* ...
*
* assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
* assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
*
* filamentAsset = assets.open("models/lucy.gltf").use { input -&gt;
* val bytes = ByteArray(input.available())
@@ -85,31 +85,30 @@ public class AssetLoader {
* {@link FilamentAsset}.
*
* @param engine the engine that the loader should pass to builder objects
* @param generator specifies if materials should be generated or loaded from a pre-built set
* @param provider an object that provides Filament materials corresponding to glTF materials
* @param entities the EntityManager that should be used to create entities
*/
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider generator,
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider provider,
@NonNull EntityManager entities) {
long nativeEngine = engine.getNativeObject();
long nativeMaterials = generator.getNativeObject();
long nativeEntities = entities.getNativeObject();
mNativeObject = nCreateAssetLoader(nativeEngine, nativeMaterials, nativeEntities);
mNativeObject = nCreateAssetLoader(nativeEngine, provider, nativeEntities);
if (mNativeObject == 0) {
throw new IllegalStateException("Unable to parse glTF asset.");
}
mEngine = engine;
mMaterialCache = generator;
mMaterialCache = provider;
}
/**
* Frees all memory consumed by the native <code>AssetLoader</code> and its material cache.
*/
public void destroy() {
nDestroyAssetLoader(mNativeObject);
mMaterialCache.destroyMaterials();
nDestroyAssetLoader(mNativeObject);
mNativeObject = 0;
}
@@ -149,10 +148,11 @@ public class AssetLoader {
if (nativeAsset == 0) {
return null;
}
FilamentAsset asset = new FilamentAsset(mEngine, nativeAsset);
for (int i = 0; i < nativeInstances.length; i++) {
instances[i] = new FilamentInstance(nativeInstances[i]);
instances[i] = new FilamentInstance(asset, nativeInstances[i]);
}
return new FilamentAsset(mEngine, nativeAsset);
return asset;
}
/**
@@ -178,7 +178,7 @@ public class AssetLoader {
if (nativeInstance == 0) {
return null;
}
return new FilamentInstance(nativeInstance);
return new FilamentInstance(asset, nativeInstance);
}
/**
@@ -197,7 +197,7 @@ public class AssetLoader {
asset.clearNativeObject();
}
private static native long nCreateAssetLoader(long nativeEngine, long nativeGenerator,
private static native long nCreateAssetLoader(long nativeEngine, Object provider,
long nativeEntities);
private static native void nDestroyAssetLoader(long nativeLoader);
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);
@@ -186,6 +186,16 @@ public class FilamentAsset {
return nGetName(getNativeObject(), entity);
}
/**
* Gets the glTF extras string for the asset or a specific node.
*
* @param entity the entity corresponding to the glTF node, or 0 to get the asset-level string.
* @return the requested extras string, or null if it does not exist.
*/
public @Nullable String getExtras(@Entity int entity) {
return nGetExtras(mNativeObject, entity);
}
/**
* Creates or retrieves the <code>Animator</code> interface for this asset.
*
@@ -252,6 +262,7 @@ public class FilamentAsset {
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 int nGetResourceUriCount(long nativeAsset);
private static native void nGetResourceUris(long nativeAsset, String[] result);
@@ -28,10 +28,12 @@ import com.google.android.filament.Entity;
* @see AssetLoader
*/
public class FilamentInstance {
private FilamentAsset mAsset;
private long mNativeObject;
private Animator mAnimator;
FilamentInstance(long nativeObject) {
FilamentInstance(FilamentAsset asset, long nativeObject) {
mAsset = asset;
mNativeObject = nativeObject;
mAnimator = null;
}
@@ -46,6 +48,11 @@ public class FilamentInstance {
mNativeObject = 0;
}
@SuppressWarnings("unused")
public @NonNull FilamentAsset getAsset() {
return mAsset;
}
/**
* Gets the transform root for the asset, which has no matching glTF node.
*/
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* 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.
@@ -16,36 +16,108 @@
package com.google.android.filament.gltfio;
import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import java.lang.reflect.Method;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
/**
* Loads pre-generated ubershader materials that fulfill glTF requirements.
*
* <p>This class is used by {@link AssetLoader} to create Filament materials.
* Client applications do not need to call methods on it.</p>
*/
public class MaterialProvider {
private long mNativeObject;
public interface MaterialProvider {
/**
* Constructs an ubershader loader using the supplied {@link Engine}.
*
* @param engine the engine used to create materials
* MaterialKey specifies the requirements for a requested glTF material.
* The provider creates Filament materials that fulfill these requirements.
*/
public MaterialProvider(Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateMaterialProvider(nativeEngine);
}
public static class MaterialKey {
public boolean doubleSided;
public boolean unlit;
public boolean hasVertexColors;
public boolean hasBaseColorTexture;
public boolean hasNormalTexture;
public boolean hasOcclusionTexture;
public boolean hasEmissiveTexture;
public boolean useSpecularGlossiness;
public int alphaMode; // 0 = OPAQUE, 1 = MASK, 2 = BLEND
public boolean enableDiagnostics;
public boolean hasMetallicRoughnessTexture; // piggybacks with specularRoughness
public int metallicRoughnessUV; // piggybacks with specularRoughness
public int baseColorUV;
public boolean hasClearCoatTexture;
public int clearCoatUV;
public boolean hasClearCoatRoughnessTexture;
public int clearCoatRoughnessUV;
public boolean hasClearCoatNormalTexture;
public int clearCoatNormalUV;
public boolean hasClearCoat;
public boolean hasTransmission;
public boolean hasTextureTransforms;
public int emissiveUV;
public int aoUV;
public int normalUV;
public boolean hasTransmissionTexture;
public int transmissionUV;
public boolean hasSheenColorTexture;
public int sheenColorUV;
public boolean hasSheenRoughnessTexture;
public int sheenRoughnessUV;
public boolean hasVolumeThicknessTexture;
public int volumeThicknessUV;
public boolean hasSheen;
public boolean hasIOR;
public MaterialKey() {}
static {
nGlobalInit();
}
/**
* Populate UV map according to the material key, altering latter if required.
*
* Filament supports up to 2 UV sets. glTF has arbitrary texcoord set indices, but it
* allows implementations to support only 2 simultaneous sets. Here we build a mapping
* table with 1-based indices where 0 means unused. Note that the order in which we drop
* textures can affect the look of certain assets. This "order of degradation" is
* stipulated by the glTF 2.0 specification.
*
* @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).
*/
public void constrainMaterial(@NonNull @Size(min = 8) int[] uvmap) {
nConstrainMaterial(this, uvmap);
}
private static native void nGlobalInit();
private static native void nConstrainMaterial(MaterialKey materialKey, int[] uvmap);
};
/**
* Frees memory associated with the native material provider.
* */
public void destroy() {
nDestroyMaterialProvider(mNativeObject);
mNativeObject = 0;
}
* Creates or fetches a compiled Filament material, then creates an instance from it.
*
* @param config Specifies requirements; might be mutated due to resource constraints.
* @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.
*/
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label);
/**
* Creates and returns an array containing all cached materials.
*/
public @NonNull Material[] getMaterials();
/**
* Returns true if the presence of the given vertex attribute is required.
*
* Some types of providers (e.g. ubershader) require dummy attribute values
* if the glTF model does not provide them.
*
* NOTE: The given attribute is the VertexAttribute enum casted to an integer.
* This is done to streamline the JNI work between Java and Native layers.
*/
public boolean needsDummyData(int attrib);
/**
* Destroys all cached materials.
@@ -53,15 +125,5 @@ public class MaterialProvider {
* This is not called automatically when MaterialProvider is destroyed, which allows
* clients to take ownership of the cache if desired.
*/
public void destroyMaterials() {
nDestroyMaterials(mNativeObject);
}
long getNativeObject() {
return mNativeObject;
}
private static native long nCreateMaterialProvider(long nativeEngine);
private static native void nDestroyMaterialProvider(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
public void destroyMaterials();
}
@@ -45,7 +45,7 @@ public class ResourceLoader {
*/
public ResourceLoader(@NonNull Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, false, false);
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
}
/**
@@ -54,14 +54,15 @@ 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);
}
/**
@@ -101,6 +102,15 @@ public class ResourceLoader {
return nHasResourceData(mNativeObject, uri);
}
/**
* Frees memory by evicting the URI cache that was populated via addResourceData.
*
* This can be called only after a model is fully loaded or after loading has been cancelled.
*/
public void evictResourceData() {
nEvictResourceData(mNativeObject);
}
/**
* Iterates through all external buffers and images and creates corresponding Filament objects
* (vertex buffers, textures, etc), which become owned by the asset.
@@ -157,10 +167,11 @@ 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);
private static native void nEvictResourceData(long nativeLoader);
private static native boolean nHasResourceData(long nativeLoader, String url);
private static native void nLoadResources(long nativeLoader, long nativeAsset);
private static native boolean nAsyncBeginLoad(long nativeLoader, long nativeAsset);
@@ -0,0 +1,102 @@
/*
* 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.
*/
package com.google.android.filament.gltfio;
import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
/**
* Loads pre-generated ubershader materials that fulfill glTF requirements.
*
* <p>This class is used by {@link AssetLoader} to create Filament materials.
* Client applications do not need to call methods on it.</p>
*/
public class UbershaderLoader implements MaterialProvider {
private static final VertexBuffer.VertexAttribute[] sVertexAttributesValues =
VertexBuffer.VertexAttribute.values();
private long mNativeObject;
/**
* Constructs an ubershader loader using the supplied {@link Engine}.
*
* @param engine the engine used to create materials
*/
public UbershaderLoader(Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateUbershaderLoader(nativeEngine);
}
/**
* Frees memory associated with the native material provider.
* */
public void destroy() {
nDestroyUbershaderLoader(mNativeObject);
mNativeObject = 0;
}
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label) {
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
}
public @NonNull Material[] getMaterials() {
final int count = nGetMaterialCount(mNativeObject);
Material[] result = new Material[count];
long[] natives = new long[count];
nGetMaterials(mNativeObject, natives);
for (int i = 0; i < count; i++) {
result[i] = new Material(natives[i]);
}
return result;
}
public boolean needsDummyData(int attrib) {
VertexBuffer.VertexAttribute vattrib = sVertexAttributesValues[attrib];
switch (vattrib) {
case UV0:
case UV1:
case COLOR:
return true;
default:
return false;
}
}
public void destroyMaterials() {
nDestroyMaterials(mNativeObject);
}
public long getNativeObject() {
return mNativeObject;
}
private static native long nCreateUbershaderLoader(long nativeEngine);
private static native void nDestroyUbershaderLoader(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
private static native long nCreateMaterialInstance(long nativeProvider,
MaterialKey config, int[] uvmap, String label);
private static native int nGetMaterialCount(long nativeProvider);
private static native void nGetMaterials(long nativeProvider, long[] result);
}
+9 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.9.11
VERSION_NAME=1.17.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -18,3 +18,11 @@ POM_DEVELOPER_NAME=Filament Team
org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
org.gradle.unsafe.configuration-cache=true
# TODO: Remove this when we switch to Gradle 7.4
org.gradle.unsafe.configuration-cache.max-problems=3
com.google.android.filament.tools-dir=../../../out/release/filament
com.google.android.filament.dist-dir=../out/android-release/filament
com.google.android.filament.abis=all

Some files were not shown because too many files have changed in this diff Show More