Compare commits

..

490 Commits

Author SHA1 Message Date
Benjamin Doherty
6960b1148a Merge branch 'rc/1.12.1' into release 2021-08-23 12:39:38 -07:00
Benjamin Doherty
3cc23aac25 Update RELEASE_NOTES for 1.12.1 2021-08-23 10:45:59 -07:00
Benjamin Doherty
11dc8740f2 Fix stack-use-after-scope error 2021-08-20 15:40:06 -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
fe1c1736cd Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:30:11 -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 Agopian
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 Rideout
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 Guy
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 Pelykh
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
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
80485bf520 Update RELEASE_NOTES for 1.9.24 2021-05-07 21:38:43 -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
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 Rideout
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
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
2065 changed files with 100404 additions and 43426 deletions

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]

View File

@@ -96,6 +96,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 +121,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 }}

View File

@@ -4,29 +4,23 @@
To build Filament, you must first install the following tools:
- CMake 3.10 (or more recent)
- CMake 3.19 (or more recent)
- clang 7.0 (or more recent)
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
To build the Java based components of the project you can optionally install (recommended):
- OpenJDK 1.8 (or more recent)
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
Additional dependencies may be required for your operating system. Please refer to the appropriate
section below.
To build Filament for Android you must also install the following:
- Android Studio 4.1.0 or more recent
- Android Studio Arctic Fox or more recent
- Android SDK
- Android NDK "side-by-side" 22.0 or higher
- Android NDK "side-by-side" 22.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:
```
@@ -375,7 +349,7 @@ same version that our continuous builds use.
```
cd <your chosen parent folder for the emscripten SDK>
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.17.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

View File

