Compare commits

..
1575 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
Benjamin Doherty f222f1b925 Merge branch 'rc/1.9.11' into release 2021-02-08 09:51:08 -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 2839c352b8 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:47:18 -08:00
Ben Doherty 6a01cbc312 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:06:40 -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
Benjamin Doherty 6193156556 Bump version to 1.9.11 2021-02-01 11:49:12 -08:00
Benjamin Doherty fe23aa917d Merge branch 'rc/1.9.10' into release 2021-02-01 11:45:47 -08:00
Benjamin Doherty eb8a29a332 Update RELEASE_NOTES for 1.9.10 2021-02-01 11:45:17 -08:00
Benjamin Doherty 6eec2cde81 Release Filament 1.9.10 2021-02-01 11:44:33 -08:00
Philip Rideout 98ae61ffe5 gltfio: Fix "_maskThreshold not found" error.
MaterialGenerator selects a custom blend mode for transmissive models,
therefore the AssetLoader should look at the material's blend mode when
it sets up properties, not the one requested by the glTF file.

Fixes #3444.
2021-02-01 09:52:06 -08:00
Romain Guy adb489c77a Compile Android libraries with fPIC (#3473)
* Compile Android libraries with fPIC

* Rmove warning
2021-01-29 15:23:34 -08:00
Philip Rideout eeccfed8e4 Rewrite and enhance test_FeedbackLoops.
Previously this test was actually finding a ReadPixels failure on Intel
GPU's, rather than a failure of feedback loop behavior. This was due to
the fact that it was calling ReadPixels on a non-zero miplevel, which
seems to be unsupported on Intel GPU's.

The test now follows the downsample phase with an upsample phase, just
like the real bloom effect. This allows us to issue ReadPixels on the
base level, thus making the test more targetted to rendering feedback
loops.
2021-01-29 15:06:57 -08:00
Philip Rideout 893ed861e9 gltfio on Java: free material cache in AssetLoader#destroy
Fixes #3469
2021-01-29 14:42:54 -08:00
Romain Guy 411ae23512 Update Kotlin, Gradle and NDK dependencies (#3470)
* Update Kotlin, Gradle and NDK dependencies

* Update CI build
2021-01-29 12:09:08 -08:00
Romain Guy 8f05984551 Update release notes 2021-01-29 09:31:36 -08:00
Romain GuyandPhilip Rideout 4567b01c1d Multi-thread shaders generation when compiling materials (#3464)
* Stop using members as globals between methods

* Multi-thread shaders generation with JobSystem

* Pass JobSystem to MaterialBuilder::build()

* Fix MeshAssimp to use the new API

* Allow the Java API to pass a job system via Engine

* Update docs

* Apply suggestions from code review

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2021-01-29 09:30:37 -08:00
Philip Rideout 29315f9a1b gltfio: fix crash during async texture decode.
Recall that we now use shared_ptr to simplify lifetime management of
cgltf source data (#3413).

Before this commit, we were only using shared_ptr to retain the source
data during buffer uploads. After this commit, we are using it to retain
source data during texture decoding.

Fixes #3428.
2021-01-29 09:06:32 -08:00
Ben Doherty 0626902530 Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:40:16 -08:00
Ben Doherty d4a2d30a1c Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:38:38 -08:00
Philip Rideout cec5f3e988 gltfio: disable shader optimizations by default
Note that ubershaders (which are always used on Android and WebGL) are
still optimized by default.
2021-01-27 11:40:51 -08:00
Romain Guy 02501c6e60 Modulate emissive by alpha on blended objects (#3459)
This prevents light from being emitted from completely
transparent pixels.
2021-01-26 16:35:49 -08:00
Ben Doherty 4d8da14c1f Update universal library option in build.sh for Apple silicon (#3458) 2021-01-26 16:34:46 -08:00
Philip Rideout 4fae917fb5 Introduce optional ping-ping bloom implementation.
Second attempt after abandoning #3451.

Feedback loops do not work with Chrome or Intel GPU's, so we now have an
optional ping-pong implementation of Bloom.

Issue #2338.
2021-01-26 15:08:39 -08:00
Philip Rideout c84036c8c4 Update JavaScript bindings and demo to prep for Bloom workaround. 2021-01-26 13:18:03 -08:00
Philip Rideout 34429f5490 Add unit test for feedback loops.
This test passes on my Radeon GPU MacBook but fails with an Intel GPU.
2021-01-26 13:12:46 -08:00
Philip Rideout 59c2d5bef3 Plumbing for disabling feedback loops on Intel.
This is a follow-on to #3451, which adds optional ping-pong support to
the bloom generator.
2021-01-26 13:12:24 -08:00
Ben Doherty a3412c4f45 Remove shadow cascade visualization from unlit variants (#3455) 2021-01-26 11:20:54 -08:00
Philip Rideout 564d846be5 Repair backend unit tests on macOS.
This fixes "illegal hardware instruction" seen on my MacBook, which
is the same as #1839, but triggered only in a test environment where
the main thread is the same as the driver thread, and filament is built
with HAS_THREADING enabled.
2021-01-26 08:57:16 -08:00
Romain Guy 41186340c9 Change visibility of a few color grading options 2021-01-25 08:49:25 -08:00
Ben Doherty 96bba71739 Update combine-static-libs.sh script to work with universal binaries (#3447) 2021-01-22 15:57:43 -08:00
Adrian PerezandMathias Agopian 5ab7a9e3ab Add swap() methods to Allocator.h (#3445)
* Add swap() methods to Allocator.h

This allows StructureOfArraysBase's move constructor to compile.
Removed an apparent workaround in SingleInstanceComponentManager.

* swap can be noexcept

* Add swap() methods to Allocator.h

This allows StructureOfArraysBase's move constructor to compile.

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-01-22 15:45:20 -08:00
Mathias Agopian 4c30067dac fix missing froxel
Fix a possible out-of-bound access when reading the x-planes array. 
Also account for the fact that the loops filling the froxels assume
stl-like iterators (1-past the end on the right), while the indices
themselves were right-inclusive.

fixes #3142
2021-01-19 17:31:43 -08:00
Philip Rideout 243ba77025 gltfio: support animation in dynamically-added instances.
I tested this by viewing CesiumMan with our `gltf_instances` sample app.

There is now a need for some general refactoring in gltfio. I feel that
the high-level objects have become too tightly coupled to each other.

Fixes #3137.
2021-01-19 16:37:54 -08:00
Mathias Agopian 229f1f6d95 make sure the ResourceAllocator stays below the cache size limit
Only items older than a certain value were purged from the cache,
this allowed the cache to grow unbounded before this age limit was
reached.

We now purge the cache at each frame if it's above the size threshold.

Fixes #3381
2021-01-19 15:20:37 -08:00
Mathias Agopian bc2eae2ecd fix filament_test on aarch64 mac
don't use slog from a static variable, because it might not have been
constructed yet, due to static initialized order.
For some reason, this happens on aarch64 macs, but this was actually
a real problem.
2021-01-19 15:20:11 -08:00
Philip Rideout e468ec91b7 Metal: honor inverseFrontFaces RasterState.
Fixes #3402.
2021-01-19 10:35:14 -08:00
Philip Rideout ca2829461a Add options to planar reflection demo.
By default, the demo now reflects the camera instead of the renderable.
However this can be changed via the command line. Users can now change
the backend too.
2021-01-19 09:16:50 -08:00
Philip Rideout 7805687f7a Update emsdk version in README. 2021-01-16 09:17:56 -08:00
Mathias Agopian af82aaa0fc remove unused code that causes warnings 2021-01-15 14:38:01 -08:00
Mathias Agopian 410ecfd014 support for Apple Silicon macs
- add darwin-aarch64 support to bluegl
- remove all aarch64 conditions in our cmakefiles, the architecture
  is better handled in the source files (to allow fat binaries later)
2021-01-15 14:02:19 -08:00
Mathias Agopian 0df1f9fcce hack libfilament_jni to compile on Apple Silicon
The problem is that we're trying to link against an x86 jdk and that
fails, in turn preventing the library to link.
2021-01-15 14:02:19 -08:00
MirsfangandMathias Agopian 45f7e07832 fix material use (#3417)
* fix material use

* Update filament/src/PostProcessManager.cpp

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-01-15 13:59:09 -08:00
Mathias Agopian 1aefe741b2 update libpng to 1.6.37 2021-01-15 12:10:03 -08:00
Mathias Agopian d1842919cf update zlib to 1.2.11 2021-01-15 12:10:03 -08:00
Philip Rideout 6473771f1e Update Draco to 1.4.1
Tested with gltf_viewer release macOS on:

- CesiumMan/glTF-Draco/CesiumMan.gltf
- MorphPrimitivesTest/glTF-Draco/MorphPrimitivesTest.gltf
2021-01-15 11:03:29 -08:00
Philip Rideout 2d57a82b49 Add simple RenderTarget demo (planar reflection)
When we removed the old "ghetto bloom" demo, we ceased to have any
samples demonstrating the RenderTarget API. This demo is a fairly simple
demonstration of planar reflection.
2021-01-14 16:27:18 -08:00
Romain Guy dc2d55c409 Update static documentation 2021-01-14 10:29:38 -08:00
Romain Guy c0b8e98a93 Update documentation to fix broken links 2021-01-14 10:28:56 -08:00
Philip Rideout 8252bbe512 gltf_viewer: fix very sporadic crash when exiting.
This could occur when trying to exit the app while textures
are still being decoded.
2021-01-13 09:48:36 -08:00
Philip Rideout a4817f3e2a Simplify lifetime management of cgltf_data.
The gltfio API allows users to destroy ResourceLoader or FilamentAsset
even when various asynchronous work (e.g. uploading buffers to the GPU)
has not yet been completed. This was achieved in an error-prone manner
using manual reference counting and an internal management object called
AssetPool.

This PR refactors gltfio by wrapping cgltf_data in shared_ptr, which I
usually try to avoid. However in this case it provides the precisely the
functionality that is needed.

I tested this PR for memory leaks and crashes by hacking gltf_viewer
and monitoring memory usage in Activity Monitor.

This fixes #3383 and makes it easier to implement some missing features,
such as animation support for instanced assets.
2021-01-13 09:44:56 -08:00
Philip Rideout fa879b4bd0 gltf_viewer: call asyncCancelLoad in drop handler
Relates to #3383
2021-01-08 09:40:39 -08:00
Ben Doherty 005e4ba2ec Fix Filament RenderingTest (#3407) 2021-01-07 12:10:53 -08:00
Romain Guy d2299c4502 List supported glTF 2.0 features 2021-01-06 14:20:46 -08:00
Philip Rideout 5c666c254e gltfio: Improve robustness when decoding textures.
Bad texture files would cause the background decoder thread to never
finish and would generate textures with 0x0 dimensions, which eventually
triggers GL_INVALID_VALUE.

To recap, gltfio texture loading has two phases: the first phase is
synchronous and uses stbi_info to gather texture info. The second phase
is asynchronous and uses stbi_load to do the actual decoding.

During the first phase, we now check the return code from stbi_info
rather than assuming that it worked.  :)

Fixes #3344
2021-01-05 12:00:29 -08:00
ritwik a09c17bd4f Make install gltfio_resources and gltfio_resources_lite for desktop builds also 2021-01-05 10:35:13 -08:00
Ben Doherty 57df4481e9 Update Material query API to work with subpasses (#3203)
* Update Material query API to work with subpasses

* Add JNI binding
2020-12-23 13:27:04 -08:00
Ben Doherty 47af85aed1 Remove libSPIRV-Tools-shared from spirv-tools (#3390) 2020-12-23 13:26:14 -08:00
Ben Doherty 44fc295913 Unbind texture from all sampler groups upon destroy (#3386) 2020-12-22 11:34:05 -08:00
Philip Rideout 6878b0be36 build.sh: Add TypeScript bindings to the tgz file.
This makes the tgz consistent with the npm package. Fixes #3268.

Note that we already stopped packaging the old HTML docs. Going forward,
we would like to use the TS declarations as documentation because they
must be kept up to date anyway, and they already contain type
information. This was discussed in #3250.
2020-12-21 17:27:46 -08:00
Romain Guy 6c222bf4e3 Update README 2020-12-15 14:48:38 -08:00
Philip Rideout 042bfe2597 Partial fix for MSVC build. 2020-12-14 12:15:06 -08:00
Ben Doherty 97133f3591 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-14 12:14:53 -08:00
Philip Rideout d06cc4390e filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-14 11:19:43 -08:00
Philip Rideout 6047d3235f Remove VSM variant from Skybox material. 2020-12-14 11:19:31 -08:00
Philip Rideout 2cda6e35bd math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-14 11:19:22 -08:00
Philip Rideout 8f8d51e17b Code review fixups for libibl_lite. 2020-12-14 11:19:16 -08:00
Philip Rideout 6919e3b274 libibl: use C callback for progress 2020-12-14 11:19:09 -08:00
Philip Rideout 10bf944410 Add libibl_lite. 2020-12-14 11:19:03 -08:00
Romain Guy eb70fd5dee Sample the proper channel for sheenRoughness 2020-12-12 18:05:02 -08:00
Romain Guy 986a3869cc Fix struct initialization 2020-12-12 17:40:48 -08:00
Romain Guy 9ad3d88d74 Fix build breakage.
We were declaring one too many material properties which would
lead to out of bounds writes/reads.
2020-12-12 12:04:24 -08:00
Romain Guy a3bfdb89fa Update release notes 2020-12-12 11:09:28 -08:00
Romain Guy 2895530e09 Add support for sheenColor and sheenRoughness (#3358)
* Add support for sheenColor and sheenRoughness

This work is necessary to support the glTF extension KHR_materials_sheen.
This change effectively adds the specular lobe from the cloth material
model to the base material model. The cloth model remains useful for
its extra subsurface color feature but also because it's cheaper.

* Add support for KHR_materials_sheen to gltfio

* Update documentation

* Document default shading values
2020-12-12 11:07:40 -08:00
Romain Guy f8069aa99f Update to cgltf 1.9 (#3361) 2020-12-11 16:42:36 -08:00
Philip Rideout b70eea9556 filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-10 11:20:14 -08:00
Philip Rideout 44a8da6a8e Remove VSM variant from Skybox material. 2020-12-10 11:20:01 -08:00
Philip Rideout 3bd066f993 math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-10 11:19:46 -08:00
Philip Rideout 1b10afa9e6 Code review fixups for libibl_lite. 2020-12-10 11:19:36 -08:00
Philip Rideout 024910ba8e libibl: use C callback for progress 2020-12-10 11:19:36 -08:00
Philip Rideout f2e3a132db Add libibl_lite. 2020-12-10 11:19:36 -08:00
Philip Rideout 87abd1f8bc Fix RenderableManager docs for "index"
I also double-checked the backends, they indeed treat it as an index
count.

Fixes #3351
2020-12-10 10:11:46 -08:00
Philip Rideout 57662c52f2 matdbg / matinfo: fix post-process variant string
Also some minor HTML stuff:

- Hide "Required attributes" header when there are none.
- Remove legend for variants (takes too much space).
2020-12-09 14:44:27 -08:00
Philip Rideout a50cd1f8c8 zbloat now includes chunk sizes 2020-12-06 21:54:37 -08:00
Philip Rideout fe907398d4 resgen / zbloat fixups 2020-12-06 15:25:08 -08:00
Philip Rideout 8b6ddfe97a Add zbloat tool.
This tool makes it easy to analyze the composition of Android
applications that use Filament.

- Filament materials are shown in the treemap if `resgen --json` was
  used in the build.
- The input path can be a so file, folder, or zip archive (apk or aar).
- If the path is a zip or folder, helps you find the file to analyze.
- The generated web report is a self-contained HTML file.
- Reports the gzipped size of all Filament materials.

For example, from a mac, you can generate a self-contained HTML file by
typing this from the Filament repo root:

    ./tools/zbloat/zbloat.py ./android/filament-android
    open index.html

This tool uses Python, `nm`, and `objdump`.

The `nm` tool works slightly differently between macOS and Linux, so a
`Dockerfile` is provided that installs dependencies inside a Linux
container. This is also convenient if you do not have both versions of
Python on your system.

The easy way to use docker is to invoke the helper bash script. Simply
type `zbloat.sh [args...]` instead of `zbloat.py [args...]`. The first
time you run it, it will be slow but subsequent times will be fast.

Many thanks to Evan Martin for his interactive treemap widget.
2020-12-06 14:36:25 -08:00
Philip Rideout 3226b20ece resgen: add --json option.
This option embeds a small JSON string inside the resgen blob that lists
all materials and their respective sizes. This is useful when analyzing
the footprint of the binary executable.
2020-12-06 14:36:13 -08:00
MasTraER 61d473887f Fix clearing Rendertarget multiple times
This fixes a bug Renderer clearing a render target multiple times when the first time and back again.

Usually the default RenderTarget is unintentionally cleared/discarded in the current behavior.
1) Renderer renders a view without custom RenderTarget having full-screen viewport,
2) Renderer renders a view with custom RenderTarget
3) And Renderer renders an another view without custom RenderTarget having different viewport from 1)
You may see junk or empty pixels in outside of the viewport of the view 3), depending on ClearOptions and the backend.

This fix make Renderer put cleared RenderTargets into a set and check them to be cleared only for the first time, instead of comparing the previous RenderTarget to the current RenderTarget.
2020-12-06 14:35:26 -08:00
cjsliuj b3d7819e78 Fix computeTangents 2020-12-05 15:24:34 -08:00
Philip Rideout de6220594d WebGL: RGB16F is not color renderable.
This was problematic with Chrome's ANGLE backend; more information at:
https://bugs.chromium.org/p/chromium/issues/detail?id=941671#c10

Fixes #3308
2020-12-02 14:31:19 -08:00
Philip Rideout d9dfe69a81 Android: do not export internal symbols.
We now export only two groups of symbols: (1) JNI and (2) dynamic linker
symbols used by the companion libraries.

This commit has the following impact:

- Shrinks the arm64 so from 1024 KiB to 954 KiB.
- Shrinks the arm64 aar from 560 KiB to 538 KiB.

Note that the patterns in the map file are tested against mangled names
and therefore should not be used to match the double-colon operator.
2020-12-02 13:11:38 -08:00
Ben Doherty 22d4e63787 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-01 14:05:15 -08:00
Philip Rideout f033799a43 Fix incorrect JNI binding for destroyColorGrading. 2020-12-01 09:02:51 -08:00
Ben Doherty 30e150c016 Fix Metal assertion when loading into texture arrays (#3314) 2020-11-24 10:46:16 -08:00
Ben Doherty f5f27749a4 Update native window documentation (#3315) 2020-11-23 14:03:10 -08:00
Philip Rideout b5f95213db Partial fix for MSVC build. 2020-11-20 14:18:08 -08:00
Philip Rideout 9a2f6fdb53 Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

More specifically, the failure to wait in `acquireWorkCommandBuffer`
causes the subsequent destruction of an in-use fence, which causes
a TSAN failure with Google's internal tests.

I am consulting with the SwiftShader team on a real fix, meanwhile
we can commit this easy workaround.

We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
2020-11-20 09:37:54 -08:00
Philip Rideout d42865373d Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

More specifically, the failure to wait in `acquireWorkCommandBuffer`
causes the subsequent destruction of an in-use fence, which causes
a TSAN failure with Google's internal tests.

I am consulting with the SwiftShader team on a real fix, meanwhile
we can commit this easy workaround.

We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
2020-11-20 09:36:06 -08:00
Philip Rideout 761977d385 Filament should always bind an IBL texture.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 13:28:19 -08:00
Philip Rideout f83eb114bc Filament should always bind an IBL texture.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 10:22:45 -08:00
Philip Rideout 9c20294e4b gltfio: Fix animator crash for orphaned nodes.
Fixes #3285
2020-11-18 11:26:39 -08:00
Ben Doherty 40e7a86f5f Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:41:15 -08:00
Ben Doherty 21248f15b5 Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:37:55 -08:00
Ben Doherty 34707431f7 Fix spirv-tools CMake warning (#3289) 2020-11-16 14:30:06 -08:00
Benjamin Doherty 4f32817f6d Bump version to 1.9.10 2020-11-16 12:37:49 -08:00
Benjamin Doherty cc9e05e711 Merge branch 'rc/1.9.9' into release 2020-11-16 12:34:13 -08:00
Benjamin Doherty 5e585496b2 Update RELEASE_NOTES for 1.9.9 2020-11-16 12:33:43 -08:00
Benjamin Doherty 1e501eb00b Release Filament 1.9.9 2020-11-16 12:32:38 -08:00
Benjamin Doherty 419d68d4db Update RELEASE_NOTES for 1.9.9 2020-11-16 12:17:02 -08:00
Ben Doherty fdc28801a2 Silence spirv-opt warnings in release builds (#3288) 2020-11-13 13:55:19 -08:00
Ben Doherty c008109335 Update Android building instructions on Windows 2020-11-13 11:04:24 -08:00
Philip Rideout 8450232448 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

With OpenGL, this warning would never be a false positive because it has
the luxury of calling `glGetUniformLocation`.

This adds a private attribute to our samplers called `strict` that
indicates whether or not a sampler should always have a bound texture.
For now the only strict samplers are the custom ones declared in the
user's material.

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:21:13 -08:00
Philip Rideout 99c5fc7388 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

With OpenGL, this warning would never be a false positive because it has
the luxury of calling `glGetUniformLocation`.

This adds a private attribute to our samplers called `strict` that
indicates whether or not a sampler should always have a bound texture.
For now the only strict samplers are the custom ones declared in the
user's material.

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:02:32 -08:00
Ben Doherty 90c156ebef Add fog variant filter to matc (#3286) 2020-11-12 12:47:42 -08:00
Ben Doherty 2df02d81d3 Add setFrameCompletedCallback JNI binding (#3275) 2020-11-12 12:24:41 -08:00
Ben Doherty 8019b11589 Update glslang and friends (#3277) 2020-11-12 12:23:51 -08:00
Philip Rideout cc51726590 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:36:13 -08:00
Philip Rideout 16454e0de6 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:35:50 -08:00
Philip Rideout 318e22af51 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

The fix is to factor some the flag-setting logic in `beginFrame()` into
a private method, and call this method from `render()` each time
the user-level RenderTarget has been changed.

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:36 -08:00
Philip Rideout 3bf934f5d7 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

The fix is to factor some the flag-setting logic in `beginFrame()` into
a private method, and call this method from `render()` each time
the user-level RenderTarget has been changed.

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:07 -08:00
Philip Rideout 68ac87dc24 NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-10 15:44:01 -08:00
Ben Doherty b4a6d0a83e Add callback API to SwapChain (#3270) 2020-11-10 14:52:04 -08:00
Ben Doherty a09037cec0 Revert "macOS: fix headless rendering." (#3273) 2020-11-10 12:02:12 -08:00
Philip Rideout 50a61984ec NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-09 11:11:12 -08:00
Romain Guy 6486eba7e2 Fix typo in docs 2020-11-09 09:37:10 -08:00
Benjamin Doherty acb8f00075 Bump version to 1.9.9 2020-11-09 09:32:55 -08:00
Benjamin Doherty 06d9183aaa Merge branch 'rc/1.9.8' into release 2020-11-09 09:28:58 -08:00
Benjamin Doherty c92d13c0c9 Update RELEASE_NOTES for 1.9.8 2020-11-09 09:28:15 -08:00
Benjamin Doherty bd9aba35f6 Release Filament 1.9.8 2020-11-09 09:27:06 -08:00
Benjamin Doherty 75af25419d Update RELEASE_NOTES for 1.9.8 2020-11-09 09:26:27 -08:00
Benjamin Doherty f6b90d2a31 Bump version to 1.9.8 2020-11-09 09:21:36 -08:00
Philip Rideout 7fbd00e59b Repair Windows build, maybe. 2020-11-09 08:35:43 -08:00
Philip Rideout f814138f83 Regenerate BlueVK, use a C++ namespace.
This moves all Vulkan entry points into the bluevk namespace
to avoid conflicts with other Vulkan loaders.

This also updates the header files and loader code to version 1.2.159 of
the Vulkan spec, which is currently available at the following links.

https://khronos.org/registry/vulkan/specs/1.2/html/vkspec.html
https://github.com/KhronosGroup/Vulkan-Headers/commit/87451c55aa8b4f00831fab6ffc4b721d0f148102
2020-11-09 08:35:43 -08:00
Philip Rideout 96d3f2f16b More fixes for signed integer overflow.
Fence.cpp:

My previous fix to the fix was insufficient because a signed integer
overflow could still occur as follows (this was observed in an internal
test at Google).

If the conditional on line 87 is true, then a clamped value is passed
into `wait`, which causes the conditional on line 133 to fail, which
causes `wait_for` to be called inappropriately, which is where an
overflow would occur.

MetalHandles.mm:

This is more theoretical, but to prevent potential integer overflow
within STL, I think we should call `wait()` rather than `wait_for()`
when an infinite timeout is desired.

This is our fourth fix to fences in since November 2; see also dcca236,
e9c9e45, and 8969416.  :)
2020-11-09 08:35:17 -08:00
Philip Rideout 89694168a6 Another fix for FENCE_WAIT_FOR_EVER.
FFence::wait() has some logic that tests if "timeout" is equal to
FENCE_WAIT_FOR_EVER, which is actually impossible because it would
be modified by the clamp in this situation.

In practice I think this oversight would not cause any problems. I
noticed it while reviewing the code.

To recap why the clamp exists: according to the ISO C++ spec, the
"nanoseconds" duration in chrono is at least a signed 64-bit type, but
our sentinel constant might not (and does not) fit within this range.
2020-11-05 17:24:44 -08:00
Romain Guy 63d5698a78 Update Gradle, AGP, and other dependencies (#3257)
* Update Gradle and AGP

* Update other dependencies
2020-11-05 10:47:12 -08:00
Romain Guy 24ca2bf181 Fix JNI binding 2020-11-04 13:01:16 -08:00
Ben Doherty f37a3e9497 Support CVPixelBuffer SwapChains with Metal (#3251) 2020-11-04 11:05:45 -07:00
Ben Doherty 90ad9b457a Implement copyFrame for Metal (#3249) 2020-11-03 12:25:29 -07:00
Ben Doherty 30f5a97ea1 Consolidate surface-related functionality into MetalSwapChain (#3246) 2020-11-03 12:00:03 -07:00
Philip Rideout 964a1bd7f2 BlueVK: improved error messaging. 2020-11-03 10:23:06 -08:00
Philip Rideout a3822f4af0 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:12:53 -08:00
Philip Rideout e9c9e45ac9 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:02:27 -08:00
Philip Rideout fb831dec0a Vulkan: adjust usage flags to allow DEPTH blits. 2020-11-02 11:00:57 -08:00
Benjamin Doherty bcdad769ff Merge branch 'rc/1.9.7' into release 2020-11-02 11:03:57 -07:00
Benjamin Doherty dc1c5529c0 Update RELEASE_NOTES for 1.9.7 2020-11-02 11:00:55 -07:00
Benjamin Doherty 8b8d563b0f Bump version to 1.9.7 2020-11-02 11:00:09 -07:00
Benjamin Doherty be4fb4fdbb Update RELEASE_NOTES for 1.9.7 2020-11-02 10:59:19 -07:00
Ben Doherty dcca236f60 Fix bug with Fence timeouts (#3243) 2020-11-02 10:47:28 -07:00
Philip Rideout 70dba2398e gltfio: add createInstance() to AssetLoader.
Note that this API is on the loader rather than the asset. This is
because the loader knows how to create Filament entities by traversing
a cgltf node hierarchy.

Animation on dynamically added instances is not yet supported.

We did not add destroyInstance() because gltfio favors flat arrays for
long term storage of entity lists and instance lists, which would be
slow to shift. We also wish to discourage create/destroy churn since it
is more efficient to pre-allocate instances and selectively add them
into the scene.

Fixes #3137.
2020-11-02 09:47:14 -08:00
Philip Rideout 47521d70a1 gltfio: fix ASAN issue when consuming invalid animation.
Release builds do not call cgltf_validate() so it was possible to
read out-of-bounds animation data when encountering a badly formed glTF
file with mismatched counts between sampler inputs and outputs.
2020-10-31 15:17:15 -07:00
Philip Rideout 468992f4cd gltfio: do not segfault on invalid primitives. 2020-10-31 13:28:13 -07:00
Philip Rideout 0db7057983 Vulkan: disable unreliable blit diagnostics. 2020-10-31 12:37:42 -07:00
Philip Rideout 8a63834607 Vulkan: fix layout mismatch after blitting to swap chain. 2020-10-31 12:37:42 -07:00
Philip Rideout 4e4d4f9ee3 Vulkan: add blit support for depth and MRT. 2020-10-31 10:29:25 -07:00
Philip Rideout 6abef94d95 mathio: add ostream operator for quaternions. 2020-10-29 17:04:03 -07:00
Philip Rideout 4b1c557bb1 Vulkan: fix color attachment list in first subpass.
This fixes a slew of validation warnings and errors seen when multiple
subpasses are enabled, starting with:

    Attachment 1 not written by fragment shader; undefined values will
    be written to attachment

The Vulkan driver was using the same color attachment list for both
subpasses, so the first subpass had unused attachments.

Note that Vulkan makes a distinction between color attachments and input
attachments and requires separate lists to be supplied for each subpass,
but our Driver API consolidates everything into a single list. This
should perhaps be refactored at a later date.
2020-10-29 15:03:34 -07:00
Philip Rideout 94a1eb27b4 Do not declare unused fragColor in GLSL.
This fixes a Vulkan validation warning when building a pipeline that
does not have a color attachment.
2020-10-29 11:08:13 -07:00
Philip Rideout a9754273b0 Vulkan: minor fix for diagnostic output. 2020-10-28 15:41:07 -07:00
Philip Rideout 2fe4f6cbe7 AutomationEngine: fix regression with screenshots. 2020-10-28 12:58:54 -07:00
Philip Rideout 1159435d47 gltfio: add safety checks to getAnimator. 2020-10-28 11:51:06 -07:00
Philip Rideout a6f364e0f3 gltfio: fix segfault when consuming invalid file. 2020-10-28 11:50:54 -07:00
Philip Rideout c6942a52e6 gltfio: refactor the instancing cache.
This prepares for #3137 by moving the mesh cache and material instance
cache out of the loader (where they were transient anyway) and into the
actual asset. This paves the way for a `createInstance()` API.
2020-10-27 10:30:18 -07:00
Philip Rideout c65dc99771 Fix colorGradingAsSubpass when dithering is off.
This fixes the blank screen seen with Vulkan when all view options are
disabled.
2020-10-26 15:33:42 -07:00
Benjamin Doherty 65394f6301 Bump version to 1.9.7 2020-10-26 11:34:20 -06:00
Benjamin Doherty b0beee03bc Merge branch 'rc/1.9.6' into release 2020-10-26 11:29:45 -06:00
Benjamin Doherty 6971b3b6b0 Update RELEASE_NOTES for 1.9.6 2020-10-26 11:28:06 -06:00
Benjamin Doherty 4270384661 Bump version to 1.9.6 2020-10-26 11:27:08 -06:00
Benjamin Doherty fe1de41b8e Update RELEASE_NOTES for 1.9.6 2020-10-26 11:25:31 -06:00
Philip Rideout 82cb13936c Vulkan: warn instead of panic for sampler overflow.
This makes behavior in release builds similar to the OpenGL backend.

In debug builds, we will still assert.
2020-10-23 11:11:35 -07:00
Philip Rideout 212b64ea5f Vulkan: make ReadPixels synchronous.
This makes it so that the PixelBufferDescriptor callback triggers at a
time consistent with other backends.

ReadPixels is still asynchronous in the sense that the callback is
triggered on the main thread. However, it is now guaranteed to trigger
during (or before) flushAndWait(), which is less surprising behavior.
2020-10-22 17:42:07 -07:00
Philip Rideout 2849dc6a2a Fix iOS build break. 2020-10-22 17:03:06 -07:00
Philip Rideout d84bb82e44 Merge duplicated implementations of toLinear(). 2020-10-22 17:03:06 -07:00
Philip Rideout 5746532b7c Add PNG output to test_ReadPixels. 2020-10-22 17:03:06 -07:00
Philip Rideout 2e10fe6680 PlatformVkLinux now supports all combos of XLIB and XCB.
You can now build Filament with support for both X11 APIs, or neither.
If both are supported, run-time selection is achieved using a SwapChain
flag.

Supporting only one API at build time (or neither) is useful because our
list of "required" VkInstance extensions can vary according to which
API's are supported. During VkInstance creation, we do not have a priori
knowledge about what kinds of swap chains will be created. (headless vs
non-headless, XCB vs XLIB, etc)

Note that some Vulkan implementation (e.g. some builds of SwiftShader)
only support XCB.
2020-10-22 16:55:25 -07:00
Philip Rideout f55c9ee437 Fix Windows build. 2020-10-22 13:08:09 -07:00
Philip Rideout 06e639ae91 Vulkan: fix destroy-while-used for UBOs. 2020-10-22 11:43:16 -07:00
Philip Rideout 8de19cb582 Vulkan: fix leak with headless swap chain. 2020-10-22 11:43:16 -07:00
Philip Rideout 47b1ece804 Vulkan: Improve refcounting for vertex buffers.
This avoids the following validation error when clients create then
immediately destroy vertex buffers, index buffers, and uniform buffers.

        VUID-vkDestroyBuffer-buffer-00922

        Cannot free VkBuffer that is in use by a command buffer.

Buffers that are used across multiple frames were fine, but
create-and-destroy scenarios were problematic.
2020-10-22 11:39:57 -07:00
Philip Rideout d47189536f Vulkan: fix thread safety regression in Disposer.
This fixes a regression introduced by 548b28c6e manifesting as
intermittent assertions. The VulkanDisposer gc() should only be called
from the driver thread.
2020-10-22 11:39:46 -07:00
dsternfeld7 4533a42a6f Makes it possible to have multiple instances of ImGuiHelper at the same time
This change fixes an issue where ImGuiHelper would crash on destruction if you created more than one instance at the same time.

This crash occurred when ImGui::DestroyContext() was called, because when the second instance was destroyed there was no current context causing it to crash.

This fixes it by making ImGuiHelper store and manage it's own context.

Having two instances of ImGuiHelper is useful in cases where you want to use imgui with multiple views.
2020-10-22 11:39:33 -07:00
Philip Rideout 853247f32f Vulkan: ReadPixels y-flip workaround. 2020-10-21 17:42:46 -07:00
Philip Rideout 5f6cbc779a Allow test_ReadPixels with SwiftShader. 2020-10-21 16:24:27 -07:00
Philip Rideout 548b28c6e2 Vulkan: improve the ReadPixels implementation.
This adds support for more format conversions and removes a bogus
assert that prevented ReadPixels within beginFrame / endFrame.
This was tested with:

    backend_test_mac --api vulkan --gtest_filter=BackendTest.ReadPixels
2020-10-21 16:04:31 -07:00
Ben Doherty 239246e221 Add ability to specify post-process material output location (#3205) 2020-10-21 12:19:46 -06:00
Philip Rideout 75c4f36f96 Add Dockerfile and test script for SwiftShader.
This adds a Dockerfile and a new bash script that makes it
east to invoke the appopriate Docker commands.

This does not yet enable a GitHub Action because of intermittent
issues that we have not yet ironed out.
2020-10-21 10:50:25 -07:00
Philip Rideout 7260bab7b3 Fix TypeScript binding for TextureUsage. 2020-10-20 14:09:05 -07:00
Ben Doherty e7250571e7 Add subpass parameter type to materials (#3193) 2020-10-19 16:28:26 -06:00
Philip Rideout c68d0a4e46 Vulkan: add missing field to VmaVulkanFunctions. 2020-10-19 11:57:37 -07:00
Benjamin Doherty a37b431e87 Bump version to 1.9.6 2020-10-19 11:55:13 -06:00
Benjamin Doherty 98107016b9 Merge branch 'rc/1.9.5' into release 2020-10-19 11:51:30 -06:00
Benjamin Doherty 37d080dfd1 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:50:54 -06:00
Benjamin Doherty de75b9d125 Bump version to 1.9.5 2020-10-19 11:49:57 -06:00
Benjamin Doherty 8bccfc2863 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:49:05 -06:00
Philip Rideout 07fd883f9a Vulkan + Android: fix build break.
Fixes #3200.
2020-10-19 09:36:12 -07:00
Philip Rideout 5ceb9fc5d5 Add optional XCB support to PlatformVkLinux.
This allows clients to build the Vulkan backend with either XLIB or XCB
support. I did a quick smoke test of the XCB option, but for now we are
continuing to default to XLIB. Note that the native window type used to
create the swap chain differs between these two API's.
2020-10-19 09:24:13 -07:00
Ben Doherty d14ba856a7 matc: fix some compilation failures still exit with code 0 (#3192) 2020-10-15 14:11:46 -06:00
Ben Doherty 7eec70276e Add release scripts and RELEASE_GUIDE (#3191) 2020-10-15 12:57:38 -06:00
Ben Doherty 4f58a7e5fb Fix Vulkan black screen on Windows with NVIDIA hardware (#3190) 2020-10-15 12:00:42 -06:00
Ben Doherty 30565a5afc Add capture frame button to gltf_viewer (#3189) 2020-10-14 12:43:05 -06:00
Ben Doherty 62d06592d3 VSM: add support for mipmaps and anisotropic sampling (#3185) 2020-10-14 11:48:23 -06:00
Benjamin Doherty e74e583b97 Fix CocoaPod version 2020-10-13 15:16:25 -06:00
Benjamin Doherty f54a0a3452 Fix CocoaPod version 2020-10-13 15:15:02 -06:00
Benjamin Doherty 6778ab0624 Fix CocoaPod version 2020-10-13 15:09:59 -06:00
Philip Rideout 37768ed9e1 Various changes to help clients upgrade Filament.
The non-const getSkybox() method is especially useful to client code
that needs to change the clear color, but does not have direct
access to the Renderer object.
2020-10-13 10:10:59 -07:00
Philip Rideout 20abfec7d3 Minor change to adhere to CODE_STYLE. 2020-10-12 11:15:45 -07:00
Benjamin Doherty 269d636785 Bump version to 1.9.5 2020-10-12 12:03:29 -06:00
Benjamin Doherty 39862c91ce Merge branch 'rc/1.9.4' into release 2020-10-12 11:56:24 -06:00
Benjamin Doherty 03df97d0e3 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:55:39 -06:00
Benjamin Doherty 40e10817dd Bump version to 1.9.4 2020-10-12 11:52:49 -06:00
Benjamin Doherty 523f4026b4 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:52:01 -06:00
Philip Rideout b82dca4fac JobSystem: work around hang on 2-CPU machines
If hardware_concurrency() returned 2 while UTILS_HAS_HYPER_THREADING was
enabled, `mThreadCount` was resulting in zero, so jobs (such as texture
decoding) would simply never start. This problem was noticed with
GitHub Actions.

I tested this fix locally by replacing `hardware_concurrency()` with
fixed values like 1 or 2, and verified that the hang went away.
2020-10-09 16:14:50 -07:00
Philip Rideout 5ebc6bce04 Add schema for automation specs.
This can help when authoring a spec using your favorite text editor.
2020-10-09 10:23:27 -07:00
Benjamin Doherty a6bf162431 Bump version to 1.9.4 2020-10-07 16:06:23 -06:00
Ben Doherty bd625e42e9 Fix Vulkan crash when using shadow cascades (#3172) 2020-10-07 15:36:45 -06:00
Philip Rideout 7471237178 Linux fixes for headless SwiftShader. 2020-10-07 11:24:33 -07:00
Ben Doherty 52698aab14 Destroy dummyOneTextureArray in PostProcessManager (#3171)
* Destroy dummyOneTextureArray in PostProcessManager

Fixes #3166

* Update RELEASE_NOTES.md
2020-10-07 12:19:02 -06:00
Philip Rideout 3d121eb873 Vulkan ReadPixels: fix platforms that use BGRA.
Fixes a color issue seen with SwiftShader in non-headless mode.
2020-10-06 15:22:14 -07:00
Ben Doherty 1dd7b06e6f Fix null pointer dereference in FIndirectLight (#3163) 2020-10-06 15:27:28 -06:00
Philip Rideout d2ca1c79d2 Fix Windows build by avoiding nested initializers.
Note that designated initializers are technically a C++20 feature so we
should not be using them. However they are really nice for Vulkan code.
2020-10-06 13:45:26 -07:00
Philip Rideout 52913e685e Vulkan: support readPixels and headless swap chains.
This adds support for headless rendering as well as readPixels. These
features are necessary for automated testing.

NOTE: invoking readPixels with a non-headless SwapChain seems to fail
with MoltenVK. I will investigate this later.
2020-10-06 13:45:26 -07:00
Benjamin Doherty f30332b12b Fix RELEASE_NOTES 2020-10-06 11:17:30 -06:00
Ben Doherty f31eb09ca0 Add Live Wallpaper Android sample (#3161) 2020-10-06 11:03:55 -06:00
Ben Doherty 0bec65701a VSM: render both shadow casters and receivers (#3147) 2020-10-05 17:03:10 -06:00
Ben Doherty 59ef044ce0 Add support to UiHelper for SurfaceHolder (#3155) 2020-10-05 12:04:05 -06:00
Benjamin Doherty 826e8d181c Merge branch 'rc/1.9.3' into release 2020-10-05 11:36:16 -06:00
Benjamin Doherty 76f1e91fd2 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:35:44 -06:00
Benjamin Doherty d72d3533e6 Bump version to 1.9.3 2020-10-05 11:34:19 -06:00
Benjamin Doherty 16dfadbba0 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:29:36 -06:00
Yixing Lao 9ce2c319a9 ARM64 support for bluegl (#3150)
* ARM64 support for bluegl

* Detect arch with uname

* Use register x16
2020-10-05 10:19:05 -07:00
Philip Rideout 4fe5832333 gltf_viewer: add --headless option.
This should only be used in combination with --batch. Users are
admonished if they try using it on its own.
2020-10-04 10:02:10 -07:00
Philip Rideout 79f1744823 Automation: fix segfault when closing the app early.
The Filament View that gets passed to tick() is retained briefly when
screenshots are enabled, but it may be destroyed by the time the
PixelBufferDescriptor callback is invoked. So, we needed a way of
notifying the AutomationEngine.
2020-10-04 10:01:43 -07:00
Philip Rideout e352542e24 Automation: add support for materials.
This adds a `material` key to `Settings`, as a sister to `view`.

Here's an example of an automation spec that manipulates material
parameters:

    [{
      "name": "metallic_vs_roughness",
      "permute": {
          "material.scalar.roughnessFactor": [0.0, 0.5, 1.0],
          "material.scalar.metallicFactor": [0.0, 1.0]
      }
    }]

Currently this is limited to float, vec3, and vec4 parameters.
2020-10-02 11:57:23 -07:00
Philip Rideout 5938242d61 gltf_viewer: Add automation UI and functionality.
This adds `AutomationEngine` to libs/viewer, which iterates through
`Settings` instances that were generated from a JSON spec and applies
them to a Filament `View`. It can be configured to sleep between tests
using a time delay or a frame count.

This also adds command line arguments and user-interface elements to
`gltf_viewer` for automated testing.
2020-10-02 11:00:26 -07:00
Philip Rideout cfddd5b273 Rename AutomationList to AutomationSpec. 2020-10-01 19:07:24 -07:00
Philip Rideout 8a865e531e gltf_viewer: minor refactoring 2020-10-01 17:15:25 -07:00
Philip Rideout d05fb52ebf gltf_viewer: use integers for Temperature / Tint. 2020-10-01 16:41:24 -07:00
Philip Rideout fd142b9b84 gltf_viewer: add --settings, prep for automation. 2020-10-01 16:41:24 -07:00
Philip Rideout 6658283617 FilamentApp: Do not call postRender when skipping. 2020-10-01 16:41:24 -07:00
Pixelflinger 8b3caeffb9 ssct: decouple shadow distance from sample count 2020-10-01 10:20:38 -07:00
Philip Rideout 5fae33bde5 Automation: simplify API by flattening the test cases. 2020-09-30 16:17:23 -07:00
Philip Rideout 43cc5f9906 Automation: add a built-in default spec. 2020-09-30 16:17:23 -07:00
Philip Rideout 902eb32e3c Fix typo in copyright headers. 2020-09-30 16:17:23 -07:00
Philip Rideout 08f7973d0c Refactor Automation API. 2020-09-30 16:17:23 -07:00
Philip Rideout a736b8b018 Rename parse.h to jsonParseUtils. 2020-09-30 16:17:23 -07:00
Philip Rideout 094e7169cc Introduce a configurable test case generator.
This lets us generate long lists of settings permutations by writing a
simple JSON spec. For example, the following spec would generate six
`Settings` objects, all of which have SSAO enabled. See the unit test
for a larger example.

```
{
    "name": "viewopts",
    "base": { "view.ssao.enabled": true }
    "permute": {
        "view.dithering": ["NONE", "TEMPORAL"],
        "view.sampleCount": [1, 4, 8]
    }
}
```
2020-09-30 16:17:23 -07:00
Ben Doherty 44d4694c29 Add JNI binding for vsm msaa samples (#3139) 2020-09-30 16:12:45 -06:00
Ben Doherty 42862ddcde Fix RELEASE_NOTES 2020-09-30 14:53:01 -06:00
Ben Doherty 236ed9680c Add MSAA option to VSM (#3084) 2020-09-30 14:51:40 -06:00
Ben Doherty 229fdc9be5 Add View::setShadowType JNI binding (#3094) 2020-09-30 13:20:39 -06:00
Ben Doherty 4af0cdfd4d Use light space Z as VSM depth metric (#3131) 2020-09-30 12:31:03 -06:00
Philip Rideout 451fac7d7b Fix writeJson() for vectors and enums. 2020-09-30 11:12:10 -07:00
Philip Rideout 617dc932bb Fix unit test failure. 2020-09-29 19:59:53 -07:00
Pixelflinger 583c1c07cf SSCT optimizations and fixes
- Use lower depth LOD as the cone radius increases.
  This is the same technique we use for SAO.
  The better cache access significantly improve performance.
  On a test on Pixel4 at 585MHz, SAO pass improves by 30%.
  This also helps the algorithm scale with the shadow distance.

- Shadow direction/length no longer dependent on aspect-ratio and camera
  orientation.
  This is fixed by doing all the computations in screen-space instead of 
  normalized screen space.

- Shadow parameters are no longer dependent on the field of view.

- Also rename dominantLightShadowing.fs to ssct.fs

- remove zoom parameter, it wasn't very useful.
2020-09-29 17:00:32 -07:00
Benjamin Doherty 9e01348dd5 Fix CocoaPod Podspec for Xcode 12 2020-09-29 12:25:13 -06:00
Philip Rideout ec2579bad5 Viewer Settings: remove SSCT scale. 2020-09-29 10:47:35 -07:00
Philip Rideout e5a9a259de Fix build break. 2020-09-29 10:47:35 -07:00
Philip Rideout 6472f645fc viewer: add SCCT to JSON serializer. 2020-09-29 10:47:35 -07:00
Philip Rideout e9ace4e5fb Add jsmn to third_party. 2020-09-29 10:47:35 -07:00
Philip Rideout c119f9bdca gltf_viewer: Re-use ViewSettings structs. 2020-09-29 10:47:35 -07:00
Philip Rideout 7997e4aa21 Introduce libs/viewer and serializable view settings.
This introduces the `viewer::Settings` struct, and a JSON reader /
writer.

This will be used for automated testing and for client / server
communication.

Note that `viewer::Settings` is closely associated with the
`filament::View` API; when updating the latter we will often need to
update the former, as well as some serialization code. This increases
the maintenance burden and I think we should consider using a parser
library like libclang or a macro-based reflection utility.

This PR also migrates SimpleViewer into libs/viewer and un-inlines its
implementation. It does not belong in gltfio because it has an imgui
dependency.
2020-09-29 10:47:35 -07:00
Pixelflinger cdb0f20c6c Save some ALU by assuming the shape of the projection matrix 2020-09-28 10:53:30 -07:00
Pixelflinger 4da58ecb29 Fix mediump issue on mobile 2020-09-28 10:53:30 -07:00
Pixelflinger 075486724f Add JNI support for SSCT 2020-09-28 10:53:30 -07:00
Pixelflinger 530f41c29c fix light vector transform 2020-09-28 10:53:30 -07:00
Pixelflinger 5cbd80136c control the number of rays per pixel 2020-09-28 10:53:30 -07:00
Pixelflinger bfd1de809a Implement screen space cone tracing (SSCT)
This is a technique from Naughty Dog used in TLOU2, where we compute
the "ambient" shadowing of a dominant light in screen-space.

This is currently integrated to the SSAO pass.
2020-09-28 10:53:30 -07:00
Pixelflinger 0f2993aec7 Decouple SSAO bilateral filter from quality setting 2020-09-28 10:53:30 -07:00
Pixelflinger e8bb895c58 refactor SSAO shader a bit
the main change here is that we now have ssaoUtils which contains
utilities that will soon be shared with other "ambiant" effects.
2020-09-28 10:53:30 -07:00
Benjamin Doherty 5cbb97551f Bump version to 1.9.3 2020-09-28 11:40:31 -06:00
Benjamin Doherty f7fc2a0af6 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:34:32 -06:00
Benjamin Doherty 42733c10b7 Bump version to 1.9.2 2020-09-28 11:34:32 -06:00
Benjamin Doherty defee767c3 Merge branch 'rc/1.9.2' into release 2020-09-28 11:27:47 -06:00
Benjamin Doherty 9560318521 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:26:21 -06:00
Philip Rideout d8c7bba403 gltfio: Fix animation by clamping the per-channel interpolant.
Tested with the model in #3124 as well as Fox, BusterDrone, CesiumMan,
InterpolationTest, and VC.

Fixes #3124.
2020-09-26 09:26:40 -07:00
Romain Guy 50e5db4347 Add tasks to manage Sonatype releases (#3127)
* Add tasks to manage Sonatype releases

* Edit comments
2020-09-25 16:07:12 -07:00
Philip Rideout 7019629bcb Vulkan: fix final image barrier used for swap chain.
The image barrier must wait until all write operations are complete;
this was not set up correctly but somehow did not cause problems.
Also tried to document this better, since using an image barrier for
the swap chain seems to be an unusual thing to do (e.g. the Sascha
Willems demos do not do this).
2020-09-25 09:40:12 -07:00
Philip Rideout 5549adc020 JavaScript bindings: fix TextureUsage bitmask.
There's no really good solution, so this just keeps it simple and makes
is so that embind consumes an integer rather than an embind enum object.

Tested by hacking _createTextureFromImageFile.

Fixes #3028.
2020-09-24 15:53:20 -07:00
Philip Rideout 947d178f2b matdbg: stable ordering for anonymous materials.
For example, this makes it so that the primary material in Sponza
is *always* "untitled 0", which makes it easier to figure out which
material to modify.
2020-09-24 10:23:58 -07:00
Philip Rideout 29cd7bb6b4 matdbg: use Shift+Ctrl for navigation.
This avoids interference with both the default VSCode bindings and
Mission Control.
2020-09-24 09:54:19 -07:00
Philip Rideout eb5d346e60 matdbg: repair keyboard navigation.
Recall that Ctrl + Up / Down navigates between materials while
Left / Right navigates between variants.

- Make this behavior more explicit in the documentation.
- Shortcuts now use the same ordering as the displayed list.
- Shortcuts now use Cmd on macOS instead of Ctrl to avoid conflict with
  Mission Control defaults.
2020-09-24 09:54:19 -07:00
Philip Rideout 1afb0e2ea4 matdbg: allow edits without trailing newline. 2020-09-24 09:54:11 -07:00
Philip Rideout 89485ae0ae matdbg: fix edits for large shaders.
If the websocket message exceeds a certain size, we might receive it
in chunks and civetweb does not auto-consolidate for us.

Fixed this by adding a length prefix to the edit command.
2020-09-24 09:53:59 -07:00
Philip Rideout 92e1e91261 matdbg: warn user when editing unused variant. 2020-09-24 09:53:59 -07:00
Philip Rideout ac07719414 CString should allow arbitrary data. 2020-09-24 09:53:59 -07:00
Philip Rideout 4a604c2513 matdbg: do not hide anonymous materials
This change also makes it so that matdbg shows a numeric suffix to help
with duplicated names, and fixes a bug with names that start with
non-alpha characters.
2020-09-23 16:03:03 -07:00
Philip Rideout 22312b2090 cmgen / mipgen: add opt-in for ASTC / ETC support.
Block compression is currently only used when we invoke mipgen for the
suzanne demo. This PR makes it easy to disable.

Block compression is still enabled in our CMake build, but other build
systems can simply omit BlockCompression.{h,cpp} from imageio (as well
as the two third_party libs) and it will "just work".
2020-09-23 11:17:27 -07:00
Philip Rideout 1ebdb18eae gltfio: add async cancellation API 2020-09-23 10:53:55 -07:00
Philip Rideout 450fe214f9 Flip the shading normal when det < 0.
This was tested by replacing the node 0 scale in BusterDrone with
[-1, 1, 1].

For future reference, commit f728776 shows when we switched from
transpose(inverse()) to cof(). This was a good change, but before that
particular change, we had a "two wrongs made a right" situation for
mirrored normals.

Fixes #3001.
2020-09-22 16:54:44 -07:00
Philip Rideout 97c1f99cab gltfio: Fix "uniform not found" errors.
The equality operator for MaterialKey was missing some fields (also, its
ordering was inconsistent with the struct), which caused faulty behavior
in the material cache.

I ran into this bug when testing against a Blender-exported model that
has some materials with texture transforms, and some without.
2020-09-22 14:12:47 -07:00
Romain Guy 9830925a96 Disable clear coat layer IOR change in glTF files (#3104)
The glTF spec doesn't call for this and there are extensions
to deal with this manually.
2020-09-21 20:40:35 -07:00
Pixelflinger c3975f2640 APIs to enable/disable screen space refraction
Just like with shadows, this is a toggle to entirely disable
screen space refraction.

Added missing getters, and minor refactoring.
2020-09-21 16:30:56 -07:00
Pixelflinger 6c8e134d01 Random engine should be owned by Engine
This way it can be used elsewhere.
2020-09-21 11:01:58 -07:00
Benjamin Doherty ef09feb048 Bump version to 1.9.2 2020-09-21 11:16:53 -06:00
Benjamin Doherty a0fb396ba4 Update RELEASE_NOTES headings 2020-09-21 11:08:57 -06:00
Benjamin Doherty b3a79bf82b Update RELEASE_NOTES for 1.9.1 2020-09-21 11:02:20 -06:00
Benjamin Doherty 35ace36b7d Bump version to 1.9.1 2020-09-21 11:02:11 -06:00
Benjamin Doherty 39f323fe09 Merge branch 'rc/1.9.1' into release 2020-09-21 11:00:07 -06:00
Benjamin Doherty 11b95304ea Merge branch 'release' into rc/1.9.1 2020-09-21 10:59:52 -06:00
Benjamin Doherty b7c30a7916 Update RELEASE_NOTES for 1.9.1 2020-09-21 10:59:06 -06:00
Pixelflinger 73f1ddfebf ssao: reduce creases caused by geometry tessellation
We borrow a page from the HBAO book here and allow to limit the angle
with the horizon of SSAO samples. This can help reducing the effects
of low tessellation, which tend to create unwanted creases with SSAO.
2020-09-20 22:34:34 -07:00
Pixelflinger ed8db2f58f fix a recent regression with contact shadows
contact shadows wouldn't work if shadowmap-based shadows were not
enabled, in this case the (unneeded) shadow pass would run and
attempt to create the shadow-map with an incorrect size (0), which
would later crash/assert in the backend.
2020-09-20 22:34:14 -07:00
Pixelflinger 06a13d2e25 remove remnants of when we had a depth preps
DEPTH_PREPASS is never set, not need to check for it.
2020-09-18 12:17:38 -07:00
Pixelflinger 377f043ded smooth out the transition from the background layer
This is a bit of a hack but it helps a lot -- for some reason the
background layer often has a sharp transition to the in-focus plane and 
because we're calculating the DoF at 1/4 resolution these transitions
are quite visible. We work around this by fading out the transition over
a 1 CoC unit, specifically between a CoC of 2 to 1 pixel. Below 1 pixel,
we currently clamp to 0.
2020-09-18 09:42:23 -07:00
Pixelflinger ea057ca754 fix typo -- ResourceAllocator is not in fg:: namespace anymore 2020-09-17 15:17:22 -07:00
Romain Guy 60ef6581c1 Fix compilation issue with clang 12 2020-09-17 10:02:08 -07:00
Romain Guy 2708b3d076 Initialize fields to nullptr to avoid crashes
This happens when a Texture with no callback is created.
2020-09-17 09:00:34 -07:00
Romain Guy 6dc278c551 Update cgltf (#3092)
Adds support for glTF extensions we want to support:
  KHR_materials_ior
  KHR_materials_specular
2020-09-17 08:52:30 -07:00
Pixelflinger e4c1557159 fix how we handle "emulated" MSRTT
The sidecar buffer for multisampled_render_to_texture emulation was
stored with the texture, instead of the rendertarget, this prevented
a single texture to be used as an attachment of multiple render targets
with different sample counts.
2020-09-16 17:36:41 -07:00
Pixelflinger 090c02b2cf non-sampleable textures didn't support "magic resolve"
There was an inconsistency in the gles backend where non-sampleable,
non-MS textures failed (assert) if they were used with a render target 
with MS (i.e. "magic resolve" case).

We fix this by taking the same code path for textures and renderbuffers,
the only difference being the calls to glFrameBufferRenderbuffer
instead of glFramebufferTexture2D.
2020-09-16 17:36:41 -07:00
Pixelflinger 86125ca72a fix use after free in the framegraph
resources structures where not cleared when destroyed, and some code
relies in the handles being set or not to decide if a texture should
be used.  in this case, the texture would be set in the shader after
it was destroyed, because its handle wasn't cleared.
2020-09-16 16:55:59 -07:00
Pixelflinger 14532a2e69 several fog fixes
- inScatteringSize actually cannot be set to zero because it produces
  a 0^0 in the shader. So with this change, in-scattering must be
  strictly > 0 to enable.

- inScatteringSize on the java side had an incorrect default value of
  zero (which of course, now doesn't matter anymore).

- also clamp the fog altitude to 1mm which simplifies the shader quite
  a bit for the same result.

Fixes #3069
2020-09-16 00:18:49 -07:00
Pixelflinger 2312d483c1 fix typo and static analysis warnings in libutils 2020-09-15 15:43:03 -07:00
Mathias Agopian 842425e784 code cleanup (typos and warnings) (#3082)
fix typos and some static analysis warnings
2020-09-15 08:33:03 -07:00
Pixelflinger 6211820a70 increase framegraph vector heap
this is needed now that shadows are using the framegraph
2020-09-14 22:23:13 -07:00
Pixelflinger dc16eb04f8 rename .blurScale to .cocScale in dof options
.blurScale was in fact a scale factor applied to the circle of
confusion (which makes it indeed a "blur scale", but let's use
a more precise language here). 

Update comments to show how to  use .cocScale to control the DoF
effect independently from the camera aperture, which can be useful for
artistic reasons.
2020-09-14 22:22:52 -07:00
Ben Doherty 15a24318e8 Render shadow passes with frame graph (#3073) 2020-09-14 15:57:40 -07:00
Ben Doherty c0bd3590b2 Support texture layers in frame graph (#3072) 2020-09-14 15:35:25 -07:00
Ben Doherty b1c78dfc8c Add branching guide (#3077) 2020-09-14 12:12:12 -07:00
Benjamin Doherty 4cae48fc77 Bump version to 1.9.1 2020-09-14 11:51:36 -07:00
Romain Guy 489e926635 Update README.md 2020-09-14 11:36:39 -07:00
Benjamin Doherty b7c38ef0f1 Update release notes for 1.9.0 2020-09-14 11:07:22 -07:00
Benjamin Doherty 38d37d0d59 Bump version to 1.9.0 2020-09-14 11:07:22 -07:00
Pixelflinger 5701ca939a Improvements to SSAO quality
- simulate a standard deviation of 8 by skipping every other pixel
  when blurring the AO buffer at LOW or MEDIuM quality. This creates
  a faint checker pattern, but does look much better than the low
  frequency noise that is introduced otherwise.

- tweak AO parameters to give a more uniform and smooth AO effect by
  default. This also makes AO even more consistant between quality
  modes.

- add a simple dithering stage to AO blur to help eliminate banding
  artifacts at higher sample counts.
2020-09-13 20:26:11 -07:00
Benjamin Doherty 014abbfb63 Fix documentation bug 2020-09-11 15:43:20 -07:00
Benjamin Doherty f097ec7d5a Fix const warning 2020-09-11 15:00:40 -07:00
Ben Doherty be8bd92a34 Remove Google-style line directives driver-side (#3064) 2020-09-11 11:59:50 -07:00
Pixelflinger fb42817304 add float versions of math constants to libmath
e.g. `F_PI` is also available as `d::PI` and `f::PI` as `double` or
`float` respectively.

Most of our uses of those constants are `float` and it was error prone
and cumbersome to have to cast to that each time we used them.

The `F_` constants are intended to mimic `math.h`, however these new
constants are not, and all the "n over" constants are named
`N_OVER_` instead of `N_`, which helps avoiding the confusion that e.g.:
`F_2_PI` is actually `2/pi` and not `2*pi`.

Also added `F_TAU` which is 2 * PI.
2020-09-10 15:39:16 -07:00
Romain Guy c92ebada6f Fix simpler viewer UI, add SSAO options 2020-09-10 09:17:40 -07:00
Pixelflinger c3c535e256 bilateral blur is more configurable
all parameters of the bilateral blur can now be set from the CPU, 
instead of being hardcoded -- this probably prevent the shader compiler
from unrolling the filter, but it's also probably not a big deal.

additionally, we now use a kernel size of 23 (12 samples) when the
SSAO quality is set to HIGH or more.

ssaogen is no longer needed

Higher quality levels used to darken the ssao a lot, now they all have
a consistant look.

Add quality control to material sandbox.

Slightly simplify shader code.
2020-09-09 18:15:31 -07:00
daichen 6c25f5e50f CoroutineScope job should be canceled before destory (#3056) 2020-09-08 21:31:26 -07:00
Pixelflinger b57510cb3c attempt at a better noise for SSAO
We add noise do the radius of the samples on the spiral 
(instead of adding noise only to the angle), this reduces a visible
"echo", especially at higher radii.
2020-09-08 19:17:02 -07:00
Pixelflinger 69d9a178bf rework a bit dithering noise
- don't use frameUniform.time as the temporal noise seed because
  this has a cycle to it. It's not very visible on dithering but
  obvious when used for other things.

- don't use fract(time) since time was already in [0,1] -- though it's
  moot now.

- instead of time pass a random number in [0,1] generated on the CPU
  each frame.
  This will also allow to control temporal noise more easily if
  needed in the future (e.g. for accessibility or rendering tests)
2020-09-08 13:54:54 -07:00
4088 changed files with 561273 additions and 151945 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
+4
View File
@@ -12,3 +12,7 @@ filament/docs/html/**
*tmp*.png
civetweb.txt
/TAGS
settings.json
test*.png
test*.json
results
+29
View File
@@ -0,0 +1,29 @@
![Filament branching strategy](art/diagrams/branching.png)
## Which branch do I open my PR against?
For normal development, open PRs against main. Once they're merged, no further action is necessary.
If you discover a bug with the latest *release candidate*, open a bug fix PR against the release
candidate branch (rc/1.9.0, for example). Once the PR is merged, decide whether it makes sense for
the fix to also go into main. If it was a temporary fix, simply make the _correct_ fix in main as
you would any other change. If the fix is good for main as well, use `git cherry-pick <sha>` to
cherry-pick it into main.
If an immediate hotfix is needed on the *release* branch, open a PR against the release branch. Once
the PR is merged, decide whether the fix is temporary or permanent. If the fix was temporary, make
the _correct_ fix in both the next release candidate branch _and_ main. If the fix is good, use `git
cherry-pick <sha>` to cherry-pick it into the relase candidate branch and main.
## What consitutes a bug?
Only bug fix PRs should be opened against the *release candidate* branch.
Bugs are defined as one of the following _introduced since the prior release_:
- crashes
- rendering issues
- unintentional binary size increases
- unintentional public API changes
For example, a long-standing crash just recently discovered would not necessitate a bug fix PR.
+32 -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.0.1 or more recent
- Android Studio Arctic Fox or more recent
- Android SDK
- Android NDK "side-by-side" 21.3 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/1.39.19.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
@@ -468,3 +443,19 @@ export SWIFTSHADER_LD_LIBRARY_PATH=`pwd`
```
Next, go to your Filament repo and use the [easy build](#easy-build) script with `-t`.
## SwiftShader for CI
Continuous testing turnaround can be quite slow if you need to build SwiftShader from scratch, so we
provide an Ubuntu-based Docker image that has it already built. The Docker image also includes
everything necessary for building Filament. You can fetch and run the image as follows:
```
docker pull ghcr.io/filament-assets/swiftshader
docker run -it ghcr.io/filament-assets/swiftshader
```
To do more with the container, see the helper script at `build/swiftshader/test.sh`.
If you are a team member, you can update the public image to the latest SwiftShader by
following the instructions at the top of `build/swiftshader/Dockerfile`.
+143 -46
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)
@@ -21,6 +19,20 @@ option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the c
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
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."
)
@@ -33,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."
)
# ==================================================================================================
@@ -83,11 +99,35 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
set(LINUX TRUE)
endif()
if (ANDROID OR WEBGL OR IOS)
if (LINUX)
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)
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 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()
@@ -111,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})
@@ -248,7 +296,10 @@ if (LINUX)
# /usr/bin/ld: ../bluegl/libbluegl.a(BlueGL.cpp.o): relocation R_X86_64_32S
# against `.bss' can not be used when making a shared object; recompile with -fPIC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if (ANDROID)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Werror=unguarded-availability")
endif()
if (CYGWIN)
@@ -268,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
# ==================================================================================================
@@ -282,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()
@@ -348,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)
@@ -383,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
# ==================================================================================================
@@ -396,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()
@@ -406,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})
@@ -418,8 +488,23 @@ set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
# ==================================================================================================
# choose where to put the objects in the dist folder
if (NOT DIST_ARCH)
set(DIST_ARCH x86_64)
# On Apple silicon, the value of CMAKE_HOST_SYSTEM_PROCESSOR varies based on the CMake process's
# own architecture. Because of this, running a x86_64 CMake binary on Apple silicon will cause
# DIST_ARCH to be set incorrectly.
set(DIST_ARCH "${CMAKE_HOST_SYSTEM_PROCESSOR}")
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*;.*")
set(DIST_ARCH "universal")
else()
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()
@@ -437,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)
@@ -457,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(
@@ -490,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()
@@ -544,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)
@@ -574,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()
@@ -593,24 +694,19 @@ set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
if (WEBGL)
add_subdirectory(web/filament-js)
add_subdirectory(web/samples)
add_subdirectory(${EXTERNAL}/imgui/tnt)
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(${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}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
@@ -626,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()
+75 -58
View File
@@ -31,39 +31,28 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.9.0'
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.0'
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,29 +107,76 @@ 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
- Anisotropic lighting
- Approximated translucent (subsurface) materials
- Cloth shading
- Cloth/fabric/sheen shading
- Normal mapping & ambient occlusion mapping
- Image-based lighting
- 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
- 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
- Encodings
- [x] Embeded
- [x] Binary
- Primitive Types
- [x] Points
- [x] Lines
- [ ] Line Loop
- [x] Line Strip
- [x] Triangles
- [x] Triangle Strip
- [ ] Triangle Fan
- Animation
- [x] Transform animation
- [x] Linear interpolation
- [x] Morph animation
- [x] Sparse accessor
- [x] Skin animation
- [x] Joint animation
- Extensions
- [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
## Rendering with Filament
@@ -218,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
@@ -264,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
@@ -286,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
@@ -308,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
+140
View File
@@ -0,0 +1,140 @@
# Filament Release Guide
This guide makes use of some "environment variables":
- $RELEASE = the new version of Filament we are releasing today. (e.g., 1.9.3)
- $NEXT_RELEASE = the version we plan to release next week (e.g., 1.9.4)
Before starting, ensure that each of these branches is up-to-date with origin:
- release
- rc/$RELEASE
- main
## 0. Make sure the rc/$RELEASE branch has the correct version.
It should have the version corresponding to its name, $RELEASE.
## 1. Update RELEASE_NOTES.md on the rc branch.
Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE
and write release notes. To see which commits make up the release, run:
```
build/common/release.sh -c rc/$RELEASE
```
Commit the changes to rc/$RELEASE with the title:
```
Update RELEASE_NOTES for $RELEASE
```
## 2. Bump versions on main to $RELEASE.
Checkout main and run the following command to bump Filament's version to $RELEASE:
```
build/common/bump-version.sh $RELEASE
```
Commit changes to main with the title:
```
Release Filament $RELEASE
```
Do not push to origin yet.
## 3. Cherry-pick RELEASE_NOTES change from rc branch to main.
```
git cherry-pick rc/$RELEASE
```
Update the headers. The "Next release" header becomes a header for $NEXT_RELEASE, and a new "Next
release" header is added.
For example, this:
```
## Next release (main branch)
- foo
- bar
## v1.9.3
- baz
- bat
```
becomes:
```
## Next release (main branch)
## v1.9.4
- foo
- bar
## v1.9.3
- baz
- bat
```
Ammend these changes to the cherry-picked change.
```
git add -u
git commit --amend --no-edit
```
## 4. Run release script.
```
build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
```
This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc
branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally.
## 5. Push the release branch.
```
git push origin release
```
## 6. Create the GitHub 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 (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
```
## 8. Bump the version on the new rc branch to $NEXT_RELEASE.
```
git checkout rc/$NEXT_RELEASE
build/common/bump-version.sh $NEXT_RELEASE
```
Commit the changes to rc/$NEXT_RELEASE with the title:
```
Bump version to $NEXT_RELEASE
```
## 9. Push main.
```
git push origin main
```
## 10. Push the new rc branch.
```
git push origin -u rc/$NEXT_RELEASE
```
+552 -1
View File
@@ -3,7 +3,558 @@
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
## 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
- Added support for Apple silicon Macs. build.sh can now be used to build on either Apple silicon or
Intel-based Macs. Pass the `-l` flag to build universal binaries.
- Added `sheenColor` and `sheenRoughness` properties to materials to create cloth/fabric.
- Materials generation using `libfilamat` is now multi-threaded.
- `MaterialBuilder::build()` now expects a reference to a `JobSystem` to multi-thread shaders
generation. A `JobSystem` can be obtained with `Engine::getJobSystem()` when using Filament,
or created directly otherwise. (⚠️ **API change**)
- Add planar reflection RenderTarget demo.
- Metal: honor inverseFrontFaces RasterState.
- Metal: Fix crash when switching between views with shadowing enabled.
- Metal: Fix crash when calling Texture::setImage() on SAMPLER_2D_ARRAY texture.
- gltfio: added support for `KHR_materials_sheen`.
- gltfio: shader optimizations are now disabled by default, unless opting in or using ubershaders.
- gltfio: Fix "_maskThreshold not found" error.
- gltfio on Java: fix potential memory leak in AssetLoader#destroy.
- gltfio: fix crash during async texture decode.
- gltfio: support animation in dynamically-added instances.
- gltfio: Improve robustness when decoding textures.
- gltfio: Fix animator crash for orphaned nodes.
- gltfio: fix tangents with morphing.
- gltf_viewer: fix very sporadic crash when exiting.
- gltf_viewer: fix crash when rapidly switching between glTF models.
- WebGL: Fix samples erroring on Windows with Chrome.
- WebGL: Support `highlight` for setBloomOptions in JavaScript.
- WebGL: Include TypeScript bindings in releases.
- engine: Fix, punctual lights get clipped at certain angles.
- engine: Fix memory leak when calling `View::setViewport` frequently.
- engine: Fix, materials not working on some Qualcomm devices.
- engine: Modulate emissive by alpha on blended objects.
- engine: Fix, RenderTarget cleared multiple times.
- Java: Fix JNI bindings for color grading.
- Android: reduced binary size.
## v1.9.10
- Introduce `libibl_lite` library.
- engine: Fix `EXC_BAD_INSTRUCTION` seen when using headless SwapChains on macOS with OpenGL.
- engine: Add new callback API to `SwapChain`.
- engine: Fix SwiftShader crash when using an IBL without a reflections texture.
- filamat: Shrink internal `Skybox` material size.
- filamat: improvements to generated material size.
- filamat: silence spirv-opt warnings in release builds.
- matc: Add fog variant filter.
- matc: Fix crash when building mobile materials.
- math: reduce template bloat for matrices.
## v1.9.9
- 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.
## v1.9.8
- Fix a few Fence-related bugs
- gltfio: add createInstance() to AssetLoader.
- gltfio: fix ASAN issue when consuming invalid animation.
- gltfio: do not segfault on invalid primitives.
- gltfio: add safety checks to getAnimator.
- gltfio: fix segfault when consuming invalid file.
- Vulkan: various internal refactoring and improvements
- mathio: add ostream operator for quaternions.
- Fix color grading not applied when dithering is off.
## v1.9.7
- Vulkan: improvements to the ReadPixels implementation.
- Vulkan: warn instead of panic for sampler overflow.
- Vulkan: fix leak with headless swap chain.
- PlatformVkLinux now supports all combos of XLIB and XCB.
- Fix TypeScript binding for TextureUsage.
## v1.9.6
- Added View::setVsmShadowOptions (experimental)
- Add anisotropic shadow map sampling with VSM (experimental)
- matc: fixed bug where some compilation failures still exited with code 0
- Vulkan + Android: fix build break
- Add optional XCB support to PlatformVkLinux
- Fix Vulkan black screen on Windows with NVIDIA hardware
## v1.9.5
- Added a new Live Wallpaper Android sample
- `UiHelper` now supports managing a `SurfaceHolder`
- Fix: an internal texture resource was never destroyed
- Fix: hang on 2-CPU machines
- Fix: Vulkan crash when using shadow cascades
- Linux fixes for headless SwiftShader
- Fix null pointer dereference in `FIndirectLight`
- Fix Windows build by avoiding nested initializers
- Vulkan: support readPixels and headless swap chains
- VSM improvements
## v1.9.4
- Add screen space cone tracing (SSCT)
- Improvements to VSM shadow quality
- New `ShadowOptions` control to render Variance Shadow Maps (VSM) with MSAA (experimental)
- Improvements and fixes to screen-space ambient occlusion
- gltf_viewer: add --headless option
- gltf_viewer: Add new automation UI and functionality
## v1.9.3
- engine: Added new APIs to enable/disable screen space refraction
- engine: Fix, flip the shading normal when det < 0.
- gltfio: Fix animation by clamping the per-channel interpolant.
- gltfio: add async cancellation API
- gltfio: Fix "uniform not found" errors.
- gltfio: Disable clear coat layer IOR change in glTF files (#3104)
- Vulkan: fix final image barrier used for swap chain.
- matdbg: Various improvements
- JavaScript bindings: fix TextureUsage bitmask.
- cmgen / mipgen: add opt-in for ASTC / ETC support.
## v1.9.2
- Fixes / improvements for contact shadows, fog, and DOF
- Reduce SSAO creases caused by geometry tessellation
- Fix compilation warnings and issue with Clang 12
- Fix JNI crashes
- Rename .blurScale to .cocScale in DOF options
## v1.9.1
- Improvements to SSAO quality
- Fix unoptimized shader crashes with certain OpenGL drivers
- Add float versions of math constants to libmath
- filament-utils: fix, `CoroutineScope` job should be canceled before destroy
## v1.9.0
+23 -5
View File
@@ -6,11 +6,29 @@ In addition to the requirements for [building Filament on Windows](../BUILDING.m
need the Android SDK and NDK. See [Getting Started with the
NDK](https://developer.android.com/ndk/guides/) for detailed installation instructions.
You'll also need [Ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or
more recent) and [Git for Windows](https://git-scm.com/download/win) to clone the repository and run
Bash scripts.
Ensure the `%ANDROID_HOME%` environment variable is set to your Android SDK installation location.
On Windows, we require VS2019 for building the host tools. All of the following commands should be
executed in a *Visual Studio x64 Native Tools Command Prompt for VS 2019*.
### A Note About Python 3
Python 3 is required. If CMake errors because it cannot find Python 3:
```
Could NOT find PythonInterp: Found unsuitable version "1.4", but required is at least "3"
```
then add the following flag to the CMake invocations:
```
-DPYTHON_EXECUTABLE:FILEPATH=\path\to\python3
```
## Desktop Tools
First, a few Filament tools need to be compiled for desktop.
@@ -104,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
```
+75 -32
View File
@@ -1,67 +1,99 @@
// 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
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseRepository
//
// The following is needed in ~/gradle/gradle.properties:
//
// SONATYPE_NEXUS_USERNAME=nexus_user
// SONATYPE_NEXUS_PASSWORD=nexus_password
//
// nexusUsername=nexus_user
// nexusPassword=nexus_password
//
// signing.keyId=pgp_key_id
// signing.password=pgp_key_password
// signing.secretKeyRingFile=/Users/user/.gnupg/maven_signing.key
//
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': 29,
'compileSdk': 29,
'kotlin': '1.3.72',
'buildTools': '30.0.1',
'ndk': '21.3.6528147'
'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.0.1'
// 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}"
}
@@ -76,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",
@@ -99,10 +130,20 @@ buildscript {
repositories {
mavenCentral()
google()
jcenter()
}
}
plugins {
id 'io.codearte.nexus-staging' version '0.30.0'
}
// Nexus Staging configuration
// See https://github.com/Codearte/gradle-nexus-staging-plugin/
nexusStaging {
packageGroup = 'com.google.android'
stagingProfileId = '9a75a224a4f17b'
}
subprojects {
group = GROUP
version = VERSION_NAME
@@ -110,7 +151,6 @@ subprojects {
repositories {
mavenCentral()
google()
jcenter()
}
if (!name.startsWith("sample")) {
@@ -135,11 +175,13 @@ subprojects {
ndk {
abiFilters(*rootProject.ext.abis)
}
}
consumerProguardFiles '../proguard-rules.pro'
}
externalNativeBuild {
cmake {
version "3.19.0+"
path "CMakeLists.txt"
}
}
@@ -161,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"
+50 -27
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,55 +45,76 @@ 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,
// -----------------------------------------------------------------------------------------------
JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
return new JniCallback(env, handler, callback);
}
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
: mHandler(env->NewGlobalRef(handler)),
mCallback(env->NewGlobalRef(callback)) {
acquireCallbackJni(env, mCallbackUtils);
}
JniCallback::~JniCallback() = default;
void JniCallback::post(void* user, filament::backend::CallbackHandler::Callback callback) {
callback(user);
}
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)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mBuffer(std::move(buffer)) {
acquireCallbackJni(env, mCallbackUtils);
: JniCallback(env, handler, callback),
mBuffer(std::move(buffer)) {
}
JniBufferCallback::~JniBufferCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
JniBufferCallback::~JniBufferCallback() = default;
void JniBufferCallback::invoke(void*, size_t, void* user) {
JniBufferCallback* data = reinterpret_cast<JniBufferCallback*>(user);
delete data;
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* engine,
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)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mImage(image) {
acquireCallbackJni(env, mCallbackUtils);
: JniCallback(env, handler, callback),
mImage(image) {
}
JniImageCallback::~JniImageCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
JniImageCallback::~JniImageCallback() = default;
void JniImageCallback::invoke(void*, void* user) {
JniImageCallback* data = reinterpret_cast<JniImageCallback*>(user);
delete data;
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;
}
+47 -26
View File
@@ -18,57 +18,78 @@
#include <jni.h>
#include "common/CallbackUtils.h"
#include "common/NioUtils.h"
#include <backend/CallbackHandler.h>
#include <filament/Engine.h>
struct CallbackJni {
#ifdef ANDROID
jclass handlerClass;
jmethodID post;
#ifdef __ANDROID__
jclass handlerClass = nullptr;
jmethodID post = nullptr;
#endif
jclass executorClass;
jmethodID execute;
jclass executorClass = nullptr;
jmethodID execute = nullptr;
};
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(JniBufferCallback const &) = delete;
JniImageCallback(JniBufferCallback&&) = delete;
~JniImageCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
virtual ~JniImageCallback();
long mImage;
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;
}
+8 -4
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)
@@ -33,13 +34,16 @@ add_library(shaders STATIC IMPORTED)
set_target_properties(shaders PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libshaders.a)
set(FILAMAT_INCLUDE_DIRS
../../libs/utils/include
)
include_directories(${FILAMENT_DIR}/include)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
add_library(filamat-jni SHARED
src/main/cpp/MaterialBuilder.cpp
)
add_library(filamat-jni SHARED src/main/cpp/MaterialBuilder.cpp)
target_include_directories(filamat-jni PRIVATE ${FILAMAT_INCLUDE_DIRS})
target_link_libraries(filamat-jni
${FILAMAT_FLAVOR}
@@ -18,6 +18,8 @@
#include <filamat/MaterialBuilder.h>
#include <utils/JobSystem.h>
using namespace filament;
using namespace filamat;
@@ -45,9 +47,23 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyMaterialBuilder
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder) {
jlong nativeBuilder, jlong nativeJobSystem) {
auto builder = (MaterialBuilder*) nativeBuilder;
return (jlong) new Package(builder->build());
auto jobSystem = (utils::JobSystem*) nativeJobSystem;
if (nativeJobSystem == 0) {
jobSystem = new utils::JobSystem;
jobSystem->adopt();
}
jlong result = (jlong) new Package(builder->build(*jobSystem));
if (nativeJobSystem == 0) {
jobSystem->emancipate();
delete jobSystem;
}
return result;
}
extern "C" JNIEXPORT jbyteArray JNICALL
@@ -107,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);
}
@@ -130,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);
}
@@ -239,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) {
@@ -275,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) {
@@ -17,17 +17,29 @@
package com.google.android.filament.filamat;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
public class MaterialBuilder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
private final BuilderFinalizer mFinalizer;
private final long mNativeObject;
private static Class<?> sEngineClass = null;
private static Method sGetNativeJobSystemMethod = null;
static {
System.loadLibrary("filamat-jni");
try {
sEngineClass = Class.forName("com.google.android.filament.Engine");
sGetNativeJobSystemMethod = sEngineClass.getDeclaredMethod("getNativeJobSystem");
} catch (ClassNotFoundException | NoSuchMethodException e) {
// It's okay if we don't find it, this is to avoid creating dependencies
}
}
public enum Shading {
@@ -79,7 +91,7 @@ public class MaterialBuilder {
SHADOW
}
public enum SamplerPrecision {
public enum ParameterPrecision {
LOW,
MEDIUM,
HIGH,
@@ -102,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 {
@@ -235,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;
@@ -337,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);
@@ -379,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);
@@ -421,9 +462,55 @@ public class MaterialBuilder {
return this;
}
/**
* Validates, builds, and returns the compiled material. While this method never
* returns null, the returned {@link MaterialPackage} may be invalid. Call
* {@link MaterialPackage#isValid()} before using it.
*
* Calling this method is equivalent to calling {@link #build(Object)} and passing
* <code>null</code> as the job system provider.
*
* @see #build(Object)
*/
@NonNull
public MaterialPackage build() {
long nativePackage = nBuilderBuild(mNativeObject);
return build(null);
}
/**
* Validates, builds, and returns the compiled material. While this method never
* returns null, the returned {@link MaterialPackage} may be invalid. Call
* {@link MaterialPackage#isValid()} before using it.
*
* You can pass a job system provider to this method, or null. When passing null
* or an invalid job system provider, a temporary job system will be created which
* is less efficient than reusing an existing job system.
*
* Currently the only valid type of job system provider is an <code>Engine</code>
* instance from the main Filament library (<code>com.google.android.filament.Engine</code>).
*
* If you are using Filament and the filamat library together you <em>must</em> pass an
* <code>Engine</code> as the job system provider, <em>or</em> invoke
* <code>MaterialBuilder</code> from a thread other than the thread used to invoke Filament
* APIs.
*
* @param jobSystemProvider An <code>Engine</code> instance or null
*/
@NonNull
public MaterialPackage build(@Nullable Object jobSystemProvider) {
long nativeJobSystem = 0;
if (jobSystemProvider != null && sEngineClass != null) {
if (sEngineClass.isInstance(jobSystemProvider) && sGetNativeJobSystemMethod != null) {
try {
//noinspection ConstantConditions
nativeJobSystem = (Long) sGetNativeJobSystemMethod.invoke(jobSystemProvider);
} catch (IllegalAccessException | InvocationTargetException e) {
// Ignore
}
}
}
long nativePackage = nBuilderBuild(mNativeObject, nativeJobSystem);
byte[] data = nGetPackageBytes(nativePackage);
MaterialPackage result =
new MaterialPackage(ByteBuffer.wrap(data), nGetPackageIsValid(nativePackage));
@@ -455,7 +542,7 @@ public class MaterialBuilder {
private static native long nCreateMaterialBuilder();
private static native void nDestroyMaterialBuilder(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder, long nativeJobSystem);
private static native byte[] nGetPackageBytes(long nativePackage);
private static native boolean nGetPackageIsValid(long nativePackage);
private static native void nDestroyPackage(long nativePackage);
@@ -465,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,
@@ -487,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,
@@ -498,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,
+26 -6
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})
@@ -17,14 +19,18 @@ add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(ibl STATIC IMPORTED)
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
add_library(ibl-lite STATIC IMPORTED)
set_target_properties(ibl-lite PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl-lite.a)
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,10 +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
@@ -90,22 +104,28 @@ target_link_libraries(filament-jni
PRIVATE backend
PRIVATE filaflat
PRIVATE filabridge
PRIVATE geometry
PRIVATE ibl
PRIVATE ibl-lite
PRIVATE log
PRIVATE GLESv3
PRIVATE EGL
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)
+25 -1
View File
@@ -1,4 +1,28 @@
LIBFILAMENT {
global: *filament*; JNI*;
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*;
local: *;
};
@@ -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,31 @@ 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();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetJobSystem(JNIEnv*, jclass, jlong nativeEngine) {
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) {
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,9 +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
.maxShadowDistance = maxShadowDistance,
.vsm = {
.msaaSamples = (uint8_t) vsmMsaaSamples,
.blurWidth = blurWidth
},
.shadowBulbRadius = shadowBulbRadius
};
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));
@@ -185,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) {
@@ -209,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,
@@ -376,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);
}
@@ -91,7 +91,7 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_Material_nGetRefraction(JNIEnv*, jclass,
Java_com_google_android_filament_Material_nGetRefractionMode(JNIEnv*, jclass,
jlong nativeMaterial) {
Material* material = (Material*) nativeMaterial;
return (jint)material->getRefractionMode();
@@ -204,9 +204,20 @@ Java_com_google_android_filament_Material_nGetParameters(JNIEnv* env, jclass,
jfieldID parameterSamplerOffset = env->GetStaticFieldID(parameterClass,
"SAMPLER_OFFSET", "I");
jfieldID parameterSubpassOffset = env->GetStaticFieldID(parameterClass,
"SUBPASS_OFFSET", "I");
jint offset = env->GetStaticIntField(parameterClass, parameterSamplerOffset);
jint subpassOffset = env->GetStaticIntField(parameterClass, parameterSubpassOffset);
for (size_t i = 0; i < received; i++) {
jint type = info[i].isSampler ? (jint) info[i].samplerType + offset : (jint) info[i].type;
jint type;
if (info[i].isSampler) {
type = (jint) info[i].samplerType + offset;
} else if (info[i].isSubpass) {
type = subpassOffset;
} else {
type = (jint) info[i].type;
}
env->CallStaticVoidMethod(
parameterClass, parameterAdd,
@@ -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);
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,19 @@
#include <jni.h>
#include <gltfio/MaterialProvider.h>
#include <filament/SwapChain.h>
#include "common/CallbackUtils.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;
Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* env, jclass,
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto *callback = JniCallback::make(env, handler, runnable);
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);
}
+186 -20
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
@@ -67,9 +71,9 @@ Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong n
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
Java_com_google_android_filament_View_nSetShadowingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setShadowsEnabled(enabled);
view->setShadowingEnabled(enabled);
}
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,17 +129,47 @@ 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);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
View* view = (View*) nativeView;
view->setShadowType((View::ShadowType) type);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
jint anisotropy, jboolean mipmapping, jfloat minVarianceScale,
jfloat lightBleedReduction) {
View* view = (View*) nativeView;
View::VsmShadowOptions options;
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,
@@ -196,18 +236,45 @@ 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 upsampling, jboolean enabled) {
jfloat bilateralThreshold,
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jboolean bentNormals,
jfloat minHorizonAngleRad) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = {
.radius = radius,
.power = power,
.bias = bias,
.resolution = resolution,
.intensity = intensity,
.quality = (View::QualityLevel)quality,
.upsampling = (View::QualityLevel)upsampling,
.enabled = (bool)enabled
};
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.radius = radius;
options.power = power;
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);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetSSCTOptions(JNIEnv *, jclass, jlong nativeView,
jfloat ssctLightConeRad, jfloat ssctStartTraceDistance, jfloat ssctContactDistanceMax,
jfloat ssctIntensity, jfloat ssctLightDirX, jfloat ssctLightDirY, jfloat ssctLightDirZ,
jfloat ssctDepthBias, jfloat ssctDepthSlopeBias, jint ssctSampleCount,
jint ssctRayCount, jboolean ssctEnabled) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.ssct.lightConeRad = ssctLightConeRad;
options.ssct.shadowDistance = ssctStartTraceDistance;
options.ssct.contactDistanceMax = ssctContactDistanceMax;
options.ssct.intensity = ssctIntensity;
options.ssct.lightDirection = math::float3{ ssctLightDirX, ssctLightDirY, ssctLightDirZ };
options.ssct.depthBias = ssctDepthBias;
options.ssct.depthSlopeBias = ssctDepthSlopeBias;
options.ssct.sampleCount = (uint8_t)ssctSampleCount;
options.ssct.rayCount = (uint8_t)ssctRayCount;
options.ssct.enabled = (bool)ssctEnabled;
view->setAmbientOcclusionOptions(options);
}
@@ -215,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 = {
@@ -228,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);
}
@@ -261,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 blurScale, 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, .blurScale = blurScale,
.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"
@@ -277,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,
@@ -285,3 +389,65 @@ Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *,
view->setTemporalAntiAliasingOptions({
.filterWidth = filterWidth, .feedback = feedback, .enabled = (bool) enabled});
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return (jboolean)view->isShadowingEnabled();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetScreenSpaceRefractionEnabled(JNIEnv *, jclass,
jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setScreenSpaceRefractionEnabled((bool)enabled);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsScreenSpaceRefractionEnabled(JNIEnv *, jclass,
jlong nativeView) {
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,109 +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;
foundJawt = JAWT_GetAWT(env, &awt);
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
@@ -270,7 +365,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder shadowsMidtonesHighlights(
public Builder shadowsMidtonesHighlights(
@NonNull @Size(min = 4) float[] shadows,
@NonNull @Size(min = 4) float[] midtones,
@NonNull @Size(min = 4) float[] highlights,
@@ -309,7 +404,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder slopeOffsetPower(
public Builder slopeOffsetPower(
@NonNull @Size(min = 3) float[] slope,
@NonNull @Size(min = 3) float[] offset,
@NonNull @Size(min = 3) float[] power) {
@@ -360,7 +455,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder vibrance(float vibrance) {
public Builder vibrance(float vibrance) {
nBuilderVibrance(mNativeBuilder, vibrance);
return this;
}
@@ -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
@@ -568,7 +569,7 @@ public class Engine {
* Destroys a {@link ColorGrading} and frees all its associated resources.
* @param colorGrading the {@link ColorGrading} to destroy
*/
public void destroySkybox(@NonNull ColorGrading colorGrading) {
public void destroyColorGrading(@NonNull ColorGrading colorGrading) {
assertDestroy(nDestroyColorGrading(getNativeObject(), colorGrading.getNativeObject()));
colorGrading.clearNativeObject();
}
@@ -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>,
@@ -654,13 +663,21 @@ public class Engine {
return mNativeObject;
}
@UsedByReflection("MaterialBuilder.java")
public long getNativeJobSystem() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Engine");
}
return nGetJobSystem(getNativeObject());
}
private void clearNativeObject() {
mNativeObject = 0;
}
private static void assertDestroy(boolean success) {
if (!success) {
throw new IllegalStateException("Object couldn't be destoyed (double destroy()?)");
throw new IllegalStateException("Object couldn't be destroyed (double destroy()?)");
}
}
@@ -675,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);
@@ -686,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);
@@ -698,4 +715,6 @@ public class Engine {
private static native long nGetTransformManager(long nativeEngine);
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
@@ -305,6 +326,37 @@ public class LightManager {
*</p>
*/
public float maxShadowDistance = 0.3f;
/*
* Options prefixed with 'vsm' are available when the View's ShadowType is set to VSM.
*
* @see View#setShadowType
*/
/**
* The number of MSAA samples to use when rendering VSM shadow maps.
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
* off MSAA.
* Higher values may not be available depending on the underlying hardware.
*
* <p>
* <strong>Warning: This API is still experimental and subject to change.</strong>
* </p>
*/
@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 {
@@ -403,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)
*
@@ -432,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.shadowFarHint, options.stable,
options.polygonOffsetConstant, options.polygonOffsetSlope,
options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
options.blurWidth, options.shadowBulbRadius);
return this;
}
@@ -722,7 +789,7 @@ public class LightManager {
@NonNull
public Type getType(@EntityInstance int i) {
return Type.values()[nGetType(mNativeObject, i)];
return sTypeValues[nGetType(mNativeObject, i)];
}
/**
@@ -757,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.
*
@@ -1046,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;
}
@@ -1059,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);
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);
@@ -1072,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);
@@ -1099,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,
@@ -233,7 +249,8 @@ public class Material {
SAMPLER_2D_ARRAY,
SAMPLER_CUBEMAP,
SAMPLER_EXTERNAL,
SAMPLER_3D
SAMPLER_3D,
SUBPASS_INPUT
}
public enum Precision {
@@ -247,6 +264,10 @@ public class Material {
@UsedByNative("Material.cpp")
private static final int SAMPLER_OFFSET = Type.MAT4.ordinal() + 1;
@SuppressWarnings("unused")
@UsedByNative("Material.cpp")
private static final int SUBPASS_OFFSET = Type.SAMPLER_3D.ordinal() + 1;
@NonNull
public final String name;
@NonNull
@@ -270,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);
@@ -368,7 +389,7 @@ public class Material {
* Material Models</a>
*/
public Shading getShading() {
return Shading.values()[nGetShading(getNativeObject())];
return EnumCache.sShadingValues[nGetShading(getNativeObject())];
}
/**
@@ -379,7 +400,7 @@ public class Material {
* Vertex and attributes: interpolation</a>
*/
public Interpolation getInterpolation() {
return Interpolation.values()[nGetInterpolation(getNativeObject())];
return EnumCache.sInterpolationValues[nGetInterpolation(getNativeObject())];
}
/**
@@ -390,7 +411,7 @@ public class Material {
* Blending and transparency: blending</a>
*/
public BlendingMode getBlendingMode() {
return BlendingMode.values()[nGetBlendingMode(getNativeObject())];
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
}
/**
@@ -401,7 +422,7 @@ public class Material {
* Blending and transparency: refraction</a>
*/
public RefractionMode getRefractionMode() {
return RefractionMode.values()[nGetRefractionMode(getNativeObject())];
return EnumCache.sRefractionModeValues[nGetRefractionMode(getNativeObject())];
}
/**
@@ -412,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.
*
@@ -424,7 +444,7 @@ public class Material {
* Vertex and attributes: vertexDomain</a>
*/
public VertexDomain getVertexDomain() {
return VertexDomain.values()[nGetVertexDomain(getNativeObject())];
return EnumCache.sVertexDomainValues[nGetVertexDomain(getNativeObject())];
}
/**
@@ -435,7 +455,7 @@ public class Material {
* Rasterization: culling</a>
*/
public CullingMode getCullingMode() {
return CullingMode.values()[nGetCullingMode(getNativeObject())];
return EnumCache.sCullingModeValues[nGetCullingMode(getNativeObject())];
}
/**
@@ -526,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]);
@@ -755,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:
@@ -763,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()
@@ -784,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:
@@ -792,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()
@@ -813,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:
@@ -821,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}.
@@ -85,6 +85,12 @@ public class SwapChain {
*/
public static final long CONFIG_READABLE = 0x2;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
SwapChain(long nativeSwapChain, Object surface) {
mNativeObject = nativeSwapChain;
mSurface = surface;
@@ -98,6 +104,31 @@ public class SwapChain {
return mSurface;
}
/**
* FrameCompletedCallback is a callback function that notifies an application when a frame's
* contents have completed rendering on the GPU.
*
* <p>
* Use setFrameCompletedCallback to set a callback on an individual SwapChain. Each time a frame
* completes GPU rendering, the callback will be called.
* </p>
*
* <p>
* The FrameCompletedCallback is guaranteed to be called on the main Filament thread.
* </p>
*
* <p>
* Warning: Only Filament's Metal backend supports frame callbacks. Other backends ignore the
* callback (which will never be called) and proceed normally.
* </p>
*
* @param handler A {@link java.util.concurrent.Executor Executor}.
* @param callback The Runnable callback to invoke.
*/
public void setFrameCompletedCallback(@NonNull Object handler, @NonNull Runnable callback) {
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SwapChain");
@@ -108,4 +139,6 @@ public class SwapChain {
void clearNativeObject() {
mNativeObject = 0;
}
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
}
@@ -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,6 +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.
@@ -130,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
@@ -168,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
@@ -176,6 +205,14 @@ public class View {
@NonNull
public QualityLevel quality = QualityLevel.LOW;
/**
* The lowPassFilter setting controls the quality of the low pass filter applied to
* AO estimation. The default is QualityLevel.MEDIUM which is sufficient for most mobile
* applications. QualityLevel.LOW disables the filter entirely.
*/
@NonNull
public QualityLevel lowPassFilter = QualityLevel.MEDIUM;
/**
* The upsampling setting controls the quality of the ambient occlusion buffer upsampling.
* The default is QualityLevel.LOW and uses bilinear filtering, a value of
@@ -188,11 +225,104 @@ public class View {
* enable or disable screen space ambient occlusion
*/
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.
* For e.g. a good values to try could be around 0.2.
*/
public float minHorizonAngleRad = 0.0f;
/**
* Full cone angle in radian, between 0 and pi/2. This affects the softness of the shadows,
* as well as how far they are cast. A smaller angle yields to sharper and shorter shadows.
* The default angle is about 60 degrees.
*/
public float ssctLightConeRad = 1.0f;
/**
* Distance from where tracing starts.
* This affects how far shadows are cast.
*/
public float ssctStartTraceDistance = 0.01f;
/**
* Maximum contact distance with the cone. Intersections between the traced cone and
* geometry samller than this distance are ignored.
*/
public float ssctContactDistanceMax = 1.0f;
/**
* Intensity of the shadows.
*/
public float ssctIntensity = 0.8f;
/**
* Light direction.
*/
@NonNull @Size(min = 3)
public float[] ssctLightDirection = { 0, -1, 0 };
/**
* Depth bias in world units (mitigate self shadowing)
*/
public float ssctDepthBias = 0.01f;
/**
* Depth slope bias (mitigate self shadowing)
*/
public float ssctDepthSlopeBias = 0.01f;
/**
* Tracing sample count, between 1 and 255. This affects the quality as well as the
* distance of the shadows.
*/
public int ssctSampleCount = 4;
/**
* Numbers of rays to trace, between 1 and 255. This affects the noise of the shadows.
* Performance degrades quickly with this value.
*/
public int ssctRayCount = 1;
/**
* Enables or disables SSCT.
*/
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) */
@@ -210,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).
@@ -255,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;
@@ -265,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;
@@ -289,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;
}
/**
@@ -335,9 +511,9 @@ public class View {
public float inScatteringStart = 0.0f;
/**
* size of in-scattering (>=0 to activate). Good values are >> 1 (e.g. ~10 - 100)
* size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100)
*/
public float inScatteringSize = 0.0f;
public float inScatteringSize = -1.0f;
/**
* fog color will be modulated by the IBL color in the view direction
@@ -357,17 +533,81 @@ public class View {
*/
public static class DepthOfFieldOptions {
/** focus distance in world units */
public float focusDistance = 10.0f;
public enum Filter {
NONE,
MEDIAN
}
/** scale factor controlling the amount of blur (values other than 1.0 are not physically correct)*/
public float blurScale = 1.0f;
/**
* circle of confusion scale factor (amount of blur)
*
* <p>cocScale can be used to set the depth of field blur independently from the camera
* aperture, e.g. for artistic reasons. This can be achieved by setting:</p>
* <code>
* cocScale = cameraAperture / desiredDoFAperture
* </code>
*
*/
public float cocScale = 1.0f;
/** maximum aperture diameter in meters (zero to disable bokeh rotation) */
public float maxApertureDiameter = 0.01f;
/** 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;
};
/**
@@ -483,6 +723,92 @@ public class View {
TEMPORAL
}
/**
* List of available shadow mapping techniques.
*
* @see #setShadowType
*/
public enum ShadowType {
/**
* Percentage-closer filtered shadows (default).
*/
PCF,
/**
* Variance shadows.
*/
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>
*
*/
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;
}
/**
* Used to select buffers.
*/
@@ -707,8 +1033,31 @@ public class View {
* @see RenderableManager.Builder#receiveShadows
* @see RenderableManager.Builder#castShadows
*/
public void setShadowsEnabled(boolean enabled) {
nSetShadowsEnabled(getNativeObject(), enabled);
public void setShadowingEnabled(boolean enabled) {
nSetShadowingEnabled(getNativeObject(), enabled);
}
/**
* @return whether shadowing is enabled
*/
boolean isShadowingEnabled() {
return nIsShadowingEnabled(getNativeObject());
}
/**
* Enables or disables screen space refraction. Enabled by default.
*
* @param enabled true enables screen space refraction, false disables it.
*/
public void setScreenSpaceRefractionEnabled(boolean enabled) {
nSetScreenSpaceRefractionEnabled(getNativeObject(), enabled);
}
/**
* @return whether screen space refraction is enabled
*/
boolean isScreenSpaceRefractionEnabled() {
return nIsScreenSpaceRefractionEnabled(getNativeObject());
}
/**
@@ -753,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);
}
@@ -766,7 +1118,10 @@ public class View {
* </p>
*
* @return value set by {@link #setSampleCount}
*
* @deprecated use getMultiSampleAntiAliasingOptions instead
*/
@Deprecated
public int getSampleCount() {
return nGetSampleCount(getNativeObject());
}
@@ -792,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;
}
/**
@@ -881,7 +1260,7 @@ public class View {
*/
@NonNull
public Dithering getDithering() {
return Dithering.values()[nGetDithering(getNativeObject())];
return sDitheringValues[nGetDithering(getNativeObject())];
}
/**
@@ -906,6 +1285,7 @@ public class View {
options.homogeneousScaling,
options.minScale,
options.maxScale,
options.sharpness,
options.quality.ordinal());
}
@@ -957,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
@@ -1031,6 +1416,88 @@ public class View {
nSetDynamicLightingOptions(getNativeObject(), zLightNear, zLightFar);
}
/**
* Sets the shadow mapping technique this View uses.
*
* The ShadowType affects all the shadows seen within the View.
*
* <p>
* {@link ShadowType#VSM} imposes a restriction on marking renderables as only shadow receivers
* (but not casters). To ensure correct shadowing with VSM, all shadow participant renderables
* should be marked as both receivers and casters. Objects that are guaranteed to not cast
* shadows on themselves or other objects (such as flat ground planes) can be set to not cast
* shadows, which might improve shadow quality.
* </p>
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*/
public void setShadowType(ShadowType type) {
nSetShadowType(getNativeObject(), type.ordinal());
}
/**
* Sets VSM 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::VSM.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @param options Options for shadowing.
* @see #setShadowType
*/
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
mVsmShadowOptions = options;
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
options.minVarianceScale, options.lightBleedReduction);
}
/**
* Gets the VSM shadowing options.
* @see #setVsmShadowOptions
* @return VSM shadow options currently set.
*/
@NonNull
public VsmShadowOptions getVsmShadowOptions() {
if (mVsmShadowOptions == null) {
mVsmShadowOptions = new VsmShadowOptions();
}
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
@@ -1049,7 +1516,7 @@ public class View {
@Deprecated
@NonNull
public AmbientOcclusion getAmbientOcclusion() {
return AmbientOcclusion.values()[nGetAmbientOcclusion(getNativeObject())];
return sAmbientOcclusionValues[nGetAmbientOcclusion(getNativeObject())];
}
/**
@@ -1060,8 +1527,14 @@ 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.upsampling.ordinal(),
options.enabled);
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);
}
/**
@@ -1088,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);
}
/**
@@ -1173,7 +1649,10 @@ public class View {
*/
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
mDepthOfFieldOptions = options;
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.blurScale, 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);
}
/**
@@ -1190,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) {
@@ -1207,7 +1751,7 @@ public class View {
private static native void nSetCamera(long nativeView, long nativeCamera);
private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height);
private static native void nSetVisibleLayers(long nativeView, int select, int value);
private static native void nSetShadowsEnabled(long nativeView, boolean enabled);
private static native void nSetShadowingEnabled(long nativeView, boolean enabled);
private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget);
private static native void nSetSampleCount(long nativeView, int count);
private static native int nGetSampleCount(long nativeView);
@@ -1215,9 +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, 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);
@@ -1225,11 +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 upsampling, boolean enabled);
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 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,
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 blurScale, 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;
@@ -30,8 +30,8 @@ import android.view.TextureView;
import com.google.android.filament.SwapChain;
/**
* UiHelper is a simple class that can manage either a SurfaceView or a TextureView so it can
* be used to render into with Filament.
* UiHelper is a simple class that can manage either a SurfaceView, TextureView, or a SurfaceHolder
* so it can be used to render into with Filament.
*
* Here is a simple example with a SurfaceView. The code would be exactly the same with a
* TextureView:
@@ -191,6 +191,23 @@ public class UiHelper {
}
}
private static class SurfaceHolderHandler implements RenderSurface {
private SurfaceHolder mSurfaceHolder;
SurfaceHolderHandler(SurfaceHolder surface) {
mSurfaceHolder = surface;
}
@Override
public void resize(int width, int height) {
mSurfaceHolder.setFixedSize(width, height);
}
@Override
public void detach() {
}
}
private class TextureViewHandler implements RenderSurface {
private TextureView mTextureView;
private Surface mSurface;
@@ -258,8 +275,8 @@ public class UiHelper {
}
/**
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)},
* {@link #attachTo(TextureView)}, or {@link #attachTo(SurfaceHolder)}.
*/
public void detach() {
destroySwapChain();
@@ -315,8 +332,8 @@ public class UiHelper {
* Controls whether the render target (SurfaceView or TextureView) is opaque or not.
* The render target is considered opaque by default.
*
* Must be called before calling {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
* Must be called before calling {@link #attachTo(SurfaceView)}, {@link #attachTo(TextureView)},
* or {@link #attachTo(SurfaceHolder)}.
*
* @param opaque Indicates whether the render target should be opaque. True by default.
*/
@@ -341,6 +358,8 @@ public class UiHelper {
* Must be called before calling {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
*
* Has no effect when using {@link #attachTo(SurfaceHolder)}.
*
* @param overlay Indicates whether the render target should be rendered below the activity's
* surface when transparent.
*/
@@ -403,7 +422,9 @@ public class UiHelper {
SurfaceHolder holder = view.getHolder();
holder.addCallback(callback);
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
}
// in case the SurfaceView's surface already existed
final Surface surface = holder.getSurface();
@@ -483,6 +504,55 @@ public class UiHelper {
}
}
/**
* Associate UiHelper with a SurfaceHolder.
*
* As soon as a Surface is created, we'll create the
* EGL resources needed, and call user callbacks if needed.
*/
public void attachTo(@NonNull SurfaceHolder holder) {
if (attach(holder)) {
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
holder.setFormat(format);
mRenderSurface = new SurfaceHolderHandler(holder);
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
createSwapChain(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Note: this is always called at least once after surfaceCreated()
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
mRenderCallback.onResized(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
destroySwapChain();
}
};
holder.addCallback(callback);
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
}
// in case the SurfaceHolder's surface already existed
final Surface surface = holder.getSurface();
if (surface != null && surface.isValid()) {
callback.surfaceCreated(holder);
callback.surfaceChanged(holder, format,
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
}
}
}
private boolean attach(@NonNull Object nativeWindow) {
if (mNativeWindow != null) {
// we are already attached to a native window
+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 -6
View File
@@ -1,5 +1,4 @@
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
flavorDimensions "functionality"
@@ -10,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")
}
}
}
}
@@ -44,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,20 +74,28 @@ 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
private var surfaceView: SurfaceView? = null
private var textureView: TextureView? = null
private val renderer: Renderer
private var fetchResourcesJob: Job? = null
private var swapChain: SwapChain? = null
private var assetLoader: AssetLoader
private var resourceLoader: ResourceLoader
@@ -98,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.
@@ -122,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)
@@ -137,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)
@@ -169,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
@@ -190,7 +215,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
fun loadModelGltfAsync(buffer: Buffer, callback: (String) -> Buffer) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
CoroutineScope(Dispatchers.IO).launch {
fetchResourcesJob = CoroutineScope(Dispatchers.IO).launch {
fetchResources(asset!!, callback)
}
}
@@ -203,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
@@ -213,10 +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)
@@ -257,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)
@@ -279,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)
@@ -318,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) }
@@ -337,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 -3
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)
@@ -29,7 +30,6 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
${GLTFIO_DIR}/include/gltfio/SimpleViewer.h
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
@@ -45,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
@@ -57,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
@@ -70,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;
};
@@ -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) {
@@ -99,3 +107,10 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncUpdateLoad(JNIEnv*,
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncUpdateLoad();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncCancelLoad();
}
@@ -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())
@@ -78,34 +78,36 @@ import java.nio.Buffer;
public class AssetLoader {
private long mNativeObject;
private Engine mEngine;
private MaterialProvider mMaterialCache;
/**
* Constructs an <code>AssetLoader </code>that can be used to create and destroy instances of
* Constructs an <code>AssetLoader</code> that can be used to create and destroy instances of
* {@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 = provider;
}
/**
* Frees all memory consumed by the native <code>AssetLoader</code> and its material cache.
*/
public void destroy() {
mMaterialCache.destroyMaterials();
nDestroyAssetLoader(mNativeObject);
mNativeObject = 0;
}
@@ -146,10 +148,37 @@ 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;
}
/**
* Adds a new instance to an instanced asset.
*
* Use this with caution. It is more efficient to pre-allocate a max number of instances, and
* gradually add them to the scene as needed. Instances can also be "recycled" by removing and
* re-adding them to the scene.
*
* NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
* entity lists and instance lists, which would be slow to shift. We also wish to discourage
* create/destroy churn, as noted above.
*
* This cannot be called after FilamentAsset#releaseSourceData().
* This cannot be called on a non-instanced asset.
* Animation is not supported in new instances.
* See also AssetLoader#createInstancedAsset().
*/
@Nullable
@SuppressWarnings("unused")
public FilamentInstance createInstance(@NonNull FilamentAsset asset) {
long nativeInstance = nCreateInstance(mNativeObject, asset.getNativeObject());
if (nativeInstance == 0) {
return null;
}
return new FilamentInstance(asset, nativeInstance);
}
/**
@@ -168,13 +197,14 @@ 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);
private static native long nCreateAssetFromJson(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateInstancedAsset(long nativeLoader, Buffer buffer, int remaining,
long[] nativeInstances);
private static native long nCreateInstance(long nativeLoader, long nativeAsset);
private static native void nEnableDiagnostics(long nativeLoader, boolean enable);
private static native void nDestroyAsset(long nativeLoader, long nativeAsset);
}
@@ -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.
*
@@ -197,7 +207,11 @@ public class FilamentAsset {
if (mAnimator != null) {
return mAnimator;
}
mAnimator = new Animator(nGetAnimator(getNativeObject()));
long nativeAnimator = nGetAnimator(getNativeObject());
if (nativeAnimator == 0) {
throw new IllegalStateException("Unable to create animator");
}
mAnimator = new Animator(nativeAnimator);
return mAnimator;
}
@@ -215,6 +229,7 @@ public class FilamentAsset {
*
* This should only be called after ResourceLoader#loadResources().
* If using Animator, this should be called after getAnimator().
* If this is an instanced asset, this prevents creation of new instances.
*/
public void releaseSourceData() {
nReleaseSourceData(mNativeObject);
@@ -247,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.
*/

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