@@ -1,7 +1,7 @@
# ==================================================================================================
# CMake
# ==================================================================================================
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.19)
# ==================================================================================================
# Project declaration
@@ -11,8 +11,6 @@ project(TNT)
# ==================================================================================================
# Options
# ==================================================================================================
option(FILAMENT_ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(FILAMENT_USE_SWIFTSHADER "Compile Filament against SwiftShader" OFF)
@@ -25,6 +23,10 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
)
@@ -37,8 +39,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."
)
# ==================================================================================================
@@ -125,27 +131,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})
@@ -285,6 +299,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
# ==================================================================================================
@@ -365,6 +385,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)
@@ -420,9 +446,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()
@@ -430,8 +456,9 @@ if (FILAMENT_SUPPORTS_METAL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
endif()
# Disable optimizations and enable debug info (preserves names in SPIR-V)
if (FILAMENT_DISABLE_MATOPT)
set(MATC_OPT_FLAGS -g)
set(MATC_OPT_FLAGS -gd)
endif()
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
@@ -639,14 +666,12 @@ if (WEBGL)
endif()
if (IS_HOST_PLATFORM)
add_subdirectory(${LIBRARIES}/bluegl)
if (FILAMENT_SUPPORTS_OPENGL)
add_subdirectory(${LIBRARIES}/bluegl)
endif()
add_subdirectory(${LIBRARIES}/filamentapp)
add_subdirectory(${LIBRARIES}/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)

View File

@@ -31,39 +31,28 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.9.24'
implementation 'com.google.android.filament:filament-android:1.12.1'
}
```
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.24'
pod 'Filament', '~> 1.12.1'
```
### Snapshots
@@ -97,25 +86,12 @@ steps:
![Helmet](docs/images/samples/example_helmet.jpg)
![Screen-space refraction](docs/images/samples/example_ssr.jpg)
### Applications
Here are a few screenshots of applications that use Filament in production:
#### Google Maps AR Navigation
![Google Maps AR Navigation](docs/images/samples/app_gmm_ar_nav.jpg)
#### Google Search 3D/AR Viewer on Android
![Google Search 3D/AR Viewer on Android](docs/images/samples/app_google_3d_viewer.jpg)
## Features
### APIs
- Native C++ API for Android, iOS, Linux, macOS and Windows
- Java/JNI API for Android, Linux, macOS and Windows
- Java/JNI API for Android
- JavaScript API
### Backends
@@ -131,6 +107,7 @@ Here are a few screenshots of applications that use Filament in production:
- Clustered forward renderer
- Cook-Torrance microfacet specular BRDF
- Lambertian diffuse BRDF
- Custom lighting/surface shading
- HDR/linear lighting
- Metallic workflow
- Clear coat
@@ -142,20 +119,26 @@ Here are a few screenshots of applications that use Filament in production:
- Physically-based camera (shutter speed, sensitivity and aperture)
- Physical light units
- Point lights, spot lights and directional light
- Specular anti-aliasing
- Spot and directional light shadows
- Cascaded shadows
- VSM or PCF shadows
- EVSM or PCF shadows
- Transparent shadows
- Contact shadows
- Screen-space ambient occlusion
- Screen-space refraction
- Global fog
- Dynamic resolution
### 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
- TAA, FXAA, MSAA
- Screen-space lens flares
### glTF 2.0
@@ -184,10 +167,12 @@ Here are a few screenshots of applications that use Filament in production:
- [x] KHR_draco_mesh_compression
- [x] KHR_lights_punctual
- [x] KHR_materials_clearcoat
- [x] KHR_materials_ior
- [x] KHR_materials_pbrSpecularGlossiness
- [x] KHR_materials_sheen
- [x] KHR_materials_transmission
- [x] KHR_materials_unlit
- [x] KHR_materials_volume
- [x] KHR_mesh_quantization
- [x] KHR_texture_transform
@@ -255,22 +240,11 @@ if (renderer->beginFrame(swapChain)) {
```
For complete examples of Linux, macOS and Windows Filament applications, look at the source files
in the `samples/` directory. These samples are all based on `samples/app/` which contains the code
that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
in the `samples/` directory. These samples are all based on `libs/filamentapp/` which contains the
code that creates a native window with SDL2 and initializes the Filament engine, renderer and views.
### Java on Linux, macOS and Windows
After building Filament, you can use `filament-java.jar` and its companion `filament-jni` native
library to use Filament in desktop Java applications.
You must always first initialize Filament by calling `Filament.init()`.
You can use Filament either with AWT or Swing, using respectively a `FilamentCanvas` or a
`FilamentPanel`.
Following the steps above (how to use Filament from native code), create an `Engine` and a
`Renderer`, but instead of calling `beginFrame` and `endFrame` on the renderer itself, call
these methods on `FilamentCanvas` or `FilamentPanel`.
For more information on how to prepare environment maps for image-based lighting please refer to
[BUILDING.md](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples).
### Android
@@ -301,6 +275,10 @@ To get started you can use the textures and environment maps found respectively
`third_party/textures` and `third_party/environments`. These assets are under CC0 license. Please
refer to their respective `URL.txt` files to know more about the original authors.
Environments must be pre-processed using
[`cmgen`](https://github.com/google/filament/blob/main/BUILDING.md#running-the-native-samples) or
using the `libiblprefilter` library.
## How to make contributions
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
@@ -323,9 +301,9 @@ and tools.
- `docs`: Documentation
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
- `filament`: Filament rendering engine (minimal dependencies)
- `backend`: Rendering backends/drivers (Vulkan, Metal, OpenGL/ES)
- `ide`: Configuration files for IDEs (CLion, etc.)
- `ios`: Sample projects for iOS
- `java`: Java bindings for Filament libraries
- `libs`: Libraries
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
@@ -345,6 +323,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

View File

@@ -3,7 +3,154 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## Next release (main branch)
## v1.12.2 (currently main branch)
## 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

View File

@@ -59,14 +59,13 @@ buildscript {
}
}
// Our minSdkVersion is 19.
ext.versions = [
'minSdk': 19,
'targetSdk': 30,
'compileSdk': 30,
'kotlin': '1.4.31',
'kotlin': '1.5.21',
'buildTools': '30.0.3',
'ndk': '22.0.7026061'
'ndk': '22.1.7171670'
]
ext.deps = [
@@ -78,7 +77,7 @@ buildscript {
]
dependencies {
classpath 'com.android.tools.build:gradle:4.1.3'
classpath 'com.android.tools.build:gradle:7.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -93,8 +92,7 @@ buildscript {
ext.cppFlags = [
"-std=c++17",
"-Wno-unused-command-line-argument",
// Required to support API levels below 23
"-Wl,--hash-style=both",
"-Wl,--hash-style=both", // Required to support API levels below 23
"-fno-stack-protector",
"-fno-exceptions",
"-fno-unwind-tables",
@@ -116,7 +114,6 @@ buildscript {
repositories {
mavenCentral()
google()
jcenter()
}
}
@@ -138,7 +135,6 @@ subprojects {
repositories {
mavenCentral()
google()
jcenter()
}
if (!name.startsWith("sample")) {
@@ -163,11 +159,13 @@ subprojects {
ndk {
abiFilters(*rootProject.ext.abis)
}
}
consumerProguardFiles '../proguard-rules.pro'
}
externalNativeBuild {
cmake {
version "3.19.0+"
path "CMakeLists.txt"
}
}

View File

@@ -19,8 +19,11 @@ 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
@@ -33,24 +36,23 @@ import java.nio.file.Paths
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
}
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()
}
binaryPath = OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]
binaryPath = project.objects.property(String.class)
binaryPath.set(
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
}
return binaryPath
}
@@ -65,14 +67,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 +79,10 @@ 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()
MaterialCompiler() {
super("matc")
@@ -115,8 +109,8 @@ 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.")
}
@@ -129,7 +123,7 @@ abstract class MaterialCompiler extends TaskWithBinary {
project.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
executable "${binary.get()}"
args matcArgs
}
}
@@ -143,15 +137,17 @@ 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()
IblGenerator() {
super("cmgen")
@@ -178,23 +174,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
def commandArgs = cmgenArgs.getOrNull()
if (commandArgs == null) {
commandArgs =
'-q -x ' + outputPath + ' --format=rgb32f ' +
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
}
commandArgs = commandArgs + " " + file
project.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 +205,13 @@ 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()
MeshCompiler() {
super("filamesh")
@@ -240,15 +238,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 {
standardOutput out
errorOutput err
executable "${getBinary()}"
executable "${binary.get()}"
args(file, getOutputFile(file))
}
}
@@ -291,8 +289,8 @@ class FilamentToolsPlugin implements Plugin<Project> {
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"

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)

View File

@@ -123,19 +123,22 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpo
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint precision, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
builder->parameter((MaterialBuilder::UniformType) uniformType,
(MaterialBuilder::ParameterPrecision) precision, name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint size, jint precision,
jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size,
(MaterialBuilder::ParameterPrecision) precision, name);
env->ReleaseStringUTFChars(name_, name);
}
@@ -146,7 +149,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision,
name);
env->ReleaseStringUTFChars(name_, name);
}
@@ -255,6 +258,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShadowM
builder->shadowMultiplier(shadowMultiplier);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTransparentShadow(
JNIEnv*, jclass, jlong nativeBuilder, jboolean transparentShadow) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->transparentShadow(transparentShadow);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecularAntiAliasing(
JNIEnv*, jclass, jlong nativeBuilder, jboolean specularAntiAliasing) {
@@ -291,6 +301,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(
builder->flipUV(flipUV);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCustomSurfaceShading(JNIEnv*,
jclass, jlong nativeBuilder, jboolean customSurfaceShading) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->customSurfaceShading(customSurfaceShading);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBounceAmbientOcclusion(
JNIEnv*, jclass, jlong nativeBuilder, jboolean multiBounceAO) {

View File

@@ -91,7 +91,7 @@ public class MaterialBuilder {
SHADOW
}
public enum SamplerPrecision {
public enum ParameterPrecision {
LOW,
MEDIUM,
HIGH,
@@ -247,19 +247,36 @@ public class MaterialBuilder {
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(),
ParameterPrecision.DEFAULT.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type,
ParameterPrecision precision, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), precision.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
ParameterPrecision.DEFAULT.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size,
ParameterPrecision precision, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size,
precision.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
SamplerPrecision precision, String name) {
ParameterPrecision precision, String name) {
nMaterialBuilderSamplerParameter(
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
return this;
@@ -349,6 +366,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder transparentShadow(boolean transparentShadow) {
nMaterialBuilderTransparentShadow(mNativeObject, transparentShadow);
return this;
}
@NonNull
public MaterialBuilder specularAntiAliasing(boolean specularAntiAliasing) {
nMaterialBuilderSpecularAntiAliasing(mNativeObject, specularAntiAliasing);
@@ -391,6 +414,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder customSurfaceShading(boolean customSurfaceShading) {
nMaterialBuilderCustomSurfaceShading(mNativeObject, customSurfaceShading);
return this;
}
@NonNull
public MaterialBuilder multiBounceAmbientOcclusion(boolean multiBounceAO) {
nMaterialBuilderMultiBounceAmbientOcclusion(mNativeObject, multiBounceAO);
@@ -523,9 +552,9 @@ public class MaterialBuilder {
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
String name);
int precision, String name);
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
int size, String name);
int size, int precision, String name);
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
int format, int precision, String name);
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,
@@ -545,6 +574,8 @@ public class MaterialBuilder {
private static native void nMaterialBuilderShadowMultiplier(long mNativeObject,
boolean shadowMultiplier);
private static native void nMaterialBuilderTransparentShadow(long mNativeObject,
boolean transparentShadow);
private static native void nMaterialBuilderSpecularAntiAliasing(long mNativeObject,
boolean specularAntiAliasing);
private static native void nMaterialBuilderSpecularAntiAliasingVariance(long mNativeObject,
@@ -556,6 +587,8 @@ public class MaterialBuilder {
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
private static native void nMaterialBuilderCustomSurfaceShading(long nativeBuilder,
boolean customSurfaceShading);
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
boolean multiBounceAO);
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,

View File

@@ -1,4 +1,5 @@
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)
@@ -26,6 +27,10 @@ add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
add_library(filamat STATIC IMPORTED)
set_target_properties(filamat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilamat.a)
add_library(geometry STATIC IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
@@ -74,11 +79,13 @@ add_library(filament-jni SHARED
src/main/cpp/RenderTarget.cpp
src/main/cpp/Scene.cpp
src/main/cpp/SkyBox.cpp
src/main/cpp/SkinningBuffer.cpp
src/main/cpp/Stream.cpp
src/main/cpp/SurfaceOrientation.cpp
src/main/cpp/SwapChain.cpp
src/main/cpp/Texture.cpp
src/main/cpp/TextureSampler.cpp
src/main/cpp/ToneMapper.cpp
src/main/cpp/TransformManager.cpp
src/main/cpp/VertexBuffer.cpp
src/main/cpp/View.cpp
@@ -109,6 +116,7 @@ target_link_libraries(filament-jni
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>

View File

@@ -13,7 +13,9 @@ LIBFILAMENT {
*filament*IndirectLight*;
*filament*LightManager*;
*filament*Renderer*;
*filament*RenderTarget*;
*filament*Scene*;
*filament*ToneMapper*;
*filament*Transform*;
*filament*Material*;
*filament*IndexBuffer*;

View File

@@ -18,6 +18,8 @@
#include <filament/Camera.h>
#include <utils/Entity.h>
#include <math/mat4.h>
using namespace filament;
@@ -100,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_) {
@@ -139,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_) {

View File

@@ -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,21 @@ 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_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_nBuilderWhiteBalance(JNIEnv*, jclass,

View File

@@ -16,6 +16,7 @@
#include <jni.h>
#include <filament/Camera.h>
#include <filament/Engine.h>
#include <utils/Entity.h>
@@ -120,15 +121,8 @@ Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
// 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 +137,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

View File

@@ -77,7 +77,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance, jint vsmMsaaSamples) {
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
LightManager::ShadowOptions shadowOptions {
.mapSize = (uint32_t)mapSize,
@@ -92,7 +92,8 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
.stepCount = uint8_t(stepCount),
.maxShadowDistance = maxShadowDistance,
.vsm = {
.msaaSamples = (uint8_t) vsmMsaaSamples
.msaaSamples = (uint8_t) vsmMsaaSamples,
.blurWidth = blurWidth
}
};
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
@@ -188,6 +189,23 @@ Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclas
builder->sunHaloFalloff(haloFalloff);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderLightChannel(JNIEnv*, jclass,
jlong nativeBuilder, jint channel, jboolean enable) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->lightChannel(channel, (bool)enable);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine, jint entity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
}
// ------------------------------------------------------------------------------------------------
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nComputeUniformSplits(JNIEnv* env, jclass,
jfloatArray splitPositions, jint cascades) {
@@ -212,13 +230,7 @@ Java_com_google_android_filament_LightManager_nComputePracticalSplits(JNIEnv* en
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine, jint entity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
}
// ------------------------------------------------------------------------------------------------
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_LightManager_nGetType(JNIEnv* env,
@@ -379,3 +391,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);
}

View File

@@ -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;
}

View File

@@ -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,
@@ -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);
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -129,6 +129,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) {

View File

@@ -0,0 +1,109 @@
/*
* 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 shoulder, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
return (jlong) new GenericToneMapper(contrast, shoulder, 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_nGenericGetShoulder(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getShoulder();
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) {
return ((GenericToneMapper*) nativeObject)->getMidGrayIn();
}
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_nGenericSetShoulder(JNIEnv*, jclass,
jlong nativeObject, jfloat shoulder) {
((GenericToneMapper*) nativeObject)->setShoulder(shoulder);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass,
jlong nativeObject, jfloat midGrayIn) {
((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);
}

View File

@@ -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_) {
@@ -104,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,
@@ -115,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,
@@ -126,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) {
@@ -139,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();
}

View File

@@ -130,43 +130,3 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv *env, jc
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
vertexBuffer->setBufferObjectAt(*engine, (uint8_t) bufferIndex, bufferObject);
}
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
});
}

View File

@@ -138,10 +138,15 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
jint anisotropy) {
jint anisotropy, jboolean mipmapping, jfloat exponent, jfloat minVarianceScale,
jfloat lightBleedReduction) {
View* view = (View*) nativeView;
View::VsmShadowOptions options;
options.anisotropy = (uint8_t) anisotropy;
options.anisotropy = (uint8_t)anisotropy;
options.mipmapping = (bool)mipmapping;
options.exponent = exponent;
options.minVarianceScale = minVarianceScale;
options.lightBleedReduction = lightBleedReduction;
view->setVsmShadowOptions(options);
}
@@ -211,7 +216,9 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
jfloat bilateralThreshold,
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jboolean bentNormals,
jfloat minHorizonAngleRad) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.radius = radius;
@@ -219,10 +226,12 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
options.bias = bias;
options.resolution = resolution;
options.intensity = intensity;
options.bilateralThreshold = bilateralThreshold;
options.quality = (View::QualityLevel)quality;
options.lowPassFilter = (View::QualityLevel)lowPassFilter;
options.upsampling = (View::QualityLevel)upsampling;
options.enabled = (bool)enabled;
options.bentNormals = (bool)bentNormals;
options.minHorizonAngleRad = minHorizonAngleRad;
view->setAmbientOcclusionOptions(options);
}
@@ -253,7 +262,10 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
jlong nativeView, jlong nativeTexture,
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight) {
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight,
jboolean lensFlare, jboolean starburst, jfloat chromaticAberration, jint ghostCount,
jfloat ghostSpacing, jfloat ghostThreshold, jfloat haloThickness, jfloat haloRadius,
jfloat haloThreshold) {
View* view = (View*) nativeView;
Texture* dirt = (Texture*) nativeTexture;
View::BloomOptions options = {
@@ -266,7 +278,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);
}
@@ -309,7 +330,7 @@ Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass ,
// View::DepthOfFieldOptions::Filter::MEDIAN value is actually 2
eFilter = View::DepthOfFieldOptions::Filter::MEDIAN;
}
view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale,
view->setDepthOfFieldOptions({.cocScale = cocScale,
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter,
.nativeResolution = (bool)nativeResolution,
.foregroundRingCount = (uint8_t)foregroundRingCount,

View File

@@ -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

View File

@@ -1,116 +0,0 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "JAWTUtils.h"
#include <vector>
static std::vector<int> jawtVersions = {
0x00010003,
0x00010004,
0x00010007,
0x00010009,
};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wuninitialized"
bool acquireDrawingSurface(JNIEnv* env, jobject surface,
JAWT_DrawingSurface** ods, JAWT_DrawingSurfaceInfo** odsi) {
JAWT awt;
JAWT_DrawingSurface* ds = nullptr;
JAWT_DrawingSurfaceInfo* dsi = nullptr;
// Search for a valid AWT
jboolean foundJawt = JNI_FALSE;
for (int jawtVersion : jawtVersions) {
awt.version = jawtVersion;
#if defined(__APPLE__) && defined(__aarch64__)
// FIXME: enable Apple Silicon build. The problem here is that we attempt to link an x86 jdk and that fails
// so JAWT_GetAWT doesn't exist at link time.
#warning "FIXME: JAWT_GetAWT() not supported"
foundJawt = {};
#else
foundJawt = JAWT_GetAWT(env, &awt);
#endif
if (foundJawt == JNI_TRUE) {
#ifndef NDEBUG
printf("Found valid AWT v%08x.\n", jawtVersion);
#endif
break;
} else {
#ifndef NDEBUG
printf("AWT v%08x not present.\n", jawtVersion);
#endif
}
}
#ifndef NDEBUG
fflush(stdout);
#endif
if (foundJawt == JNI_FALSE) {
printf("AWT Not found\n");
fflush(stdout);
return false;
}
// Get the drawing surface
ds = awt.GetDrawingSurface(env, surface);
if (ds == nullptr) {
#ifndef NDEBUG
printf("NULL drawing surface\n");
fflush(stdout);
#endif
return false;
}
// Lock the drawing
jint lock = ds->Lock(ds);
if ((lock & JAWT_LOCK_ERROR) != 0) {
#ifndef NDEBUG
printf("Error locking surface\n");
fflush(stdout);
#endif
awt.FreeDrawingSurface(ds);
return false;
}
// Get the drawing surface info
dsi = ds->GetDrawingSurfaceInfo(ds);
if (dsi == nullptr) {
#ifndef NDEBUG
printf("Error getting surface info\n");
fflush(stdout);
#endif
ds->Unlock(ds);
awt.FreeDrawingSurface(ds);
return false;
}
*odsi = dsi;
*ods = ds;
return true;
}
#pragma clang diagnostic pop
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi) {
// Free the drawing surface info
ds->FreeDrawingSurfaceInfo(dsi);
// Unlock the drawing surface
ds->Unlock(ds);
}

View File

@@ -1,23 +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 <jawt.h>
extern "C" {
bool acquireDrawingSurface(JNIEnv* env, jobject surface, JAWT_DrawingSurface** ods,
JAWT_DrawingSurfaceInfo** odsi);
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi);
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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];

View File

@@ -29,7 +29,7 @@ import androidx.annotation.Size;
*
* 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#destroyCamera(Camera)}.
* {@link Engine#destroyCameraComponent(int Entity)} ()}.
*
* <pre>
* Camera myCamera = engine.createCamera(myCameraEntity);
@@ -37,7 +37,7 @@ import androidx.annotation.Size;
* myCamera.lookAt(0, 1.60, 1,
* 0, 0, 0,
* 0, 1, 0);
* engine.destroyCamera(myCamera);
* engine.destroyCameraComponent(myCameraEntity);
* </pre>
*
*
@@ -121,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
@@ -143,8 +146,9 @@ public class Camera {
HORIZONTAL
}
Camera(long nativeCamera) {
Camera(long nativeCamera, @Entity int entity) {
mNativeObject = nativeCamera;
mEntity = entity;
}
/**
@@ -250,6 +254,9 @@ public class Camera {
/**
* Sets a 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.
@@ -275,6 +282,9 @@ public class Camera {
/**
* 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.
@@ -409,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.
*
@@ -506,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.
*
@@ -521,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.
*
@@ -681,6 +736,15 @@ public class Camera {
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
*
@@ -721,6 +785,7 @@ public class Camera {
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);
@@ -728,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);

View File

@@ -54,6 +54,7 @@ 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>White balance</li>
* <li>Channel mixer</li>
* <li>Shadows/mid-tones/highlights</li>
@@ -63,12 +64,14 @@ import static com.google.android.filament.Asserts.assertFloat4In;
* <li>Saturation</li>
* <li>Curves</li>
* <li>Tone mapping</li>
* <li>Luminance scaling</li>
* </ul>
*
* <h1>Defaults</h1>
*
* Here are the default color grading options:
* <ul>
* <li>Exposure: 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 +81,12 @@ 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>
* </ul>
*
* @see View
* @see ToneMapping
* @see ToneMapper
*/
public class ColorGrading {
long mNativeObject;
@@ -99,6 +103,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,10 +115,6 @@ public class ColorGrading {
ACES,
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
FILMIC,
/** Exposure value invariant luminance scaling tone mapping, offers the best behaviors in high intensity areas. */
EVILS,
/** Reinhard luma-based tone mapping. */
REINHARD,
/** Tone mapping used to validate/debug scene exposure. */
DISPLAY_RANGE,
}
@@ -156,6 +158,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.
@@ -165,12 +186,49 @@ 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;
}
/**
* 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;
}
/**
* 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
@@ -463,7 +521,10 @@ 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 nBuilderExposure(long nativeBuilder, float exposure);
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);

View File

@@ -399,19 +399,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>.
*
@@ -421,9 +408,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);
}
/**
@@ -437,16 +424,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
@@ -634,6 +621,14 @@ 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
@@ -685,10 +680,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);

View File

@@ -84,11 +84,7 @@ import androidx.annotation.Size;
public class IndirectLight {
long mNativeObject;
public IndirectLight(Engine engine, long indirectLight) {
mNativeObject = indirectLight;
}
IndirectLight(long indirectLight) {
public IndirectLight(long indirectLight) {
mNativeObject = indirectLight;
}

View File

@@ -188,7 +188,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 +242,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;
/** 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;
/** 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.
@@ -324,6 +326,12 @@ public class LightManager {
*/
@IntRange(from = 1)
public int vsmMsaaSamples = 1;
/**
* Blur width for the VSM blur. Zero do disable.
* The maximum value is 125.
*/
public float blurWidth = 0.0f;
}
public static class ShadowCascades {
@@ -422,6 +430,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)
*
@@ -452,7 +472,8 @@ public class LightManager {
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
options.shadowFarHint, options.stable, options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples);
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
options.blurWidth);
return this;
}
@@ -776,6 +797,30 @@ public class LightManager {
return type == Type.SPOT || type == Type.FOCUSED_SPOT;
}
/**
* Enables or disables a light channel.
* Light channel 0 is enabled by default.
*
* @param i Instance of the component obtained from getInstance().
* @param channel Light channel to set
* @param enable true to enable, false to disable
*
* @see Builder#lightChannel
*/
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
nSetLightChannel(mNativeObject, i, channel, enable);
}
/**
* Returns whether a light channel is enabled on a specified renderable.
* @param i Instance of the component obtained from getInstance().
* @param channel Light channel to query
* @return true if the light channel is enabled, false otherwise
*/
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
return nGetLightChannel(mNativeObject, i, channel);
}
/**
* Dynamically updates the light's position.
*
@@ -1065,6 +1110,14 @@ public class LightManager {
return nIsShadowCaster(mNativeObject, i);
}
public float getOuterConeAngle(@EntityInstance int i) {
return nGetOuterConeAngle(mNativeObject, i);
}
public float getInnerConeAngle(@EntityInstance int i) {
return nGetInnerConeAngle(mNativeObject, i);
}
public long getNativeObject() {
return mNativeObject;
}
@@ -1078,7 +1131,7 @@ public class LightManager {
private static native void nDestroyBuilder(long nativeBuilder);
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth);
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
@@ -1091,6 +1144,7 @@ public class LightManager {
private static native void nBuilderAngularRadius(long nativeBuilder, float angularRadius);
private static native void nBuilderHaloSize(long nativeBuilder, float haloSize);
private static native void nBuilderHaloFalloff(long nativeBuilder, float haloFalloff);
private static native void nBuilderLightChannel(long nativeBuilder, int channel, boolean enable);
private static native void nComputeUniformSplits(float[] splitPositions, int cascades);
private static native void nComputeLogSplits(float[] splitPositions, int cascades, float near, float far);
@@ -1118,4 +1172,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);
}

View File

@@ -279,7 +279,7 @@ public class Material {
}
}
Material(long nativeMaterial) {
public Material(long nativeMaterial) {
mNativeObject = nativeMaterial;
long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial);
mDefaultInstance = new MaterialInstance(this, nativeDefaultInstance);

View File

@@ -64,6 +64,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.mMaterial, nativeInstance);
}
/** @return the {@link Material} associated with this instance */
@NonNull
public Material getMaterial() {
@@ -539,4 +555,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);
}

View File

@@ -32,7 +32,7 @@ import androidx.annotation.Nullable;
*/
public class RenderTarget {
private long mNativeObject;
private static final int ATTACHMENT_COUNT = 5;
private static final int ATTACHMENT_COUNT = AttachmentPoint.values().length;
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
private RenderTarget(long nativeRenderTarget, Builder builder) {
@@ -55,6 +55,10 @@ public class RenderTarget {
COLOR1,
COLOR2,
COLOR3,
COLOR4,
COLOR5,
COLOR6,
COLOR7,
DEPTH
}

View File

@@ -113,7 +113,7 @@ public class RenderableManager {
* @param count the number of primitives that will be supplied to the builder
*
* Note that builders typically do not have a long lifetime since clients should discard
* them after calling build(). For a usage example, see {@link RenderableManager}.
* them after calling {@link #build}. For a usage example, see {@link RenderableManager}.
*/
public Builder(@IntRange(from = 1) int count) {
mNativeBuilder = nCreateBuilder(count);
@@ -128,7 +128,7 @@ public class RenderableManager {
* <code>geometry()</code> and <code>material()</code>.
*
* @param index zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param type specifies the topology of the primitive (e.g., PrimitiveType.TRIANGLES)
* @param type specifies the topology of the primitive (e.g., {@link PrimitiveType#TRIANGLES})
* @param vertices specifies the vertex buffer, which in turn specifies a set of attributes
* @param indices specifies the index buffer (either u16 or u32)
* @param offset specifies where in the index buffer to start reading (expressed as a number of indices)
@@ -147,7 +147,7 @@ public class RenderableManager {
}
/**
* For details, see the {@link RenderableManager.Builder#geometry primary overload}.
* For details, see the {@link RenderableManager.Builder#geometry} primary overload.
*/
@NonNull
public Builder geometry(@IntRange(from = 0) int index, @NonNull PrimitiveType type,
@@ -159,7 +159,7 @@ public class RenderableManager {
}
/**
* For details, see the {@link RenderableManager.Builder#geometry primary overload}.
* For details, see the {@link RenderableManager.Builder#geometry} primary overload.
*/
@NonNull
public Builder geometry(@IntRange(from = 0) int index, @NonNull PrimitiveType type,
@@ -266,6 +266,18 @@ public class RenderableManager {
return this;
}
/**
* 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;
}
/**
* Controls if this renderable casts shadows, false by default.
*
@@ -303,6 +315,50 @@ public class RenderableManager {
return this;
}
/**
* Allows bones to be swapped out and shared using SkinningBuffer.
*
* If skinning buffer mode is enabled, clients must call #setSkinningBuffer() rather than
* #setBonesAsQuaternions(). This allows sharing of data between renderables.
*
* @param enabled If true, enables buffer object mode. False by default.
*/
@NonNull
public Builder enableSkinningBuffers(boolean enabled) {
nEnableSkinningBuffers(mNativeBuilder, enabled);
return this;
}
/**
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
*
*<p>Skinning Buffer mode must be enabled.</p>
*
*<p>Each vertex can be affected by up to 4 bones simultaneously. The attached
* VertexBuffer must provide data in the BONE_INDICES slot (uvec4) and the
* BONE_WEIGHTS slot (float4).</p>
*
*<p>See also {@link #setSkinningBuffer}, {@link SkinningBuffer#setBonesAsMatrices}
* or {@link SkinningBuffer#setBonesAsQuaternions},
* which can be called on a per-frame basis to advance the animation.</p>
*
* @see #setSkinningBuffer
* @see SkinningBuffer#setBonesAsMatrices
* @see SkinningBuffer#setBonesAsQuaternions
*
* @param skinningBuffer null to disable, otherwise the {@link SkinningBuffer} to use
* @param boneCount 0 to disable, otherwise the number of bone transforms (up to 255)
* @param offset offset in the {@link SkinningBuffer}
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder skinning(SkinningBuffer skinningBuffer,
@IntRange(from = 0, to = 255) int boneCount, int offset) {
nBuilderSkinningBuffer(mNativeBuilder,
skinningBuffer != null ? skinningBuffer.getNativeObject() : 0, boneCount, offset);
return this;
}
@NonNull
public Builder skinning(@IntRange(from = 0, to = 255) int boneCount) {
nBuilderSkinning(mNativeBuilder, boneCount);
@@ -312,6 +368,8 @@ public class RenderableManager {
/**
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
*
* <p>Skinning Buffer mode must be disabled.</p>
*
* <p>Each vertex can be affected by up to 4 bones simultaneously. The attached
* VertexBuffer must provide data in the <code>BONE_INDICES</code> slot (uvec4) and the
* <code>BONE_WEIGHTS</code> slot (float4).</p>
@@ -319,6 +377,8 @@ public class RenderableManager {
* <p>See also {@link RenderableManager#setBonesAsMatrices}, which can be called on a per-frame basis
* to advance the animation.</p>
*
* @see SkinningBuffer#setBonesAsMatrices
*
* @param boneCount Number of bones associated with this component
* @param bones A FloatBuffer containing boneCount transforms. Each transform consists of 8 float.
* float 0 to 3 encode a unit quaternion w+ix+jy+kz stored as x,y,z,w.
@@ -379,9 +439,22 @@ public class RenderableManager {
}
}
/**
* Associates a {@link SkinningBuffer} to a renderable instance
* @param i Instance of the Renderable
* @param skinningBuffer {@link SkinningBuffer} to use
* @param count Numbers of bones to set
* @param offset Offset in the {@link SkinningBuffer}
*/
public void setSkinningBuffer(@EntityInstance int i, @NonNull SkinningBuffer skinningBuffer,
int count, int offset) {
nSetSkinningBuffer(mNativeObject, i, skinningBuffer.getNativeObject(), count, offset);
}
/**
* Sets the transforms associated with each bone of a Renderable.
*
*
* @param i Instance of the Renderable
* @param matrices A FloatBuffer containing boneCount 4x4 packed matrices (i.e. 16 floats each matrix and no gap between matrices)
* @param boneCount Number of bones to set
@@ -470,6 +543,30 @@ public class RenderableManager {
nSetCulling(mNativeObject, i, enabled);
}
/**
* 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);
}
/**
* Changes whether or not the renderable casts shadows.
*
@@ -654,8 +751,12 @@ public class RenderableManager {
private static native void nBuilderScreenSpaceContactShadows(long nativeBuilder, boolean enabled);
private static native void nBuilderSkinning(long nativeBuilder, int boneCount);
private static native int nBuilderSkinningBones(long nativeBuilder, int boneCount, Buffer bones, int remaining);
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
private static native void nBuilderMorphing(long nativeBuilder, boolean enabled);
private static native void nEnableSkinningBuffers(long nativeBuilder, boolean enabled);
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
private static native void nSetSkinningBuffer(long nativeObject, int i, long nativeSkinningBuffer, int count, int offset);
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights);
@@ -663,6 +764,8 @@ public class RenderableManager {
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
@@ -672,7 +775,6 @@ public class RenderableManager {
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native long nGetMaterialAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, int offset, int count);
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);

View File

@@ -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);
}

View File

@@ -51,11 +51,7 @@ import static com.google.android.filament.Colors.LinearColor;
public class Skybox {
private long mNativeObject;
public Skybox(Engine engine, long nativeSkybox) {
mNativeObject = nativeSkybox;
}
Skybox(long nativeSkybox) {
public Skybox(long nativeSkybox) {
mNativeObject = nativeSkybox;
}

View File

@@ -166,7 +166,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);

View File

@@ -73,11 +73,7 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
public class Texture {
private long mNativeObject;
Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
public Texture(Engine engine, long nativeTexture) {
public Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
@@ -695,6 +691,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.
@@ -1167,6 +1183,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);

View File

@@ -0,0 +1,226 @@
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>
* <li>shoulder: controls the shoulder of the curve, i.e. how quickly scene
* referred values map to output white</li>
* <li>midGrayIn: sets the input middle gray</li>
* <li>midGrayOut: sets the output middle gray</li>
* <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.585f</li>
* <li>shoulder = 0.5f</li>
* <li>midGrayIn = 0.18f</li>
* <li>midGrayOut = 0.268f</li>
* <li>hdrMax = 10.0f</li>
* </ul>
*/
public Generic() {
this(1.585f, 0.5f, 0.18f, 0.268f, 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 shoulder: controls the shoulder of the curve, i.e. how quickly scene
* referred values map to output white, between 0.0 and 1.0.
* @param midGrayIn: sets the input middle gray, between 0.0 and 1.0.
* @param midGrayOut: sets the output middle gray, between 0.0 and 1.0.
* @param hdrMax: defines the maximum input value that will be mapped to
* output white. Must be >= 1.0.
*/
public Generic(
float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax) {
super(nCreateGenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax));
}
/** 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 how fast scene referred values map to output white as a value between 0.0 and 1.0. */
public float getShoulder() {
return nGenericGetShoulder(getNativeObject());
}
/** Sets how quickly scene referred values map to output white, between 0.0 and 1.0. */
public void setShoulder(float shoulder) {
nGenericSetShoulder(getNativeObject(), shoulder);
}
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
public float getMidGrayIn() {
return nGenericGetMidGrayIn(getNativeObject());
}
/** 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 shoulder, float midGrayIn, float midGrayOut, float hdrMax);
// Generic tone mappper
private static native float nGenericGetContrast(long nativeObject);
private static native float nGenericGetShoulder(long nativeObject);
private static native float nGenericGetMidGrayIn(long nativeObject);
private static native float nGenericGetMidGrayOut(long nativeObject);
private static native float nGenericGetHdrMax(long nativeObject);
private static native void nGenericSetContrast(long nativeObject, float contrast);
private static native void nGenericSetShoulder(long nativeObject, float shoulder);
private static native void nGenericSetMidGrayIn(long nativeObject, float midGrayIn);
private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut);
private static native void nGenericSetHdrMax(long nativeObject, float hdrMax);
}

View File

@@ -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.
*
@@ -170,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.
*
@@ -190,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.
*
@@ -210,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.
@@ -252,12 +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);
}

View File

@@ -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
@@ -429,38 +387,6 @@ public class VertexBuffer {
bufferObject.getNativeObject());
}
/**
* Convenience function that consumes normal vectors (and, optionally, tangent vectors) and
* produces quaternions that can be passed into a TANGENTS buffer.
*
* <p>
* The given output buffer must be preallocated with at least quatCount * outStride bytes.
* <p>
*
* <p>
* Normals are required but tangents are optional, in which case this function tries to generate
* reasonable tangents. The given normals should be unit length.
* </p>
*
* <p>
* If supplied, the tangent vectors should be unit length and should be orthogonal to the
* normals. The w component of the tangent is a sign (-1 or +1) indicating handedness of the
* basis.
* </p>
*
* @deprecated Instead please use SurfaceOrientation since it has additional capabilities and a
* builder-style API.
*
* @param context an initialized QuatTangentContext object
*/
public static void populateTangentQuaternions(@NonNull QuatTangentContext context) {
nPopulateTangentQuaternions(context.quatType.ordinal(), context.quatCount,
context.outBuffer, context.outBuffer.remaining(), context.outStride,
context.normals, context.normals.remaining(), context.normalsStride,
context.tangents, context.tangents != null ? context.tangents.remaining() : 0,
context.tangentsStride);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed VertexBuffer");
@@ -490,8 +416,4 @@ public class VertexBuffer {
private static native void nSetBufferObjectAt(long nativeVertexBuffer, long nativeEngine,
int bufferIndex, long nativeBufferObject);
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);
}

View File

@@ -169,6 +169,16 @@ public class View {
*/
public float intensity = 1.0f;
/**
* Depth distance that constitute an edge for filtering. Must be positive.
* Default is 5cm.
* This must be adjusted with the scene's scale and/or units.
* A value too low will result in high frequency noise, while a value too high will
* result in the loss of geometry edges. For AO, it is generally better to be too
* blurry than not enough.
*/
public float bilateralThreshold = 0.05f;
/**
* The quality setting controls the number of samples used for evaluating Ambient
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
@@ -198,6 +208,11 @@ public class View {
*/
public boolean enabled = false;
/**
* enables bent normals computation from AO, and specular AO
*/
public boolean bentNormals = false;
/**
* Minimal angle to consider in radian. This is used to reduce the creases that can
* appear due to insufficiently tessellated geometry.
@@ -284,11 +299,11 @@ public class View {
*
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* maximum is 12. This value together with resolution influences the spread of the
* maximum is 11. This value together with resolution influences the spread of the
* blur effect. This value can be silently reduced to accommodate the original
* image size.
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 4096. This parameter is
* resolution: Resolution of bloom's vertical axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 2048. This parameter is
* silently clamped to the minimum and maximum.
* It is highly recommended that this value be smaller than the target resolution
* after dynamic resolution is applied (horizontally and vertically).
@@ -329,7 +344,7 @@ public class View {
public float strength = 0.10f;
/**
* Resolution of minor axis (2^levels to 4096)
* Resolution of minor axis (2^levels to 2048)
*/
public int resolution = 360;
@@ -339,7 +354,7 @@ public class View {
public float anamorphism = 1.0f;
/**
* Number of blur levels (3 to 12)
* Number of blur levels (3 to 11)
*/
public int levels = 6;
@@ -363,6 +378,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;
}
/**
@@ -436,14 +497,6 @@ public class View {
MEDIAN
}
/**
* focus distance in world units
*
* @deprecated use {@link Camera#setFocusDistance(float)}
*/
@Deprecated
public float focusDistance = 10.0f;
/**
* circle of confusion scale factor (amount of blur)
*
@@ -649,20 +702,44 @@ public class View {
/**
* View-level options for VSM shadowing.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @see View#setVsmShadowOptions
*/
public static class VsmShadowOptions {
/**
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
* than 0, mipmaps will automatically be generated each frame for all lights.
* This implies mipmapping below.
*
* <p>
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
* </p>
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*/
public int anisotropy = 0;
/**
* Whether to generate mipmaps for all VSM shadow maps.
*/
public boolean mipmapping = false;
/**
* EVSM exponent
* The maximum value permissible is 5.54 for a shadow map in fp16, or 42.0 for a
* shadow map in fp32. Currently the shadow map bit depth is always fp16.
*/
public float exponent = 5.54f;
/**
* 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;
}
/**
@@ -893,16 +970,6 @@ public class View {
nSetShadowingEnabled(getNativeObject(), enabled);
}
/**
* Enables or disables shadow mapping. Enabled by default.
*
* @deprecated Use {@link #setShadowingEnabled}
*/
@Deprecated
public void setShadowsEnabled(boolean enabled) {
setShadowingEnabled(enabled);
}
/**
* @return whether shadowing is enabled
*/
@@ -1280,7 +1347,8 @@ public class View {
*/
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
mVsmShadowOptions = options;
nSetVsmShadowOptions(getNativeObject(), options.anisotropy);
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
options.exponent, options.minVarianceScale, options.lightBleedReduction);
}
/**
@@ -1325,9 +1393,11 @@ public class View {
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
mAmbientOcclusionOptions = options;
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
options.resolution, options.intensity, options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
options.enabled, options.minHorizonAngleRad);
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance, options.ssctContactDistanceMax, options.ssctIntensity,
options.resolution, options.intensity, options.bilateralThreshold,
options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
options.enabled, options.bentNormals, options.minHorizonAngleRad);
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance,
options.ssctContactDistanceMax, options.ssctIntensity,
options.ssctLightDirection[0], options.ssctLightDirection[1], options.ssctLightDirection[2],
options.ssctDepthBias, options.ssctDepthSlopeBias, options.ssctSampleCount,
options.ssctRayCount, options.ssctEnabled);
@@ -1357,7 +1427,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);
}
/**
@@ -1442,7 +1515,7 @@ public class View {
*/
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
mDepthOfFieldOptions = options;
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale,
nSetDepthOfFieldOptions(getNativeObject(), options.cocScale,
options.maxApertureDiameter, options.enabled, options.filter.ordinal(),
options.nativeResolution, options.foregroundRingCount, options.backgroundRingCount,
options.fastGatherRingCount, options.maxForegroundCOC, options.maxBackgroundCOC);
@@ -1491,7 +1564,7 @@ public class View {
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetShadowType(long nativeView, int type);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float exponent, float minVarianceScale, float lightBleedReduction);
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);
@@ -1499,12 +1572,13 @@ public class View {
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
private static native int nGetAmbientOcclusion(long nativeView);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int lowPassFilter, int upsampling, boolean enabled, float minHorizonAngleRad);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, float minHorizonAngleRad);
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
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);

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)
@@ -20,23 +22,37 @@ add_library(civetweb STATIC IMPORTED)
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
include_directories(${FILAMENT_DIR}/include
..
../../libs/utils/include)
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
..
${IMAGEIO_DIR}/include
../../libs/utils/include)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
@@ -45,6 +61,7 @@ target_link_libraries(filament-utils-jni
gltfio-jni
civetweb
camutils
iblprefilter
image
viewer
)

View File

@@ -84,7 +84,13 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
}
}
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
automation->tick((View*) view, ptrMaterials, materialCount, (Renderer*) renderer, deltaTime);
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;
@@ -94,8 +100,9 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
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 lightEntity, jlong nativeLm, jlong scene, jlong renderer) {
jint sunlightEntity, jintArray assetLights, jlong nativeLm, jlong scene, jlong renderer) {
using MaterialPointer = MaterialInstance*;
jsize materialCount = 0;
jlong* longMaterials = nullptr;
MaterialPointer* ptrMaterials = nullptr;
@@ -107,17 +114,42 @@ Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* e
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);
automation->applySettings(nativeJson, jsonLength, (View*) view, ptrMaterials, materialCount,
(IndirectLight*) nativeIbl, (Entity&) lightEntity, (LightManager*) nativeLm,
(Scene*) scene, (Renderer*) renderer);
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
@@ -136,6 +168,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
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);
@@ -145,6 +178,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -51,7 +51,7 @@ import com.google.android.filament.Renderer;
* (shouldClose) that is triggered after the last test has been invoked.
*/
public class AutomationEngine {
private long mNativeObject;
private final long mNativeObject;
private ColorGrading mColorGrading;
/**
@@ -76,6 +76,20 @@ public class AutomationEngine {
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.
*/
@@ -88,6 +102,7 @@ public class AutomationEngine {
public boolean skyboxEnabled = true;
public float cameraFocalLength = 28.0f;
public float cameraFocusDistance = 0.0f;
public boolean autoScaleEnabled = true;
}
/**
@@ -140,22 +155,22 @@ public class AutomationEngine {
* This is when settings get applied, screenshots are (optionally) exported, and the internal
* test counter is potentially incremented.
*
* @param view The Filament View that automation pushes changes to.
* @param materials Optional set of of materials that can receive parameter tweaks.
* @param renderer The Filament Renderer that can be used to take screenshots.
* @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 View view, @Nullable MaterialInstance[] materials,
@NonNull Renderer renderer, float deltaTime) {
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 (materials != null) {
nativeMaterialInstances = new long[materials.length];
if (content.materials != null) {
nativeMaterialInstances = new long[content.materials.length];
for (int i = 0; i < nativeMaterialInstances.length; i++) {
nativeMaterialInstances[i] = materials[i].getNativeObject();
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
}
}
long nativeView = view.getNativeObject();
long nativeRenderer = renderer.getNativeObject();
long nativeView = content.view.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
}
@@ -167,24 +182,32 @@ public class AutomationEngine {
*
* 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 View view,
@Nullable MaterialInstance[] materials, @Nullable IndirectLight ibl, @Entity int light,
@NonNull LightManager lm, @NonNull Scene scene, @NonNull Renderer renderer) {
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 (materials != null) {
nativeMaterialInstances = new long[materials.length];
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] = materials[i].getNativeObject();
nativeMaterialInstances[i] = content.materials[i].getNativeObject();
}
}
long nativeView = view.getNativeObject();
long nativeIbl = ibl == null ? 0 : ibl.getNativeObject();
long nativeLm = lm.getNativeObject();
long nativeScene = scene.getNativeObject();
long nativeRenderer = renderer.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, light, nativeLm, nativeScene, nativeRenderer);
nativeIbl, content.sunlight, content.assetLights, nativeLm, nativeScene,
nativeRenderer);
}
/**
@@ -246,7 +269,8 @@ public class AutomationEngine {
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 light, long lightManager, long scene, long renderer);
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);

View File

@@ -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
}

View File

@@ -0,0 +1,133 @@
/*
* 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);
*
* specularFilter = new IBLPrefilterContext.SpecularFilter(context);
* Texture reflections = specularFilter.run(skyboxTexture);
*
* IndirectLight ibl = IndirectLight.Builder()
* .reflections(reflections)
* .intensity(30000.0f)
* .build(engine);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
public class IBLPrefilterContext {
private final long mNativeObject;
public IBLPrefilterContext(Engine engine) {
mNativeObject = nCreate(engine.getNativeObject());
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create IBLPrefilterContext");
}
@Override
protected void finalize() throws Throwable {
nDestroy(mNativeObject);
super.finalize();
}
public static class EquirectangularToCubemap {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
private final HelperFinalizer mFinalizer;
private final long mNativeHelper;
public EquirectangularToCubemap(IBLPrefilterContext context) {
mNativeHelper = nCreateEquirectHelper(context.mNativeObject);
mFinalizer = new HelperFinalizer(mNativeHelper);
}
public Texture run(Texture equirect) {
long nativeTexture = nEquirectHelperRun(mNativeHelper, equirect.getNativeObject());
return new Texture(nativeTexture);
}
private static class HelperFinalizer {
private final long mNativeObject;
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
@Override
public void finalize() {
try {
super.finalize();
} catch (Throwable t) { // Ignore
} finally {
nDestroyEquirectHelper(mNativeObject);
}
}
}
}
public static class SpecularFilter {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
private final HelperFinalizer mFinalizer;
private final long mNativeHelper;
public SpecularFilter(IBLPrefilterContext context) {
mNativeHelper = nCreateSpecularFilter(context.mNativeObject);
mFinalizer = new HelperFinalizer(mNativeHelper);
}
public Texture run(Texture skybox) {
long nativeTexture = nSpecularFilterRun(mNativeHelper, skybox.getNativeObject());
return new Texture(nativeTexture);
}
private static class HelperFinalizer {
private final long mNativeObject;
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
@Override
public void finalize() {
try {
super.finalize();
} catch (Throwable t) { // Ignore
} finally {
nDestroySpecularFilter(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);
}

View File

@@ -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
}

View File

@@ -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,

View File

@@ -105,12 +105,12 @@ 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())
assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
// Always add a direct light source since it is required for shadowing.
@@ -225,6 +225,16 @@ 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.
*/
@@ -299,7 +309,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)

View File

@@ -81,6 +81,16 @@ public class RemoteServer {
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);

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)
@@ -60,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

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <gltfio/MaterialProvider.h>
using namespace filament;
using namespace gltfio;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nCreateMaterialProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createUbershaderLoader(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterialProvider(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
delete provider;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterials(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
provider->destroyMaterials();
}

View File

@@ -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);
}
}

View File

@@ -45,7 +45,7 @@ import java.nio.Buffer;
*
* ...
*
* assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
* assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
*
* filamentAsset = assets.open("models/lucy.gltf").use { input -&gt;
* val bytes = ByteArray(input.available())
@@ -85,23 +85,22 @@ public class AssetLoader {
* {@link FilamentAsset}.
*
* @param engine the engine that the loader should pass to builder objects
* @param generator specifies if materials should be generated or loaded from a pre-built set
* @param provider an object that provides Filament materials corresponding to glTF materials
* @param entities the EntityManager that should be used to create entities
*/
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider generator,
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider provider,
@NonNull EntityManager entities) {
long nativeEngine = engine.getNativeObject();
long nativeMaterials = generator.getNativeObject();
long nativeEntities = entities.getNativeObject();
mNativeObject = nCreateAssetLoader(nativeEngine, nativeMaterials, nativeEntities);
mNativeObject = nCreateAssetLoader(nativeEngine, provider, nativeEntities);
if (mNativeObject == 0) {
throw new IllegalStateException("Unable to parse glTF asset.");
}
mEngine = engine;
mMaterialCache = generator;
mMaterialCache = provider;
}
/**
@@ -149,10 +148,11 @@ public class AssetLoader {
if (nativeAsset == 0) {
return null;
}
FilamentAsset asset = new FilamentAsset(mEngine, nativeAsset);
for (int i = 0; i < nativeInstances.length; i++) {
instances[i] = new FilamentInstance(nativeInstances[i]);
instances[i] = new FilamentInstance(asset, nativeInstances[i]);
}
return new FilamentAsset(mEngine, nativeAsset);
return asset;
}
/**
@@ -178,7 +178,7 @@ public class AssetLoader {
if (nativeInstance == 0) {
return null;
}
return new FilamentInstance(nativeInstance);
return new FilamentInstance(asset, nativeInstance);
}
/**
@@ -197,7 +197,7 @@ public class AssetLoader {
asset.clearNativeObject();
}
private static native long nCreateAssetLoader(long nativeEngine, long nativeGenerator,
private static native long nCreateAssetLoader(long nativeEngine, Object provider,
long nativeEntities);
private static native void nDestroyAssetLoader(long nativeLoader);
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);

View File

@@ -186,6 +186,16 @@ public class FilamentAsset {
return nGetName(getNativeObject(), entity);
}
/**
* Gets the glTF extras string for the asset or a specific node.
*
* @param entity the entity corresponding to the glTF node, or 0 to get the asset-level string.
* @return the requested extras string, or null if it does not exist.
*/
public @Nullable String getExtras(@Entity int entity) {
return nGetExtras(mNativeObject, entity);
}
/**
* Creates or retrieves the <code>Animator</code> interface for this asset.
*
@@ -252,6 +262,7 @@ public class FilamentAsset {
private static native void nGetBoundingBox(long nativeAsset, float[] box);
private static native String nGetName(long nativeAsset, int entity);
private static native String nGetExtras(long nativeAsset, int entity);
private static native long nGetAnimator(long nativeAsset);
private static native int nGetResourceUriCount(long nativeAsset);
private static native void nGetResourceUris(long nativeAsset, String[] result);

View File

@@ -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.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,36 +16,108 @@
package com.google.android.filament.gltfio;
import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import java.lang.reflect.Method;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
/**
* Loads pre-generated ubershader materials that fulfill glTF requirements.
*
* <p>This class is used by {@link AssetLoader} to create Filament materials.
* Client applications do not need to call methods on it.</p>
*/
public class MaterialProvider {
private long mNativeObject;
public interface MaterialProvider {
/**
* Constructs an ubershader loader using the supplied {@link Engine}.
*
* @param engine the engine used to create materials
* MaterialKey specifies the requirements for a requested glTF material.
* The provider creates Filament materials that fulfill these requirements.
*/
public MaterialProvider(Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateMaterialProvider(nativeEngine);
}
public static class MaterialKey {
public boolean doubleSided;
public boolean unlit;
public boolean hasVertexColors;
public boolean hasBaseColorTexture;
public boolean hasNormalTexture;
public boolean hasOcclusionTexture;
public boolean hasEmissiveTexture;
public boolean useSpecularGlossiness;
public int alphaMode; // 0 = OPAQUE, 1 = MASK, 2 = BLEND
public boolean enableDiagnostics;
public boolean hasMetallicRoughnessTexture; // piggybacks with specularRoughness
public int metallicRoughnessUV; // piggybacks with specularRoughness
public int baseColorUV;
public boolean hasClearCoatTexture;
public int clearCoatUV;
public boolean hasClearCoatRoughnessTexture;
public int clearCoatRoughnessUV;
public boolean hasClearCoatNormalTexture;
public int clearCoatNormalUV;
public boolean hasClearCoat;
public boolean hasTransmission;
public boolean hasTextureTransforms;
public int emissiveUV;
public int aoUV;
public int normalUV;
public boolean hasTransmissionTexture;
public int transmissionUV;
public boolean hasSheenColorTexture;
public int sheenColorUV;
public boolean hasSheenRoughnessTexture;
public int sheenRoughnessUV;
public boolean hasVolumeThicknessTexture;
public int volumeThicknessUV;
public boolean hasSheen;
public boolean hasIOR;
public MaterialKey() {}
static {
nGlobalInit();
}
/**
* Populate UV map according to the material key, altering latter if required.
*
* Filament supports up to 2 UV sets. glTF has arbitrary texcoord set indices, but it
* allows implementations to support only 2 simultaneous sets. Here we build a mapping
* table with 1-based indices where 0 means unused. Note that the order in which we drop
* textures can affect the look of certain assets. This "order of degradation" is
* stipulated by the glTF 2.0 specification.
*
* @param uvmap Output argument that gets populated with a small table that maps from a
* glTF uv index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
*/
public void constrainMaterial(@NonNull @Size(min = 8) int[] uvmap) {
nConstrainMaterial(this, uvmap);
}
private static native void nGlobalInit();
private static native void nConstrainMaterial(MaterialKey materialKey, int[] uvmap);
};
/**
* Frees memory associated with the native material provider.
* */
public void destroy() {
nDestroyMaterialProvider(mNativeObject);
mNativeObject = 0;
}
* Creates or fetches a compiled Filament material, then creates an instance from it.
*
* @param config Specifies requirements; might be mutated due to resource constraints.
* @param uvmap Output argument that gets populated with a small table that maps from a glTF uv
* index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
* @param label Optional tag that is not a part of the cache key.
*/
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label);
/**
* Creates and returns an array containing all cached materials.
*/
public @NonNull Material[] getMaterials();
/**
* Returns true if the presence of the given vertex attribute is required.
*
* Some types of providers (e.g. ubershader) require dummy attribute values
* if the glTF model does not provide them.
*
* NOTE: The given attribute is the VertexAttribute enum casted to an integer.
* This is done to streamline the JNI work between Java and Native layers.
*/
public boolean needsDummyData(int attrib);
/**
* Destroys all cached materials.
@@ -53,15 +125,5 @@ public class MaterialProvider {
* This is not called automatically when MaterialProvider is destroyed, which allows
* clients to take ownership of the cache if desired.
*/
public void destroyMaterials() {
nDestroyMaterials(mNativeObject);
}
long getNativeObject() {
return mNativeObject;
}
private static native long nCreateMaterialProvider(long nativeEngine);
private static native void nDestroyMaterialProvider(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
public void destroyMaterials();
}

View File

@@ -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.
*/
package com.google.android.filament.gltfio;
import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
/**
* Loads pre-generated ubershader materials that fulfill glTF requirements.
*
* <p>This class is used by {@link AssetLoader} to create Filament materials.
* Client applications do not need to call methods on it.</p>
*/
public class UbershaderLoader implements MaterialProvider {
private long mNativeObject;
/**
* Constructs an ubershader loader using the supplied {@link Engine}.
*
* @param engine the engine used to create materials
*/
public UbershaderLoader(Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateUbershaderLoader(nativeEngine);
}
/**
* Frees memory associated with the native material provider.
* */
public void destroy() {
nDestroyUbershaderLoader(mNativeObject);
mNativeObject = 0;
}
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label) {
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
}
public @NonNull Material[] getMaterials() {
final int count = nGetMaterialCount(mNativeObject);
Material[] result = new Material[count];
long[] natives = new long[count];
nGetMaterials(mNativeObject, natives);
for (int i = 0; i < count; i++) {
result[i] = new Material(natives[i]);
}
return result;
}
public boolean needsDummyData(int attrib) {
VertexBuffer.VertexAttribute vattrib = VertexBuffer.VertexAttribute.values()[attrib];
switch (vattrib) {
case UV0:
case UV1:
case COLOR:
return true;
default:
return false;
}
}
public void destroyMaterials() {
nDestroyMaterials(mNativeObject);
}
public long getNativeObject() {
return mNativeObject;
}
private static native long nCreateUbershaderLoader(long nativeEngine);
private static native void nDestroyUbershaderLoader(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
private static native long nCreateMaterialInstance(long nativeProvider, MaterialKey config, int[] uvmap, String label);
private static native int nGetMaterialCount(long nativeProvider);
private static native void nGetMaterials(long nativeProvider, long[] result);
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.9.24
VERSION_NAME=1.12.1
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Thu Nov 05 09:33:02 PST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

53
android/gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# 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
#
# https://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.
#
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

43
android/gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

View File

@@ -24,6 +24,9 @@ import android.view.*
import android.view.GestureDetector
import android.widget.TextView
import android.widget.Toast
import com.google.android.filament.Fence
import com.google.android.filament.IndirectLight
import com.google.android.filament.Skybox
import com.google.android.filament.utils.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -57,6 +60,9 @@ class MainActivity : Activity() {
private var statusText: String? = null
private var latestDownload: String? = null
private val automation = AutomationEngine()
private var loadStartTime = 0L
private var loadStartFence: Fence? = null
private val viewerContent = AutomationEngine.ViewerContent()
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
@@ -71,6 +77,11 @@ class MainActivity : Activity() {
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
modelViewer = ModelViewer(surfaceView)
viewerContent.view = modelViewer.view
viewerContent.sunlight = modelViewer.light
viewerContent.lightManager = modelViewer.engine.lightManager
viewerContent.scene = modelViewer.scene
viewerContent.renderer = modelViewer.renderer
surfaceView.setOnTouchListener { _, event ->
modelViewer.onTouchEvent(event)
@@ -78,27 +89,28 @@ class MainActivity : Activity() {
true
}
createRenderables()
createDefaultRenderables()
createIndirectLight()
setStatusText("To load a new model, go to the above URL on your host machine.")
val dynamicResolutionOptions = modelViewer.view.dynamicResolutionOptions
dynamicResolutionOptions.enabled = true
modelViewer.view.dynamicResolutionOptions = dynamicResolutionOptions
val view = modelViewer.view
view.dynamicResolutionOptions = view.dynamicResolutionOptions.apply {
enabled = true
}
val ssaoOptions = modelViewer.view.ambientOcclusionOptions
ssaoOptions.enabled = true
modelViewer.view.ambientOcclusionOptions = ssaoOptions
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
enabled = true
}
val bloomOptions = modelViewer.view.bloomOptions
bloomOptions.enabled = true
modelViewer.view.bloomOptions = bloomOptions
view.bloomOptions = view.bloomOptions.apply {
enabled = true
}
remoteServer = RemoteServer(8082)
}
private fun createRenderables() {
private fun createDefaultRenderables() {
val buffer = assets.open("models/scene.gltf").use { input ->
val bytes = ByteArray(input.available())
input.read(bytes)
@@ -106,7 +118,7 @@ class MainActivity : Activity() {
}
modelViewer.loadModelGltfAsync(buffer) { uri -> readCompressedAsset("models/$uri") }
modelViewer.transformToUnitCube()
updateRootTransform()
}
private fun createIndirectLight() {
@@ -114,11 +126,12 @@ class MainActivity : Activity() {
val scene = modelViewer.scene
val ibl = "default_env"
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
scene.indirectLight = KtxLoader.createIndirectLight(engine, it)
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
scene.indirectLight!!.intensity = 30_000.0f
viewerContent.indirectLight = modelViewer.scene.indirectLight
}
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
scene.skybox = KtxLoader.createSkybox(engine, it)
scene.skybox = KTXLoader.createSkybox(engine, it)
}
}
@@ -151,7 +164,39 @@ class MainActivity : Activity() {
withContext(Dispatchers.Main) {
modelViewer.destroyModel()
modelViewer.loadModelGlb(message.buffer)
modelViewer.transformToUnitCube()
updateRootTransform()
loadStartTime = System.nanoTime()
loadStartFence = modelViewer.engine.createFence()
}
}
private suspend fun loadHdr(message: RemoteServer.ReceivedMessage) {
withContext(Dispatchers.Main) {
val engine = modelViewer.engine
val equirect = HDRLoader.createTexture(engine, message.buffer)
if (equirect == null) {
setStatusText("Could not decode HDR file.")
} else {
setStatusText("Successfully decoded HDR file.")
val context = IBLPrefilterContext(engine)
val equirectToCubemap = IBLPrefilterContext.EquirectangularToCubemap(context)
val skyboxTexture = equirectToCubemap.run(equirect)!!
engine.destroyTexture(equirect)
val specularFilter = IBLPrefilterContext.SpecularFilter(context)
val reflections = specularFilter.run(skyboxTexture)
val ibl = IndirectLight.Builder()
.reflections(reflections)
.intensity(30000.0f)
.build(engine)
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
modelViewer.scene.skybox = sky
modelViewer.scene.indirectLight = ibl
}
}
}
@@ -239,7 +284,9 @@ class MainActivity : Activity() {
pathToBufferMapping[path]
}
}
modelViewer.transformToUnitCube()
updateRootTransform()
loadStartTime = System.nanoTime()
loadStartFence = modelViewer.engine.createFence()
}
}
@@ -256,6 +303,7 @@ class MainActivity : Activity() {
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
remoteServer?.close()
}
fun loadModelData(message: RemoteServer.ReceivedMessage) {
@@ -265,6 +313,8 @@ class MainActivity : Activity() {
CoroutineScope(Dispatchers.IO).launch {
if (message.label.endsWith(".zip")) {
loadZip(message)
} else if (message.label.endsWith(".hdr")) {
loadHdr(message)
} else {
loadGlb(message)
}
@@ -273,11 +323,19 @@ class MainActivity : Activity() {
fun loadSettings(message: RemoteServer.ReceivedMessage) {
val json = StandardCharsets.UTF_8.decode(message.buffer).toString()
automation.applySettings(json, modelViewer.view, null,
modelViewer.scene.indirectLight, modelViewer.light, modelViewer.engine.lightManager,
modelViewer.scene, modelViewer.renderer)
modelViewer.view.colorGrading = automation.getColorGrading((modelViewer.engine))
viewerContent.assetLights = modelViewer.asset?.lightEntities
automation.applySettings(json, viewerContent)
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
updateRootTransform()
}
private fun updateRootTransform() {
if (automation.viewerOptions.autoScaleEnabled) {
modelViewer.transformToUnitCube()
} else {
modelViewer.clearRootTransform()
}
}
inner class FrameCallback : Choreographer.FrameCallback {
@@ -285,6 +343,16 @@ class MainActivity : Activity() {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
loadStartFence?.let {
if (it.wait(Fence.Mode.FLUSH, 0) == Fence.FenceStatus.CONDITION_SATISFIED) {
val end = System.nanoTime()
val total = (end - loadStartTime) / 1_000_000
Log.i(TAG, "The Filament backend took $total ms to load the model geometry.")
modelViewer.engine.destroyFence(it)
loadStartFence = null
}
}
modelViewer.animator?.apply {
if (animationCount > 0) {
val elapsedTimeSeconds = (frameTimeNanos - startTime).toDouble() / 1_000_000_000
@@ -318,11 +386,11 @@ class MainActivity : Activity() {
}
}
// Just for testing purposes, this releases the model and reloads it.
// Just for testing purposes, this releases the current model and reloads the default model.
inner class DoubleTapListener : GestureDetector.SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent?): Boolean {
modelViewer.destroyModel()
createRenderables()
createDefaultRenderables()
return super.onDoubleTap(e)
}
}

View File

@@ -109,7 +109,8 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -342,13 +343,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -113,7 +113,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -113,7 +113,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -249,12 +249,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -114,7 +114,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -358,13 +358,14 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -101,7 +101,7 @@ class FilamentLiveWallpaper : WallpaperService() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -167,7 +167,8 @@ class FilamentLiveWallpaper : WallpaperService() {
engine.destroyRenderer(renderer)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
EntityManager.get().destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly
@@ -221,4 +222,4 @@ class FilamentLiveWallpaper : WallpaperService() {
}
}
}
}
}

View File

@@ -112,7 +112,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -289,12 +289,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -65,6 +65,7 @@ class MainActivity : Activity() {
private lateinit var view1: View
private lateinit var view2: View
private lateinit var view3: View
private lateinit var view4: View
// We need skybox to set the background color
private lateinit var skybox: Skybox
// Should be pretty obvious :)
@@ -119,16 +120,20 @@ class MainActivity : Activity() {
view1 = engine.createView()
view2 = engine.createView()
view3 = engine.createView()
view4 = engine.createView()
view0.setName("view0");
view1.setName("view1");
view2.setName("view2");
view3.setName("view3");
view4.setName("view4");
view4.blendMode = View.BlendMode.TRANSLUCENT;
skybox = Skybox.Builder().build(engine);
scene.skybox = skybox
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupViews() {
@@ -136,11 +141,13 @@ class MainActivity : Activity() {
view1.camera = camera
view2.camera = camera
view3.camera = camera
view4.camera = camera
view0.scene = scene
view1.scene = scene
view2.scene = scene
view3.scene = scene
view4.scene = scene
}
private fun setupScene() {
@@ -373,15 +380,17 @@ class MainActivity : Activity() {
engine.destroyView(view1)
engine.destroyView(view2)
engine.destroyView(view3)
engine.destroyView(view4)
engine.destroySkybox(skybox)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly
@@ -410,6 +419,9 @@ class MainActivity : Activity() {
skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f);
renderer.render(view3)
skybox.setColor(0.0f, 0.0f, 0.0f, 0.0f);
renderer.render(view4)
renderer.endFrame()
}
}
@@ -442,6 +454,7 @@ class MainActivity : Activity() {
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
view3.viewport = Viewport(width / 2, height / 2, width / 2, height / 2)
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
}
}

View File

@@ -148,7 +148,7 @@ public class MainActivity extends Activity
mRenderer = mEngine.createRenderer();
mScene = mEngine.createScene();
mView = mEngine.createView();
mCamera = mEngine.createCamera();
mCamera = mEngine.createCamera(mEngine.getEntityManager().create());
mCamera.lookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
@@ -223,9 +223,10 @@ public class MainActivity extends Activity
mEngine.destroyView(mView);
mEngine.destroyScene(mScene);
mEngine.destroyCamera(mCamera);
mEngine.destroyCameraComponent(mCamera.getEntity());
EntityManager.get().destroy(mPage.renderable);
EntityManager.get().destroy(mCamera.getEntity());
mEngine.destroy();
}
@@ -298,4 +299,4 @@ public class MainActivity extends Activity
canvas.drawBitmap(bmp, borderSize, borderSize, null);
return modified;
}
}
}

View File

@@ -121,7 +121,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -328,13 +328,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -113,7 +113,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -39,5 +39,5 @@ dependencies {
implementation deps.kotlin
implementation project(':filament-android')
implementation project(':gltfio-android')
implementation project(':filament-utils-android') // required for KtxLoader
implementation project(':filament-utils-android') // required for KTXLoader
}

View File

@@ -117,7 +117,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
@@ -269,12 +269,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

View File

@@ -136,7 +136,7 @@ class MainActivity : Activity() {
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
camera = engine.createCamera(engine.entityManager.create())
// clear the swapchain with transparent pixels
val options = renderer.clearOptions
@@ -294,12 +294,13 @@ class MainActivity : Activity() {
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(renderable)
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly

119
build.sh
View File

@@ -17,14 +17,16 @@ function print_help {
echo " Generate .tgz build archives, implies -i."
echo " -c"
echo " Clean build directories."
echo " -C"
echo " Clean build directories and revert android/ to a freshly sync'ed state."
echo " All (and only) git-ignored files under android/ are deleted."
echo " This is sometimes needed instead of -c (which still misses some clean steps)."
echo " -d"
echo " Enable matdbg and disable material optimization."
echo " -f"
echo " Always invoke CMake before incremental builds."
echo " -i"
echo " Install build output"
echo " -j"
echo " Do not compile desktop Java projects"
echo " -m"
echo " Compile with make instead of ninja."
echo " -p platform1,platform2,..."
@@ -48,6 +50,10 @@ function print_help {
echo " For macOS, this builds universal binaries for both Apple silicon and Intel-based Macs."
echo " -w"
echo " Build Web documents (compiles .md.html files to .html)."
echo " -k sample1,sample2,..."
echo " When building for Android, also build select sample APKs."
echo " sampleN is an Android sample, e.g., sample-gltf-viewer."
echo " This automatically performs a partial desktop build and install."
echo ""
echo "Build types:"
echo " release"
@@ -103,13 +109,16 @@ function print_matdbg_help {
echo ""
}
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/android/ndk.version | cut -f 1 -d ".")}
# Requirements
CMAKE_MAJOR=3
CMAKE_MINOR=10
ANDROID_NDK_VERSION=21
CMAKE_MINOR=19
# Internal variables
ISSUE_CLEAN=false
ISSUE_CLEAN_AGGRESSIVE=false
ISSUE_DEBUG_BUILD=false
ISSUE_RELEASE_BUILD=false
@@ -134,9 +143,10 @@ ISSUE_CMAKE_ALWAYS=false
ISSUE_WEB_DOCS=false
RUN_TESTS=false
ANDROID_SAMPLES=()
BUILD_ANDROID_SAMPLES=false
FILAMENT_ENABLE_JAVA=ON
RUN_TESTS=false
INSTALL_COMMAND=
@@ -168,6 +178,12 @@ function build_clean {
rm -Rf android/filament-utils-android/build android/filament-utils-android/.externalNativeBuild android/filament-utils-android/.cxx
}
function build_clean_aggressive {
echo "Cleaning build directories..."
rm -Rf out
git clean -qfX android
}
function build_desktop_target {
local lc_target=$(echo "$1" | tr '[:upper:]' '[:lower:]')
local build_targets=$2
@@ -197,7 +213,6 @@ function build_desktop_target {
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
-DFILAMENT_ENABLE_JAVA="${FILAMENT_ENABLE_JAVA}" \
${SWIFTSHADER_OPTION} \
${MATDBG_OPTION} \
${deployment_target} \
@@ -322,6 +337,7 @@ function build_android_target {
-G "${BUILD_GENERATOR}" \
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DFILAMENT_NDK_VERSION="${FILAMENT_NDK_VERSION}" \
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
${MATDBG_OPTION} \
@@ -366,16 +382,9 @@ function ensure_android_build {
exit 1
fi
local ndk_side_by_side="${ANDROID_HOME}/ndk/"
if [[ -d ${ndk_side_by_side} ]]; then
# shellcheck disable=SC2012
local ndk_version=$(ls "${ndk_side_by_side}" | sort -V | tail -n 1 | cut -f 1 -d ".")
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
exit 1
fi
else
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
# shellcheck disable=SC2012
if [[ -z $(ls "${ANDROID_HOME}/ndk/" | sort -V | grep "^${FILAMENT_NDK_VERSION}") ]]; then
echo "Error: Android NDK side-by-side version ${FILAMENT_NDK_VERSION} or compatible must be installed, exiting"
exit 1
fi
@@ -399,6 +408,24 @@ function build_android {
build_desktop "${MOBILE_HOST_TOOLS}"
# When building the samples, we need to partially "install" the host tools so Gradle can see
# them.
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
mkdir -p out/debug/filament/bin
for tool in ${MOBILE_HOST_TOOLS}; do
cp out/cmake-debug/tools/${tool}/${tool} out/debug/filament/bin/
done
fi
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
mkdir -p out/release/filament/bin
for tool in ${MOBILE_HOST_TOOLS}; do
cp out/cmake-release/tools/${tool}/${tool} out/release/filament/bin/
done
fi
fi
INSTALL_COMMAND=${old_install_command}
if [[ "${ABI_ARM64_V8A}" == "true" ]]; then
@@ -438,6 +465,15 @@ function build_android {
-Pfilament_abis=${ABI_GRADLE_OPTION} \
:filamat-android:assembleDebug
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pfilament_dist_dir=../out/android-debug/filament \
-Pfilament_abis=${ABI_GRADLE_OPTION} \
:samples:${sample}:assembleDebug
done
fi
if [[ "${INSTALL_COMMAND}" ]]; then
echo "Installing out/filamat-android-debug.aar..."
cp filamat-android/build/outputs/aar/filamat-android-lite-debug.aar ../out/
@@ -453,6 +489,14 @@ function build_android {
echo "Installing out/filament-utils-android-debug.aar..."
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
echo "Installing out/${sample}-debug.apk"
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug-unsigned.apk \
../out/${sample}-debug.apk
done
fi
fi
fi
@@ -470,6 +514,15 @@ function build_android {
-Pfilament_abis=${ABI_GRADLE_OPTION} \
:filamat-android:assembleRelease
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pfilament_dist_dir=../out/android-release/filament \
-Pfilament_abis=${ABI_GRADLE_OPTION} \
:samples:${sample}:assembleRelease
done
fi
if [[ "${INSTALL_COMMAND}" ]]; then
echo "Installing out/filamat-android-release.aar..."
cp filamat-android/build/outputs/aar/filamat-android-lite-release.aar ../out/
@@ -485,6 +538,14 @@ function build_android {
echo "Installing out/filament-utils-android-release.aar..."
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
echo "Installing out/${sample}-release.apk"
cp samples/${sample}/build/outputs/apk/release/${sample}-release-unsigned.apk \
../out/${sample}-release.apk
done
fi
fi
fi
@@ -628,12 +689,6 @@ function validate_build_command {
exit 1
fi
fi
# Make sure we have Java
local javac_binary=$(command -v javac)
if [[ "${JAVA_HOME}" == "" ]] || [[ ! "${javac_binary}" ]]; then
echo "Warning: JAVA_HOME is not set, skipping Java projects"
FILAMENT_ENABLE_JAVA=OFF
fi
# If building a WebAssembly module, ensure we know where Emscripten lives.
if [[ "${EMSDK}" == "" ]] && [[ "${ISSUE_WEBGL_BUILD}" == "true" ]]; then
echo "Error: EMSDK is not set, exiting"
@@ -682,7 +737,7 @@ function run_tests {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacfijmp:q:uvslwtd" opt; do
while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
case ${opt} in
h)
print_help
@@ -695,9 +750,12 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
c)
ISSUE_CLEAN=true
;;
C)
ISSUE_CLEAN_AGGRESSIVE=true
;;
d)
PRINT_MATDBG_HELP=true
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
;;
f)
ISSUE_CMAKE_ALWAYS=true
@@ -705,9 +763,6 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
i)
INSTALL_COMMAND=install
;;
j)
FILAMENT_ENABLE_JAVA=OFF
;;
m)
BUILD_GENERATOR="Unix Makefiles"
BUILD_COMMAND="make"
@@ -796,6 +851,10 @@ while getopts ":hacfijmp:q:uvslwtd" opt; do
w)
ISSUE_WEB_DOCS=true
;;
k)
BUILD_ANDROID_SAMPLES=true
ANDROID_SAMPLES=$(echo "${OPTARG}" | tr ',' '\n')
;;
\?)
echo "Invalid option: -${OPTARG}" >&2
echo ""
@@ -834,6 +893,10 @@ if [[ "${ISSUE_CLEAN}" == "true" ]]; then
build_clean
fi
if [[ "${ISSUE_CLEAN_AGGRESSIVE}" == "true" ]]; then
build_clean_aggressive
fi
if [[ "${ISSUE_DESKTOP_BUILD}" == "true" ]]; then
build_desktop
fi

View File

@@ -8,9 +8,6 @@
#
# The default is release
NDK_VERSION="ndk;22.0.7026061"
ANDROID_NDK_VERSION=22
echo "This script is intended to run in a CI environment and may modify your current environment."
echo "Please refer to BUILDING.md for more information."
@@ -47,15 +44,12 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
fi
source `dirname $0`/../common/build-common.sh
# Only update and install the NDK if necessary, as this can be slow
ndk_side_by_side="${ANDROID_HOME}/ndk/"
if [[ -d $ndk_side_by_side ]]; then
ndk_version=`ls ${ndk_side_by_side} | sort -V | tail -n 1 | cut -f 1 -d "."`
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
fi
else
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
# Unless explicitly specified, NDK version will be set to match exactly the required one
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
# Install the required NDK version specifically (if not present)
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
fi
# Only build 1 32 bit and 1 64 bit target during presubmit to cut down build times
@@ -65,5 +59,11 @@ if [[ "$TARGET" == "presubmit" ]]; then
ANDROID_ABIS="-q arm64-v8a,x86"
fi
# Build the Android sample-gltf-viewer APK during release.
BUILD_SAMPLES=
if [[ "$TARGET" == "release" ]]; then
BUILD_SAMPLES="-k sample-gltf-viewer"
fi
pushd `dirname $0`/../.. > /dev/null
./build.sh -p android $ANDROID_ABIS -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION} ./build.sh -p android $ANDROID_ABIS -c $BUILD_SAMPLES $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE

View File

@@ -0,0 +1 @@
22.1.7171670

View File

@@ -3,4 +3,12 @@
if [[ "$GITHUB_WORKFLOW" ]]; then
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
CONTINUOUS_INTEGRATION=true
# Force Java to be Java 11 minimum, it defaults to 8 in GitHub runners for some platforms
export JAVA_HOME=${JAVA_HOME_11_X64}
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [[ "$java_version" < 11 ]]; then
echo "Android builds require Java 11, found version ${java_version} instead"
exit 0
fi
fi

View File

@@ -1,6 +1,6 @@
#!/bin/bash
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
unzip -q ninja-mac.zip
chmod +x ninja
export PATH="$PWD:$PATH"

View File

@@ -3,9 +3,9 @@
# version of clang we want to use
GITHUB_CLANG_VERSION=8
# version of CMake to use instead of the default one
CMAKE_VERSION=3.13.4
CMAKE_VERSION=3.19.5
# version of ninja to use
NINJA_VERSION=1.8.2
NINJA_VERSION=1.10.2
# Steps for GitHub Workflows
if [[ "$GITHUB_WORKFLOW" ]]; then

View File

@@ -1,6 +1,6 @@
#!/bin/bash
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
unzip -q ninja-mac.zip
chmod +x ninja
export PATH="$PWD:$PATH"

View File

@@ -31,7 +31,11 @@ set(DIST_ARCH arm64-v8a)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
if (NOT FILAMENT_NDK_VERSION)
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
endif()
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
list(SORT NDK_VERSIONS)
list(GET NDK_VERSIONS -1 NDK_VERSION)
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)

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