Compare commits

...

952 Commits

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

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

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

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

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

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

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

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

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

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

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

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

ssaogen is no longer needed

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

Add quality control to material sandbox.

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

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

- instead of time pass a random number in [0,1] generated on the CPU
  each frame.
  This will also allow to control temporal noise more easily if
  needed in the future (e.g. for accessibility or rendering tests)
2020-09-08 13:54:54 -07:00
Benjamin Doherty
b93059fad7 Bump version to 1.9.0 2020-09-08 10:47:23 -07:00
Ben Doherty
4ddd28a542 Update GitHub workflows to build release and release candidate branches (#3052) 2020-09-08 10:28:13 -07:00
Romain Guy
3092063ebb Revert recent change to depth_main
This shader is only used when the user doesn't specify anything that
could affect depth rendering. As such it must not attemp to read
material inputs.
2020-09-04 10:19:06 -07:00
Pixelflinger
b1070c6508 ssao code improvements and bug fixes
- fix a recent typo that affected SSAO quality
- add a upsampling quality checkbox in material_sandbox
- make use of textureLodOffset instead of texelFetch, so that
  we emulate more closely textureGather
- don't hardcode bilateral filter edge-distance in the shader
  (still hardcoded on the cpu side)
2020-09-03 22:44:48 -07:00
Ben Doherty
604e4ea77d Add VSM control to SimpleViewer (#3043) 2020-09-03 15:52:29 -07:00
Romain Guy
949855f1c8 Update README.md 2020-09-03 09:21:17 -07:00
Romain Guy
e984d92968 Update release notes 2020-09-03 09:20:16 -07:00
Pixelflinger
915c4d89f3 don't do the "reverse-z" in the shader for shadows
it can be done more easily on the cpu side
2020-09-02 20:52:46 -07:00
Pixelflinger
7fb1b853ac fix dynamic lighting frozen calculation
this broke recently with the reverse-z, the froxel calculation relies
on the depth, which is now inverted.

we actually fix our getNormalizedViewportCorrd() public API, which the
froxel code uses.
2020-09-02 15:13:34 -07:00
Mathias Agopian
513b3b8c3a improve stability of DoF with highlights (#3035)
apply the "fireflies" reduction during the downsampling pass instead of
the mipmap pass -- which didn't make a lot of sense.
2020-09-02 14:20:23 -07:00
Pixelflinger
f1b310ba0f minor refactor + comments in the main render pass
This just move the "finish color passes" pass before TAA and 
depth-resolve, where it belongs.
2020-09-02 09:18:13 -07:00
Pixelflinger
6329b865cf New API to create an Engine asynchronously
Because initializing the backend can be relatively slow, creating an
Engine can block the main thread, is this is a problem, this new API
can be used instead; while a bit more complex, it allow the engine to
be initialized asynchronously.
2020-09-01 15:34:04 -07:00
Pixelflinger
13cfad43b7 Use "inverted-Z" depth buffer
This significantly improve the depth-buffer resolution utilization
through the near-infinity range on Metal and Vulkan.

On OpenGL, this benefit is only seen when glClipControl is available.

The user-facing clip plane is unchanged [-1,1], the conversion
happens in filament's vertex shaders.


The bulk of this change consists in:

- invert the clip space's z in the vertex shader
- clear the depth buffer with 0
- invert all depth function comparisons
- fix all screen-space effects, e.g. ssao, DoF
- fix shadows and shadow biases
- use floating-point depth
- add a driver API to query which clip-space is used
- add glClipControl support to the gl backend
2020-09-01 09:46:46 -07:00
Pixelflinger
bb8cd6677d optionally compress highlights before bloom
This avoid unrealistic looking bloom halos from very strong highlights.
This is enabled by default.
2020-09-01 09:46:23 -07:00
Romain Guy
35ed1cb906 Update release notes 2020-08-31 13:52:04 -07:00
Pixelflinger
bcd8ce3c93 fix refraction + MSAA + TAA (depth resolve)
the depth buffer wasn't resolved in this case. We fix this by always
creating a depth buffer resolve pass -- which is a lot more robust.
this pass automatically culled if the depth is not used (i.e. TAA or 
DoF are off). The pass is a no-op if resolving is not needed.
2020-08-31 12:00:41 -07:00
Pixelflinger
84f0e97c78 apply the material clip-space transform to the depth 2020-08-31 11:59:52 -07:00
Philip Rideout
ae9504cbf9 Remove third_party/swiftshader.
These standard headers were unused, we already have them elsewhere in
the repo.
2020-08-31 11:34:07 -07:00
Philip Rideout
696327b35a Add SwiftShader to BUILDING.md 2020-08-31 11:34:07 -07:00
Pixelflinger
1a95c2b39b Fix a few issues with alpha-masked objects
- don't apply SSAO to blended objects
  these are not drawn into the structure buffer, so they don't 
  participate in SSAO.

- remove unused code that was needed for the depth prepass, which
  simplifies handling of blended objects.

- always treat alpha-masked objects as opaque.
2020-08-28 17:27:54 -07:00
toppa102
07393d6237 Changed ifdef WIN32 to WIN32 or _WIN32 (#3022) 2020-08-28 11:27:31 -07:00
Philip Rideout
2f294549a7 Migrate the SwiftShader build to Vulkan.
This also adds a -t flag to the easy build script for convenience.

SwiftShader on Vulkan can now be used as follows.

    git clone https://github.com/google/swiftshader.git
    cd swiftshader/build
    cmake .. &&  make -j && export SWIFTSHADER_LD_LIBRARY_PATH=`pwd`
    cd ../filament
    ./build.sh -t debug && ./out/cmake-debug/samples/gltf_viewer -a vulkan

Note that third_party/swiftshader does not need to exist since we
already have Vulkan headers. I will remove it in a subsequent PR.
2020-08-28 09:47:29 -07:00
Philip Rideout
2732d3ac13 Vulkan: Add support for VK_EXT_debug_utils.
Motivated by upcoming SwiftShader support, The old debug_report
extension is apparently deprecated but we need to keep it alive
for Android.
2020-08-28 09:46:49 -07:00
Pixelflinger
d7f7ab7aa4 fix a whole screen flicker when enabling TAA
the history projection wasn't initialized for the first frame.
2020-08-27 17:57:55 -07:00
Philip Rideout
0aa23945bb Do not pass a zero sample count to the backend.
FrameGraphTexture::Descriptor uses "0" to mean "auto" but the
sample count that is passed to the backend should always be 1 or
greater.

See also #2957.
2020-08-27 17:10:08 -07:00
Pixelflinger
6f5ff9dd4b render passes now also specify the depth range 2020-08-27 16:54:13 -07:00
Ben Doherty
8f32c9ad98 Handle blitting only depth in Metal backend (#3007) 2020-08-27 11:04:34 -07:00
Yadikaer Yasheng
c529a511f5 typescript defs for Texture & RenderTarget APIs (#3008)
* typescript defs for Texture &   RenderTarget APIs

* suggest to use helper functions to create textures
2020-08-26 18:52:07 -07:00
Pixelflinger
ab9c14d336 better multisample setup for depth buffer in color pass
The depth buffer was always set with a sample count of 1, this was
mostly moot because we almost never need the depth buffer after the
color pass; except for refraction and DoF.

In the case of refraction, we need to preserve the MS depth buffer
(just like we preserve the MS color buffer), moreover "backward resolve"
is not supported. So in that case, the depth buffer needed to be set to
MSAA samples.

In the case of DoF, we need to access a resolved depth texture, and
there is 2 cases here:
1) without refraction, a magic resolve is adequate -- in this case
   the depth MS count must be 1.
2) with refraction, we are forced in to a MS depth, so it needs a
   special resolve pass to be accessible from DoF.
2020-08-26 16:57:23 -07:00
Pixelflinger
6c471bc98c improve resolve pass so it works with depth buffers 2020-08-26 16:57:23 -07:00
Pixelflinger
96dc7c62d9 depth/stencil attachment's sample count validation
depth/stencil attachments must have the same MS sample count
than the FBO (rt) they're attached to.
this is because EXT_multisampled_render_to_texture[2] doesn't
resolve depth attachments. In this case, we can't use this extension.
2020-08-26 16:57:23 -07:00
Pixelflinger
a33b418478 EXT_multisampled_render_to_texture only support COLOR_ATTACHMENT0
For other attachments, we need EXT_multisampled_render_to_texture2.
2020-08-26 16:57:23 -07:00
Pixelflinger
037aa08cf2 remove support for "reverse multisample resolve"
- We will never allow this.
- minor code formating
2020-08-26 16:57:23 -07:00
Ben Doherty
bde0b477e0 Add ShadowType API and VSM rendering logic (#3004) 2020-08-26 15:41:08 -07:00
Philip Rideout
a922caed6b Vulkan: fix clear value list with MSAA. 2020-08-25 17:24:24 -07:00
Philip Rideout
040adc7fef Vulkan: add support for MSAA render targets.
This does not include lazy allocation or support for an MSAA swap chain.
Those features will come later.
2020-08-25 17:24:24 -07:00
Philip Rideout
079fda2e74 Fix VSCode warning. 2020-08-25 17:24:24 -07:00
Philip Rideout
3258972e0e WebGL: repair beginFrame() bindings.
This regressed when we added a callback argument, because the callback
cannot be bound.

This commit also modifies the helmet example to use the low-level API
for testing purposes.

Note that this omits the optional nanoseconds argument. JavaScript
does not support overloading and this argument probably cannot be
accurately provided anyway in a web environment.

Fixes #3002.
2020-08-25 17:24:04 -07:00
Philip Rideout
79b7e15c7b Vulkan + Metal: fix bad cache gc due to unsigned overflow.
This fixes a Vulkan validation error seen on Android about destroying a
framebuffer that is still in use by an active command buffer.
2020-08-25 10:56:27 -07:00
Ben Doherty
49cfbe79eb Add asserts to avoid loading into the MSAA sidecar texture (#2998) 2020-08-25 10:44:25 -07:00
Philip Rideout
44f4061227 Vulkan: request the driver info extension. 2020-08-24 17:35:17 -07:00
Philip Rideout
fe280c0c3b BUILDING.md, add Windows hints. (#2997)
* BUILDING.md, add Windows hints.

* Update BUILDING.md

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

* Update BUILDING.md

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

Co-authored-by: Ben Doherty <bendoherty@google.com>
2020-08-24 13:42:31 -07:00
Philip Rideout
86946acf08 Vulkan: log driver version info.
This is useful to see which version of MoltenVK is actually being used.
2020-08-24 10:16:25 -07:00
Philip Rideout
29bb48be09 Regenerate BlueVK. 2020-08-22 11:57:58 -07:00
Pixelflinger
a528c0367c cleanup gl context init 2020-08-21 19:46:28 -07:00
Philip Rideout
6d733091e0 Update our BlueVK generator and prep for new headers. 2020-08-21 16:46:05 -07:00
Philip Rideout
b656918c4d Update MoltenVK and its README.
LunarG stopped releasing tarballs for macOS, they use dmg files now.
2020-08-21 16:45:52 -07:00
Ben Doherty
d3c1964822 Fix IBL loading bug with missing cubemap levels (#2986) 2020-08-21 16:07:22 -07:00
Philip Rideout
cf6c518aea FrameGraph: add graphviz labels for size and MSAA. 2020-08-21 11:26:15 -07:00
Ben Doherty
af2fc39bad Add JNI bindings for CSM (#2979)
* Add JNI bindings for CSM

* Fix Windows build

* Fix jovadoc
2020-08-21 10:21:31 -07:00
Philip Rideout
83b35e5ac2 Refraction: enable SUBPASS usage flag.
This was causing a Vulkan error when refraction was enabled.
2020-08-21 09:38:35 -07:00
Pixelflinger
67030982ec minor improvements and cleanups
- more flexible linearization of depth, doesn't impact performance
  at all in the shader, but takes into account 3 parameters of
  the projection matrix instead of true. Mathematically identical
  to before.

- use depth test "less or equal" for depth only passes to be consistant
  with the color pass. Unsure if using "less" would be better.

- use textureLod() when sampling the skybox

- use mediump for all samplers in the shadowing.fs, which correspond to
  their actual definition.
2020-08-21 09:34:38 -07:00
Pixelflinger
0aea56e22d slightly improve the depth_test
we just make the output more readable
2020-08-21 01:39:08 -07:00
Philip Rideout
9c7a8fef24 Fix Windows build. 2020-08-20 10:16:11 -07:00
Philip Rideout
5b0e01329a Vulkan: add very simple cache of VkImageView.
Filament calls createRenderTarget very frequently, so this PR has the
side effect of reducing a huge amount of create-destroy churn in other
Vulkan objects such as VkRenderPass and VkFramebuffer.
2020-08-20 09:39:33 -07:00
Philip Rideout
7950b83b58 Vulkan: fix leak of VkRenderPass objects. 2020-08-19 18:39:22 -07:00
Benjamin Doherty
af99270aaa Fix another VSM shader error 2020-08-19 14:08:18 -07:00
Ben Doherty
76fe0e36fb Fix VSM shader error (#2975) 2020-08-19 14:05:12 -07:00
Pixelflinger
4e3bb9c7c8 fix translucent views with custom render targets
Marking a view with a custom render target will now disable blending
for that view but require an alpha channel for intermediate buffers.
Blending is disabled because it is meaningless.

fixes #2802
2020-08-19 11:55:13 -07:00
Ben Doherty
3e5d9fa0b4 Add VSM shader changes (#2971) 2020-08-19 10:56:48 -07:00
Philip Rideout
331d7c3e00 Repair Vulkan after vkalloc upgrade. 2020-08-18 11:15:25 -07:00
Philip Rideout
345455cf24 Update vkmemalloc. 2020-08-18 11:12:26 -07:00
Romain Guy
29a33ef215 Fix formatting error 2020-08-18 10:29:44 -07:00
Philip Rideout
7ca281d2b9 Expose ShadowOptions to JS, fix #2958. 2020-08-18 09:44:55 -07:00
Ben Doherty
ce37315ef9 Add new lightPosition uniform (#2969) 2020-08-17 18:01:24 -07:00
Ben Doherty
d3e3974179 Add new shader variants for VSM (#2968) 2020-08-17 18:00:01 -07:00
Ben Doherty
785c11a240 Metal: resolve MSAA textures to correct level / slice (#2967) 2020-08-17 12:46:42 -07:00
MorphTail
4dfc78674d Add documentation for cmgen (#2966)
* Create cmgen README

* add more description for --size attribute

resolve #454

* Update README.md
2020-08-17 11:50:59 -07:00
Philip Rideout
1c726fcef6 DriverAPI sample count should be > 0.
For single-sampled textures we were using 0 in some places and 1 in some
places. It's better to be consistent.
2020-08-14 14:49:03 -07:00
Philip Rideout
897593a8ed Vulkan: fix bad shadow map boundaries.
This fixes the long-standing "black rectangle" issue in our shadowtest
sample.

We were mistakenly constraining the clear to the viewport, which
is meant only to affect the vertex pipeline.

Also, we were needlessly setting the scissor rect in BeginRenderPass(),
since we already do so in Draw().
2020-08-14 12:12:24 -07:00
Pixelflinger
4f58be1ef1 minor micro optimizations 2020-08-13 23:44:38 -07:00
Ben Doherty
003911f0ec Set the model matrix and projection separately for shadow cameras (#2951) 2020-08-13 15:07:23 -07:00
Ben Doherty
de377c8e37 Apply clipspace fixup in GLSLPostProcessor (#2950) 2020-08-13 12:14:29 -07:00
Romain Guy
bf59b04ad0 Update release notes. 2020-08-13 11:20:01 -07:00
Ben Doherty
d14e29d4d3 Audit material variants (#2948) 2020-08-13 10:58:27 -07:00
Pixelflinger
afaac3f18c Allow color-gradding-as-subpass with TAA
while support for this is added, this is disabled because
it is actually ~0.5ms slower on qualcomm devices.
2020-08-12 22:25:10 -07:00
Philip Rideout
68c647abdb Metal: use explicit shader fixup for clip space Z.
This is more similar to the Vulkan shader pipeline and less magical.

There are 3 places in our shader code where we perform fixups like this:

- main.vs
- depth_main.vs
- post_process_getters.vs

That last one needs no change since it does not involve Z.
2020-08-12 21:12:42 -07:00
Pixelflinger
7852a9b8cb Add public APIs for texture 3D and texture 2D arrays
Also cleanup all setImage() error reporting. All error checks are
changed from silent to NON_FATAL_ASSERT, which means they'll throw
if exceptions are enabled or do a no-op and log a message otherwise.

Also added more precondition checks.
2020-08-12 17:32:46 -07:00
Philip Rideout
acdb8addfd Vulkan: enforce constraints for scissor / renderArea / blit. 2020-08-12 16:55:18 -07:00
Ben Doherty
faa785f3f6 Switch to C++17 (#2940) 2020-08-12 15:21:39 -07:00
Philip Rideout
a0a8d62587 Vulkan: fix rotation on Android. 2020-08-12 13:25:08 -07:00
Pixelflinger
681f8fae2e fix incorrect assert in GL backend
Fixes #1966
2020-08-12 12:54:18 -07:00
Philip Rideout
4d48cac0aa Vulkan: fix regression with window resizing. 2020-08-12 10:31:37 -07:00
Richard Chang
4d51042170 Add back proguard file for Android (#2933)
* Add back proguard file for Android and update README.md

The proguard-rules.pro file provided by Jeff McGlynn (9fe60a636)
works perfectly for Android projects with minifyEnabled.
Add the config file back to the repository and update README.md
to help other Android users setup release build.

* Refine android proguard file and remove proguard section in README.md
2020-08-12 10:08:53 -07:00
Philip Rideout
2dec7f7996 Fix Windows build. 2020-08-11 18:29:52 -07:00
Philip Rideout
0b653273dc Vulkan: fix zealous frame skipping on Android.
The stride passed to Vulkan for query pools is the stride between
queries, not the stride between individual values. I realized this after
seeing the SwiftShader implementation of queries.

I also used log statements to confirm that this fixes bogus frame
skipping on my Pixel 4.
2020-08-11 16:52:07 -07:00
Philip Rideout
b45d45048c Vulkan: fix Android after pause / resume.
This fixes the visual hang that would occur after going to the task
switcher and back.

After recreating the swap chain, all of its associated fences and sync
objects become invalid. Since we were not tracking this, FrameSkipper
was going into an infinite wait after the swap chain was created.
2020-08-11 16:51:45 -07:00
Philip Rideout
fb8c51c5e1 Fix resizing issues with MoltenVK.
This removes the old getClientExtent stuff that I added a while back,
and replaces it with the strategy espoused by the MoltenVK author found
here:

https://github.com/KhronosGroup/MoltenVK/issues/428

I tested this PR on macOS with Vulkan and Metal. I tested both on high
and low DPI displays. I also tried dragging the window between the two
displays.

Android still has issues with rotation, I will deal with that next.

cleanup
2020-08-11 16:51:23 -07:00
Pixelflinger
6a47924482 make use of textureLodOffet where appropriate
this really makes the code easier to read and has a chance to be
more efficient
2020-08-11 10:39:56 -07:00
Philip Rideout
8fdcd8fa62 Vulkan: allow blit to default render target.
This fixes a null pointer exception that we saw after disabling several
View -process effects.
2020-08-11 09:24:29 -07:00
Philip Rideout
6b6f80562f Vulkan: add null checks for Molten. 2020-08-11 09:24:29 -07:00
Pixelflinger
08e411aeac API CHANGE: make ssao options work like all other options
setAmbientOcclusion (and associates) is now deprecated (but still works),
in favor of the new .enabled field in AmbientOcclusionOptions.
2020-08-10 17:23:03 -07:00
Pixelflinger
b3c57a4ee1 add TAA controls in material_sandbox 2020-08-10 13:30:05 -07:00
Pixelflinger
0947f80974 TAA: tweak quality parameters for mobile
on mobile we only use the variance box instead of
min/max+variance, this saves a few hundred us.
2020-08-10 11:14:34 -07:00
Pixelflinger
8155bf04a8 Implement variance clamping
variance clamping further shrinks the min/max AABB
2020-08-10 11:14:34 -07:00
Pixelflinger
815483c5e0 execute structure pass before TAA
This fixes a lot of flickering when SSAO and TAA are enabled.
SSAO TAA shouldn't be done based on a jittered depth buffer, but
rather on jittered samples.
2020-08-10 11:14:34 -07:00
Pixelflinger
05bfa632ff Add TAA java bindings 2020-08-10 11:14:34 -07:00
ruitaocc
931daf3a69 fix typo 2020-08-10 08:58:24 -07:00
Pixelflinger
4821a95f16 Implement basic tamporal antialiasing (TAA)
while this started as a sample to demonstrate how to use the new
frame history feature, this is now solid enough to become a feature.

this version of TAA doesn't use motion vectors, so it is prone to
various artifacts (e.g. ghosting). It also has the typical issues
TAA has (e.g. transparents).

with that said, performace is good and quality is overall superior
to FXAA or MSAAx4.
2020-08-07 20:51:46 -07:00
Romain Guy
4c0a5b5f1d CMake cleanup 2020-08-07 14:21:27 -07:00
@roxlu ☾
4ba95428c2 New options that allow you to specify the buffer sizes. (#2925)
* New options that allow you to specify the buffer sizes.

* Removed debug info

* Style/location fixes
2020-08-07 14:17:44 -07:00
Philip Rideout
732a6c08de Add Texture getters to IndirectLight and Skybox.
Fixes #2851.
2020-08-07 11:49:24 -07:00
Romain Guy
0584cea125 Update website 2020-08-07 11:02:38 -07:00
Romain Guy
058c9cd28b Update docs 2020-08-07 10:55:11 -07:00
Romain Guy
2ce3b88a13 Fix ccache scripts 2020-08-07 09:03:51 -07:00
Philip Rideout
c7c1c01a0e JavaScript: fix typo in clearAssetCache. 2020-08-06 16:47:29 -07:00
Philip Rideout
827e73b682 JavaScript: add clearAssetCache helper. 2020-08-06 16:41:35 -07:00
Philip Rideout
7ada8372f2 gltf_viewer: fix ColorGrading leak. 2020-08-06 15:12:53 -07:00
Philip Rideout
749a4d01af gltfio: fix some small memory leaks.
This fixes two oversights in the FilamentAsset destructor:

- Destroy the faux root Entity.
- If it exists, remove the name component from each Entity.
2020-08-06 15:12:53 -07:00
Philip Rideout
f4004cf047 JavaScript bindings: fix a frequent 4-byte memory leak.
In retrospect, I should've exposed ints to JS instead of entities.
Making this fix is already a TODO, but it will be a tedious change. For
now, this PR fixes two issues that were causing tiny but frequent memory
leaks, according to the emscripten memory leak widget.

(1) Do not include Entity in the list of classes that should only be
passed around by pointer.

(2) Clients should always call delete() on returned Entities.
2020-08-06 14:45:28 -07:00
Philip Rideout
dc74ee2ddc Refactor CallbackUtils. 2020-08-05 17:27:12 -07:00
Philip Rideout
2727cddd7a TextureHelper: add overload with a release callback.
Fixes #2909.
2020-08-05 17:27:12 -07:00
Pixelflinger
4f239c3e3c fix a moveResource which was broken recently
a recent fix actually badly broke moveResource, we were using the
index of the newly created resource instead of the pass index.
2020-08-05 13:10:16 -07:00
Philip Rideout
4bf0d0c0a8 Web: Remove broken webpack example.
This example has fallen out of date, I tried to resurrect it but it
turned out to be non-trivial, given the special nature of emscripten's
generated JavaScript wrappers.

It might be better to provide an example that uses rollup, since that's
the bundler that model-viewer uses, or a simple TypeScript example.

For now, I think our simple HTML + raw JS samples are sufficient.
2020-08-05 11:19:08 -07:00
Pixelflinger
d70f1c0ab2 Infrastructure for frame history data
We can now save an arbitrary (but decided at compile time) number of
entries containing information about previous frames and it for while
drawing the current frame. Typically this is used for such effects as
TAA, screen-space reflection, building probes over time, etc...

Currently the frame history consists of one frame per View. FView 
provides a new (internal) getFrameHistory() method used to access
previous frames entries as well as to save the current's frame
information.

The FrameGraphPassResources (which is available in the execute closure
of a FrameGraph pass) has a new detach() method which can be used to
remove that resource from the FrameGraph lifetime management, at which
point it becomes the responsibility of the caller. Typically this
resource will be stored in the frame history.
2020-08-04 15:01:09 -07:00
Pixelflinger
991861a512 make fg resources creation/destruction more generic
creation/destruction now takes a ResourceAllocatorInterface instead of
a FrameGraph.
2020-08-04 15:01:09 -07:00
Pixelflinger
d0367a359b move ResourceAllocator out of the fg namespace 2020-08-04 15:01:09 -07:00
Mathias Agopian
d2be23045f fix a FG crasher when we have more than 32 passes (#2911)
The FrameGraph cannot store pointers internally because all objects
are stored in vectors. Unfortunately we were storing the writer of
resources as a pointer. 

This is fixed by storing an index instead.
2020-08-04 15:00:38 -07:00
Ben Doherty
4cb903a09e Fix variant-limiting bug in matdbg (#2903) 2020-08-03 11:16:33 -07:00
Philip Rideout
3ca0a8cd8d Transmission should use FADE. (#2908)
Fixed #2907.
2020-08-03 10:51:26 -07:00
Philip Rideout
2c18d7f576 Revert "Transmission should use FADE."
This reverts commit 379f92417f.
2020-08-03 10:45:46 -07:00
Philip Rideout
379f92417f Transmission should use FADE.
Fixed #2907
2020-08-03 10:44:15 -07:00
Ben Doherty
13574f793c Run MergeReturnPass only on mobile (#2901) 2020-07-31 18:40:47 -07:00
Ben Doherty
f69ba63046 Don't crash for invalid Metal programs when using matdbg (#2902) 2020-07-31 18:39:57 -07:00
Pixelflinger
a13620c66d reorganize material folder
Sets of post-process materials are in their own folder now.

Also moved fxaa.fs from shaders/ to materials/ so it's next to the 
material that includes it. This file is not shared with any other
material.
2020-07-31 10:36:44 -07:00
Pixelflinger
b4a35c3ee2 fxaa: highp precision seems overkill 2020-07-30 23:46:09 -07:00
Ben Doherty
a4e3e0c2d1 Ignore commented-out #includes in material files (#2897) 2020-07-30 18:46:16 -07:00
Ben Doherty
1a85c93894 Fix DEBUG identifier used in Log.h (#2895) 2020-07-30 16:43:42 -07:00
Philip Rideout
2c114a9a9f Add mask smoothing to the unlit path. 2020-07-30 15:14:46 -07:00
Philip Rideout
f4d8753c24 MASKED mode now leaves destination alpha intact.
This prevents strange behavior with semi-transparent render targets,
which the model viewer team discovered when testing against the Khronos
alpha test conformance model.
2020-07-30 15:14:46 -07:00
Ben Doherty
6f28da4798 Fix Podspec for 1.8.1 (#2894) 2020-07-30 13:54:12 -07:00
Philip Rideout
a6390355da Fix typos. 2020-07-30 13:50:51 -07:00
Romain Guy
a120e0a4bb Filament 1.8.1 2020-07-30 12:25:53 -07:00
Romain Guy
642fb5859b Filament 1.8.1 2020-07-30 12:18:38 -07:00
Philip Rideout
b4623c9afc Add lightroom IBL, enable ColorGrading by default in gltf_viewer.
The non-legacy ACES is now default, it looks much better.

I also tested this IBL with WebGL and Android.
2020-07-30 11:39:36 -07:00
ruitaocai
c4546f1777 fix typo (#2892) 2020-07-29 22:46:50 -07:00
Pixelflinger
ea5e8c2d14 fix refraction roughness when specular AA is active 2020-07-29 16:36:24 -07:00
Philip Rideout
440687e05a Add JavaScript bindings for Fog and Vignette. 2020-07-29 15:01:05 -07:00
Mathias Agopian
bd30abb168 attempt to reduce code size in PostProcessManager (#2880)
* attempt to reduce code size in PostProcessManager

The two main changes are:
- materials are now stored in a hash map which allows us to
  automatically destroy all of them using one loop -- instead of
  having to call terminate() for each of them.

- factored a very common sequence of code:
  commit()
  use()
  beginRenderPass()
  draw()
  endRenderPass()

  This makes the code easier to write and also results in less code.

There are also minor other changes, e.g. RenderPass constructor is not
inline anymore.
2020-07-29 13:01:23 -07:00
Pixelflinger
d15a906855 multithread the conversion to RGB10_A2
we just move the conversion code into the already existing jobs.
2020-07-29 12:59:55 -07:00
Philip Rideout
7584a7bebe Merge pull request #2885 from google/pr/jscolorgrading
WebGL: use color grading in demo, expose destroy.
2020-07-29 12:22:11 -07:00
Philip Rideout
8f3f30e9cd gltfio: fix depth writes for transmissive materials.
This fixes the depth fighting in the column of red spheres in the test
model while in filamat mode. Thanks Romain for catching this.

It also makes filamat mode more consistent with ubershader mode.
2020-07-29 11:55:21 -07:00
Philip Rideout
664e7b8a8d ColorGrading: add JavaScript and TypeScript bindings.
This is not tested but seems fairly straightforward.
2020-07-28 14:45:51 -07:00
Philip Rideout
aa5f88ae0f WebGL: Add workaround for skinning with Emscripten.
So...we use integers for bone indices, and that makes them special. :)

On May 26, the emsdk WebGL 2.0 wrapper for the integer variant of
VertexAttribPointer was broken due to an incomplete renaming operation
from an emscripten contributor.

I have a pending upstream fix to the emscripten repo (#11742) but for
now we can workaround this with a simple monkeypatch.

Fixes #2856.
2020-07-28 09:21:27 -07:00
Pixelflinger
6f5e04d489 enforce correct type with printf-style logs 2020-07-27 14:06:48 -07:00
Ben Doherty
2113c9a3be Fix Metal crash when >16 samplers are bound (#2873) 2020-07-27 13:18:13 -07:00
Pixelflinger
b0d4934d02 Add validation for Texture::setImage()
We now validate supported combinations of internalFormat vs. format/type.
We currently follow the GLES specification, but we could be more 
restrictive if needed for vulkan/metal.

The validation terminates in debug builds and logs (and becomes a no-op)
in release builds.
2020-07-27 11:22:41 -07:00
Philip Rideout
2f4dd0bbd4 sample-page-curl: add comments to variables, etc. 2020-07-27 07:35:58 -07:00
Pixelflinger
e34db6fc29 fix a few issues with color grading
- we were not clamping the color grading output to [0,1]

- we were not using a supported input (cpu) pixel format for the
  3d LUT in low and medium quality
2020-07-24 17:24:51 -07:00
Pixelflinger
087e2480d1 DoF: fix tiles dilate pass edges
We were using texelFetch which doesn't handle wrap modes, and this
resulted in all edge tiles to be undefined. Use textureLod() instead.
2020-07-24 11:38:26 -07:00
Ben Doherty
45efe2df75 CSM: allow setting individual split positions (#2835) 2020-07-24 11:04:28 -07:00
Ben Doherty
85ae21fa26 Remove Google-style line directives in filamat lite (#2860) 2020-07-24 11:04:01 -07:00
Pixelflinger
77939ad269 DoF: improve quality in "fast tiles"
fast tiles (i.e. where all pixels have the same circle-of-confusion)
are allowed to use bilinear filtering.
this results in better looking DoF in these areas.
2020-07-23 22:49:13 -07:00
Tim Psiaki
4a59e6e1ce Fix node hierarchy corruption when a node is set to parentless. 2020-07-23 22:48:40 -07:00
Pixelflinger
ca68ef22e1 update glslang to latest
glslang repo SHA: f3cb1896971f449706bb1df5053d0e8fad6b0675


This fixes another highp bug.
2020-07-23 16:11:14 -07:00
Pixelflinger
7067500a9c DoF: improve quality
Using a ring density of 4 was wrong -- apparently I can't add.
With a density of 8 we can guarantee we don't have gaps between samples
when using mips properly (or at least gaps are consistant and 
predictable).
2020-07-23 13:52:24 -07:00
Romain Guy
6ed1fb3b7b Add quality option to ColorGrading (#2858)
* Add quality option to ColorGrading

Low: 16x16x16 LUT in 10 bit
Medium: 32x32x32 LUT in 10 bit
High: 32x32x32 LUT in 16 bit
Ultra: 64x64x64 LUT in 16 bit

* Move comment
2020-07-23 13:49:01 -07:00
Romain Guy
1613c1bb0e Ensure we respect the desired size on layout change (#2859) 2020-07-23 12:45:02 -07:00
Richard Chang
1162ae4ddc Fix typo in SurfaceOrientation jni wrapper (#2853) 2020-07-23 09:06:26 -07:00
Ben Doherty
a25179b91e Update imgui to v1.77 (#2834) 2020-07-22 16:15:31 -07:00
Pixelflinger
81388ab4b4 DoF: bug fixes and quality improvements
- Use the random offset to calculate the correct intersection radius.
  For the center sample, the ring radius is otherwise zero, which means
  any sample in the random disk with a CoC radius > 0 would intersect,
  and that seems wrong.

- The selected mip was off by one.
  We were always picking a mip too high because the CoC are in
  high resolution, but our mip-chain is 1/4 res from that.
  This improves rendering quality quite a lot.
2020-07-22 15:22:28 -07:00
Pixelflinger
ec9fd58fc0 use more inclusive language 2020-07-22 15:20:54 -07:00
Ben Doherty
b786b486b6 Add getCullingProjectionMatrix JNI method (#2847) 2020-07-22 15:12:03 -07:00
Romain Guy
06b191cd53 Fix broken IBLs (#2850) 2020-07-22 14:02:49 -07:00
Philip Rideout
cd168148d8 gltfio for web: add and use destroyAsset.
Fixes #2839.
2020-07-22 13:40:08 -07:00
Philip Rideout
0da20cccdc Introduce removeEntities API / fix leak in ModelViewer (!)
For testing purposes, sample-gltf-viewer reloads the model when the
user double-taps the screen. This operation was causing a buildup of
blank entities in the Scene, because we were merely destroying the
components, not removing them from the Scene.
2020-07-22 13:38:38 -07:00
Aleksi Sapon
ecbdeb9e6d Remove case KtxBundle::R11F_G11F_B10F in toPixelDataFormat 2020-07-22 13:20:54 -07:00
Aleksi Sapon
e14c8258f7 Fix KTX texture format for latest version 2020-07-22 13:20:54 -07:00
Philip Rideout
3862b44ef4 gltfio: Add support for KHR_materials_transmission.
This chooses type=THIN, mode=SCREENSPACE, and blending=TRANSPARENT.

Due to sampler overload, we print a friendly error message and enable a
fallback if the user tries to simultaneously enable ubershader mode, the
clearcoat extension, and the transmission extension.
2020-07-22 08:40:55 -07:00
Romain Guy
f3ed31b5a0 Don't recompute the color grading LUT every frame in sandbox 2020-07-20 17:08:22 -07:00
Romain Guy
06f4920033 Don't recompute color grading LUT on every frame 2020-07-20 16:56:26 -07:00
Ben Doherty
b0c11c17e9 Add outputs block to material definition (#2823) 2020-07-20 16:48:00 -07:00
Pixelflinger
27c4174abd DoF: fix many quality/performance issues
- make sure all downsampling is exactly correct and use proper
  uv values to access these textures. This stabilizes the DoF a bit.

- for now only use NEAREST filtering, as bilinear can't be used naively.

- noise is now mandatory, fix noise radius

- add a median pass (performance is not impacted because DoF is faster
  due to using NEAREST filtering)

- fix  be consistant in how the kernel radius is computed, fix a couple
  errors in that area.

- change ring density from 8 to 4 (but starting with 8), so each new
  ring is 4 samples larger than the previous. This reduces the number
  of samples needed from 25 to 21 on mobile, and 49 to 37 on desktop. 
  It also makes it conceivable to use 5 rings (57 samples). Quality is
  not visibly impacted because the center ring is still 8 samples.
  This density, matches the number of samples required for "square"
  rings.

- fix scaling issue with diaphragm simulation

- fix typos in background accumulation code -- this fixes a lot of 
  quality issues.

- improve performance of "fast tiles" during both DoF and combine passes

Overall the effect runs about 0.5ms faster and quality is greatly
improved.
2020-07-20 12:58:11 -07:00
Philip Rideout
71f256585d Update cgltf (includes transmission ext). 2020-07-20 12:04:51 -07:00
Pixelflinger
710f83dcf5 Enable specular anti-aliasing in gltfio 2020-07-19 22:14:51 -07:00
Mingwei Samuel
36b3cc7bf0 Filament.d.ts: add Vector<T> interface, vectorToArray<T> fn, fix getResourceUris() return vec 2020-07-18 10:50:44 -07:00
Romain Guy
c6d9d4a9ae Update AGP, NDK and androidx.core (#2826) 2020-07-17 09:24:33 -07:00
Philip Rideout
665b198db0 Vulkan: add support for subpasses. 2020-07-15 17:39:29 -07:00
Philip Rideout
9f267de1b7 Fix garbage in "Exceeded max sampler" message.
uint8_t is char, so it makes junk on the screen and wakes up your dog
with beeping sounds.
2020-07-15 13:54:56 -07:00
Pixelflinger
5c71b0eae2 update glslang to latest
This fixes a lot of issues regarding precision qualifiers.

This should resolve cases where "highp" were introduced needlessly.
2020-07-14 23:24:50 -07:00
Pixelflinger
e58043f156 update spire-cross to latest
This fixes an issue where "expensive" operations can be moved to
inside loops.
2020-07-14 23:24:31 -07:00
Philip Rideout
c6a8ad9fbe Refactor colorGradingSubpass to fix #2780. 2020-07-14 19:25:43 -07:00
Romain Guy
97e8035b40 Give materials unique names 2020-07-14 15:57:56 -07:00
Philip Rideout
1d474b30b9 Add simple subpass support to the Driver API.
This makes two changes to the Driver API:
1. Adds the beginSubpass() method.
2. Adds subpassMask to RenderPassParams.

Locally I've proven that this PR is sufficient by making a series of
Vulkan changes; sneak peek is available at commit
bfef6914a7d288bbd25926c02ec93d231a8c0d07.

Note that this PR moves the new usage flag to a different texture;
I had placed it on the wrong one.

See also #2780.
2020-07-14 14:48:24 -07:00
Romain Guy
4c81bb0158 Fix material parameters enum (#2814)
* Fix material parameters enum

Fixes bug #2812

* Add  missing sampler type to filamat
2020-07-14 09:29:20 -07:00
Mingwei Samuel
a2e5cacee0 Filament.d.ts: Add BufferReference type alias, update to accept typed arrays
- buffers processed by getBufferDescriptor can be an asset string or JS typed array.
  - 185ed0cc68/web/filament-js/extensions.js (L17-L27)
2020-07-13 20:56:12 -07:00
Ben Doherty
7cfc2c9f24 Set Filament iOS support to iOS 11 (#2809) 2020-07-13 18:04:47 -07:00
Ben Doherty
fec214a772 Include Filament version instead of date in release assets (#2808) 2020-07-13 17:23:36 -07:00
Philip Rideout
6eac638fd2 Remove old method for JS doc generation.
The new way is to follow the instructions at the top of
`web/docs/build.py`.

The option in build.sh has been unused for a while. Invoking Python from
CMake was pointless, especially since I don't want to force other
developers to install a specific version of Python etc.
2020-07-13 16:07:49 -07:00
Philip Rideout
dc891f7299 CMake: specify -fPIC at root level.
Fixes #1881.
2020-07-13 16:07:07 -07:00
Ben Doherty
7c4661cc6b Fix glTF camera aspect ratio (#2807) 2020-07-13 14:42:26 -07:00
Ben Doherty
c7b6d45958 Add CocoaPods tutorial to site (#2798) 2020-07-13 14:41:56 -07:00
Max Rebuschatis
c0bf8fa83b NoopDriver now uses ShaderModel::GL_ES_30 on WASM 2020-07-13 13:39:53 -07:00
Philip Rideout
4fa987c698 WebGL: Upgrade emsdk and refactor initialization.
Since postRun can no longer be set from within the extern post JS, we
now use the promise rather than postRun.

This upgrades emsdk to 1.39.19 (see note in #2800).
2020-07-13 13:02:26 -07:00
Philip Rideout
ec533e6047 DriverEnums: add usage flag for SUBPASS_INPUT 2020-07-11 09:22:28 -07:00
Pixelflinger
bdf1272942 update comments to reflect code change 2020-07-11 01:03:20 -07:00
Benjamin Doherty
2e8a80f726 Fix, add xcsharedata for HelloCocoaPods sample, removal MetalKit 2020-07-10 18:00:57 -07:00
Ben Doherty
2516484566 Add HelloCocoaPods iOS sample (#2795) 2020-07-10 17:05:54 -07:00
Ben Doherty
c91d02ab29 Add bluevk.lib to Windows README (#2796) 2020-07-10 13:16:45 -07:00
Philip Rideout
41f7ea436d Update the descriptor set index in colorGrading. 2020-07-10 10:19:06 -07:00
Romain Guy
b224916f09 Prevent crash if the glTF doesn't have animations 2020-07-09 17:23:06 -07:00
Philip Rideout
38d2509aaf Web tutorials now use a CDN for the npm package.
This makes the tutorials more consistent with the live demos and lets us
more easily ensure that the tutorials are kept up to date without
errors. In fact it caught an error in the Suzanne tutorial.

Since this affects source rather than served files, this PR is intended
for main.  The master branch will be updated in a subsequent PR.
2020-07-09 14:56:05 -07:00
Ben Doherty
185ed0cc68 Add Filament Podspec (#2788) 2020-07-09 12:43:24 -07:00
Philip Rideout
5d2b12b9a6 Fix javadoc syntax error. 2020-07-09 12:12:41 -07:00
Romain Guy
77aec40a56 Prepare Filament v.1.8.0 (#2787) 2020-07-09 11:44:15 -07:00
Philip Rideout
25d42c939d filagui: publicize the low-level draw data handler.
The existing API was fine for FilamentApp but it prevented clients from
making ImGui calls from arbitrary places, which forced them in some
cases to queue up their ImGui calls using vector<function<>>.

This PR publicizes the low-level method that consumes the ImGui draw
list and removes calls to global functions.
2020-07-09 11:31:36 -07:00
Philip Rideout
1ad6bccbc2 Vulkan: add support for input attachment descriptors.
This is step 1 for supporting subpasses (aka framebuffer fetch).

Vulkan requires us to explicitly bind the shader to any framebuffers
that we read from. These are called input attachments in Vulkan
parlance, and each binding is called a descriptor.

For simplicity we only create homogeneous descriptor sets where each
descriptor set is comprised of only one type of binding (i.e. all
uniforms or all samplers). I see no reason to break with that
architecture right now, so input attachments live in their own set.
In the long term, we should probably think about partitioning
descriptors differently (e.g. according to their frequency of change).

This PR also renames some internal fields in order to avoid nomenclature
confusion, such as `mDescriptorSets` => `mDescriptorBundles` . Each
entry in this map is a set of descriptor sets, or what we are now
calling a "bundle".
2020-07-09 11:26:06 -07:00
Ben Doherty
3c1ea07502 Add Metal support for Texture::import (#2782) 2020-07-09 10:39:22 -07:00
Philip Rideout
07e4d1c148 Fix TypeScript error for the Render Fidelity folks. 2020-07-09 07:49:22 -07:00
Pixelflinger
1816883428 Some infrastructure to support arbitrary shaped diaphragm
This is still work in progress and disabled.
2020-07-08 17:18:40 -07:00
Pixelflinger
6a6775ebec fix typo in IBL computation comment 2020-07-08 17:18:18 -07:00
Romain Guy
767764e4ff Swizzle textures when swizzle is enabled, not the other way around (#2779)
Fixes #2777
2020-07-08 13:33:09 -07:00
Philip Rideout
d3f6ce6990 Minor fixes for "matinfo --web-server" 2020-07-08 13:15:28 -07:00
Philip Rideout
96032eada5 Vulkan code cleanup. 2020-07-08 11:04:04 -07:00
Philip Rideout
c8aad378c4 Vulkan: add support for MRT. 2020-07-08 11:01:43 -07:00
@roxlu ☾
c067d76d1d Add View::getVisibleLayers() 2020-07-08 09:24:55 -07:00
Romain Guy
630f816e7a Remove iostream from GLX backend (#2774) 2020-07-07 11:29:12 -07:00
Ben Doherty
bbf37a5480 Add error message when parsing material with missing backend (#2766) 2020-07-06 11:29:01 -07:00
Ben Doherty
a07894ca9f Fix gltf_viewer crash when switching models with glTF cameras (#2767) 2020-07-06 11:28:36 -07:00
Mingwei Samuel
e03c663bc3 filament.d.ts make init, fetch callbacks optional 2020-07-04 09:20:51 -07:00
Ben Doherty
1af254db43 Add matc support for command-line preprocessor defines (#2760) 2020-07-01 10:42:46 -07:00
Philip Rideout
7621f7e830 Vulkan: fix SSAO by removing bogus workaround.
This fix has the side effect of causing a validation warning due to
a declared fragment shader output that has no corresponding attachment.
We can fix that in a future PR.

Fixes #2752
2020-06-30 16:59:03 -07:00
Philip Rideout
d7cd247dfc matdbg: auto-select variant when clicking a material.
The UI was in a weird state after the user selected a new material but
before they had chosen a particular variant. The highlighted
material did not match the content of the source editor.
2020-06-30 16:56:19 -07:00
Philip Rideout
9a58bf2460 matdbg: support scenes that have many materials.
We now download shader source only after the user selects a variant.
Previously we tried to download all shaders at once. This caused Chrome
to throw ERR_INSUFFICIENT_RESOURCES.

Fixes #2759
2020-06-30 16:56:19 -07:00
Philip Rideout
7ee1279792 Vulkan: add diagnostics to check if format is sampleable.
Motivated by #2752.
2020-06-30 12:43:45 -07:00
Ben Doherty
7131bbf62c Fix VS 2019 build failure with Vulkan (#2758) 2020-06-30 11:29:00 -07:00
Michael Lou
820f551eea filamat: Resolve string processing inefficiency (#2754)
Co-authored-by: Michael Lou <ylou@amazon.com>
2020-06-30 10:39:31 -07:00
Ben Doherty
a6872c840c Silence more deprecation warnings (#2750) 2020-06-30 10:14:57 -07:00
Philip Rideout
c0452b5e9d JS: Update API for Camera construction / destruction. 2020-06-29 18:35:24 -07:00
Philip Rideout
b136b4aca5 JS: Temp workaround for bloom binding error. 2020-06-29 18:35:24 -07:00
Philip Rideout
59cf9e3b75 JS: Fix typo in bindings for bloom options. 2020-06-29 18:35:24 -07:00
Pixelflinger
7ca508cb7a ssao: optimize sin/cos per sample
We now get away with a sin/cos per fragment instead of per-sample,
this increases a little bit the ALU load but decreases the EFU's.
This is not necessarily faster, but sin/cos may cost more power or
have longer latencies.
2020-06-29 17:46:53 -07:00
Philip Rideout
96feea1dee Avoid deprecated API in the root README. 2020-06-29 15:12:52 -07:00
Philip Rideout
c5acacff67 Vulkan: add note about #1532. 2020-06-29 12:36:47 -07:00
Ben Doherty
92f2004c4b Improve matc error reporting (#2741) 2020-06-29 11:21:56 -07:00
Pixelflinger
aed8c7fcb4 DoF: make all function parameter const
glslang generate much less code when function parameters are marked
const (it also works around a bug where highp intermediate variables
are introduced -- but this will be fixed soon).

Also remove non-trivial uses of ?: as it also triggers a similar problem 
in glslang.
2020-06-29 10:45:08 -07:00
Philip Rideout
29f50e0feb Vulkan: fix intermittent InvalidQuery on Android.
This prevents the following validation error:

    Cannot get query results on queryPool 0x2 with index 0 as data has
    not been collected for this index.

This was occasionally triggered when we attempted to query a timer that
had not yet been inserted into any command stream. (The error seems
bogus to me since we've enabled the AVAILABILITY flag, but we might as
well fix it anyway.)
2020-06-28 04:43:06 -07:00
Romain Guy
2aeb33b260 Fix Windows build 2020-06-26 23:20:23 -07:00
Romain Guy
132e94b3bb Add vignette post-processing effect (#2743)
* Add a vignette post-processing effect

* Use numeric limits instead of hard coded values
2020-06-26 17:44:17 -07:00
Romain Guy
f7f86a7c56 Remove skygen
This will be replaced by a runtime implementation. skygen was
never finished to begin with.
2020-06-26 17:25:08 -07:00
Ben Doherty
4a3984692a Flush pending command buffer in Metal terminate (#2737) 2020-06-26 11:38:56 -07:00
Philip Rideout
c87cffd57a Transition to PRESENT layout only once per frame. 2020-06-25 19:50:34 -07:00
Philip Rideout
4bbc0c05c4 Allow LOAD_OP_LOAD when rendering to swap chain. 2020-06-25 19:50:34 -07:00
Philip Rideout
697b1b6907 Fix intermittent InvalidImageLayout error for main depth buffer. 2020-06-25 19:50:34 -07:00
Mathias Agopian
d3f5164fcb New DoF implementation (#2700)
This implementation is an order of magnitude more efficient, running
in about 6ms on Pixel 4.

We're using the ring binning technique described in "Life of a Bokeh",
SIGGRAPH 2018.
2020-06-25 16:37:16 -07:00
Pixelflinger
8882132f43 fix a use after free in filamat
This would happen when using math -E -a vulkan. GLSLangCleaner lifetime
must be shorter than TProgram/TShader.
I think we can fix this by using another scoped GLSLangCleaner.

Tested successfully with ASAN.
2020-06-25 12:20:16 -07:00
Ben Doherty
89a8592714 Fix, incorrect camera view matrix with non-rigid transformations (#2735) 2020-06-25 11:22:09 -07:00
Philip Rideout
9d35aff2d3 Vulkan: fix bloom on Android by supporting LOAD_OP_LOAD.
If a render target attachment is not cleared or discarded, then it
should be preserved and therefore requires VK_ATTACHMENT_LOAD_OP_LOAD.
2020-06-24 22:33:57 -07:00
Romain Guy
c6e7382cb9 Update README.md 2020-06-24 16:30:23 -07:00
Mingwei Samuel
0be094cd4f Update TypeScipt declarations
- Add missing LightManager$Builder methods.
- Fix IcoSphere.tangents type to be unsigned.
- Add missing IcoSphere.suvdivide() method.
2020-06-24 15:37:15 -07:00
Ben Doherty
81c60c4efa Remove use of deprecated APIs in libfilamentapp (#2729) 2020-06-24 10:47:42 -07:00
Pixelflinger
456e057754 texelFetch w/ LOD requires at least MIPMAP_NEAREST
if NEAREST or LINEAR min filter is used, texelFetch is actually
undefined when the LOD is not 0.
2020-06-23 18:23:16 -07:00
Ben Doherty
ab12881888 Remove camutils dependency on utils (#2727) 2020-06-23 15:28:20 -07:00
Philip Rideout
efaf02ca61 CMake: fix macOS build break. 2020-06-23 15:19:04 -07:00
Philip Rideout
8f7b25088d CMake: build matdbg / civetweb only when enabled.
Also group FILAMENT_ENABLE_MATDBG with all our other CMake options.
2020-06-23 15:19:04 -07:00
Philip Rideout
8f4ffbc782 gltfio: various improvements to skinning normalization.
- Allow JavaScript and Java / Kotlin clients to configure this setting.
- Opt in by default (this was disabled in #2621)
- Optimize large assets like Bistro by iterating through prims only when
  the asset actually has skins.

Fixes #2714.
2020-06-23 13:30:45 -07:00
Mingwei Samuel
455bed917b Fix typescript missing options parameter for createTextureFromX 2020-06-23 09:25:44 -07:00
Ben Doherty
d5033b5857 Silence warnings in public headers (#2722) 2020-06-22 16:56:55 -07:00
Philip Rideout
cf5b6ccba3 Use MAX_MORPH_TARGETS instead of magic number. 2020-06-22 16:02:12 -07:00
Philip Rideout
42c80d5d5e Fix CUBICSPLINE interpolation for morph weights.
Tested with Polly the robo-hound and ensured that InterpolationTest
did not regress.

Partial fix for #2714.
2020-06-22 16:02:12 -07:00
Philip Rideout
2b92b5e060 gltf_viewer: move "Animation" UI
The Animation selector is now a top-level group (collapsed by default),
previously it was in the Hierarchy group, which was non-intuitive.

Also:

- Use indent() for consistency with other UI groups.
- Remove un-necessary usage of a lambda.
2020-06-22 15:43:35 -07:00
Ben Doherty
1762baab61 Remove unused SPIRV-Tools-shared library (#2719) 2020-06-22 14:30:43 -07:00
Ben Doherty
ab98548e75 Fix iOS projects build (#2718) 2020-06-21 22:31:12 -07:00
Ben Doherty
5e2c9e3aff Create universal libraries for iOS releases (#2717) 2020-06-21 19:43:03 -07:00
Ben Doherty
b8ece355d7 Install Filament LICENSE alongside README (#2712) 2020-06-19 18:10:27 -07:00
Ben Doherty
79fb878fb9 Update build instructions link (#2711) 2020-06-19 13:26:18 -07:00
Ben Doherty
026298182e Fix gltfio-java build errors on Windows (#2709) 2020-06-19 10:55:15 -07:00
Philip Rideout
a79effc78b Page Curl: fix CPU animation. 2020-06-18 19:38:41 -07:00
Philip Rideout
66471ee990 Page Curl: add configurable curl style. 2020-06-18 19:35:42 -07:00
Ben Doherty
1fc57b8bf0 Add bitcode to iOS builds (#2708) 2020-06-18 14:00:05 -07:00
Philip Rideout
6b5d21639e gltf_viewer: collapse all UI panels by default 2020-06-18 12:54:45 -07:00
Ben Doherty
d70e317065 Use local iOS toolchain instead of downloading (#2705) 2020-06-18 12:16:40 -07:00
Philip Rideout
a5c49cc1b6 Improve JS API for Scene::addEntities.
This repairs the `animation.html` sample. Using a JS array is more
natural for web developers and more consistent with the latest
JavaScript bindings in gltfio.
2020-06-18 12:16:01 -07:00
Philip Rideout
ce995d021a Improve JS API for SurfaceOrientation helper. (#2706)
* Improve JS API for SurfaceOrientation helper.

Web developers should not be expected to call malloc on the emscripten
heap. This new API is better aligned with how we handle vertex buffers.

Fixes #2702.

* Update web/filament-js/extensions.js

Co-authored-by: Wojciech Czerniak <wojciech.czerniak@gmail.com>

Co-authored-by: Wojciech Czerniak <wojciech.czerniak@gmail.com>
2020-06-18 12:02:02 -07:00
Ben Doherty
9cd2f2edc1 Check in pristine copy of Clang iOS toolchain (#2703) 2020-06-18 10:19:31 -07:00
Philip Rideout
5c64ed5125 gltfio: use highp for UV coords.
Fixes #2500.
2020-06-17 17:27:53 -07:00
Ben Doherty
623cd1a5f2 Remove PDB and ILK files when building for Windows CI (#2698) 2020-06-17 11:13:47 -07:00
Ben Doherty
94776a01b3 Add JNI bindings for gltfio camera (#2693) 2020-06-16 15:24:24 -07:00
Romain Guy
f462eafed0 Update workflows from master branch to main (#2697) 2020-06-16 13:40:34 -07:00
Romain Guy
7d1dbba2b4 Rename reference from master to main 2020-06-16 13:39:51 -07:00
Romain Guy
8c9cc988a6 Update references to master with references to main 2020-06-16 13:35:57 -07:00
@roxlu ☾
7a1d9968a7 Check if an existing material parameter is a sampler (#2694)
* Check if an material parameter is a sampler

* Rename hasSampler to isSampler
2020-06-16 13:32:23 -07:00
Romain Guy
56682794d3 Update getTime() documentation 2020-06-16 13:14:48 -07:00
Philip Rideout
87ee5783b7 export_graphviz() now includes name string. 2020-06-15 15:11:54 -07:00
Ben Doherty
7a1c079050 Use an int, not byte, for variantFilter (#2691) 2020-06-15 11:38:43 -07:00
Philip Rideout
242e8d1b56 Update live JS demos and tutorials.
At some point I should probably change the tutorials to use a versioned
NPM package rather than a checked-in prebuilt Filament WASM file.

Fixes #2686.
2020-06-15 11:34:59 -07:00
Ben Doherty
42d55f226b Support Metal in the iOS simulator (#2678) 2020-06-15 11:08:52 -07:00
Ben Doherty
25b43d7c2a iOS samples: set opaque = YES on CAMetalLayer (#2675) 2020-06-15 11:05:17 -07:00
Ben Doherty
de3f757013 Add JS bindings to gltfio camera funcs (#2681) 2020-06-15 11:04:16 -07:00
Philip Rideout
ebd195f8e4 matdbg: Add support for Android.
See the matdbg README for details.
2020-06-14 22:42:55 -07:00
Romain Guy
a2ce57ade3 Fir applyAnimation() when scale is close or equal to 0 2020-06-13 14:48:07 -07:00
Ben Doherty
7a78ccd184 Turn off Windows DEBUG builds for continuous builds (#2682) 2020-06-12 16:48:53 -07:00
Philip Rideout
963a8958ec Fix Ubuntu build. 2020-06-12 13:47:54 -07:00
Philip Rideout
899ac1224f gltfio: Add Java bindings for desktop.
This is completely untested.

Fixes #2670.
2020-06-12 13:47:54 -07:00
Romain Guy
a019de3363 Add (improved) color grading UI to gltf-viewer (#2676) 2020-06-12 08:30:43 -07:00
Ben Doherty
79c83f509c Fix Metal bug not creating default depth attachment (#2677) 2020-06-11 17:55:20 -07:00
Ben Doherty
fde2d2e483 Fix MeshReader material bug (#2674) 2020-06-11 14:49:25 -07:00
Ben Doherty
b2c63b6cd2 Add support to gltfio for glTF cameras (#2663) 2020-06-11 13:57:01 -07:00
Philip Rideout
1f9d073a64 gltfio: enable unused UV attributes when possible.
Reproduced the issue by hacking the TexturedCube glTF file.

Verified the fix by viewing TexturedCube in ubershader mode, then
hacking the shader with matdbg in order to visualize texture
coordinates.

Fixes #2659
2020-06-11 12:05:43 -07:00
Philip Rideout
fa0f5e0501 Prep the build for multi-platform matdbg. 2020-06-10 20:00:24 -07:00
Philip Rideout
fee6a2f075 Miscellaneous matdbg improvements
matdbg
    - Materials are now sorted by name and the sha id is hidden.
    - PostProcess materials now separated from Surface materials.
    - PostProcess details now hide the non-existing properties.
    - Larger default pane size for the material list.
    - Use nicer font.

matinfo
    - Print out the Material Domain.

filament
    - get*Slow methods in FMaterial are now private.
2020-06-10 20:00:24 -07:00
Romain Guy
19a212389b Perform non-ACES grading in BT.2020 (#2662)
* Perform non-ACES grading in BT.2020

* Don't use BT.2020 with legacy filmic tone mapper

* Fix comments

* Use == operator instead of memcmp
2020-06-10 13:41:17 -07:00
Mathias Agopian
1b1ef591a4 fix typo that prevented fxaa to work properly (#2667)
It caused the wrong fxaa variant to be chosen, in turn causing
flickering due to temporal dithering.
2020-06-10 08:53:09 -07:00
Rupert Rawnsley
b0acb3216a eglInitialize requires a non-null IntArray reference and different offsets for major and minor. (#2668) 2020-06-10 08:52:20 -07:00
Philip Rideout
10e1aaadff Vulkan: fix mipmap generation on Android.
The blit DriverAPI command was not enforcing correct synchronization.
On Android, this manifested as an intermittent issue with bad mipmap
levels.

This did not trigger any validation warnings and therefore took a long
time to track down.

Fixes #2643
2020-06-09 21:11:44 -07:00
Pixelflinger
00b522669c minor fixes for matdbg
- don't crash when a material doesn't have a name
- don't cache the program in PostProcessManager so we can do live
  editing. Not needed anyways, because Material has a cache.
2020-06-09 13:27:56 -07:00
Philip Rideout
f125e1730d Throw Java exception when using destroyed Animator.
Someone wise once said: "It is better to throw in Java than to crash in
Native."

Motivated by #2654.
2020-06-09 10:36:35 -07:00
Rupert Rawnsley
18776fc432 SamplerType JNI definition was out of step with the native definition. (#2658)
When invoking MaterialBuilder.samplerParameter with Java enum SAMPLER_EXTERNAL it was wrongly recast as native enum SAMPLE_CUBEMAP in the JNI interface because the Java enum was missing SAMPLE_2D_ARRAY.
2020-06-09 08:35:33 -07:00
Romain Guy
4bf21876b4 Add new color grading feature, vibrance (#2656)
* Add new color grading feature, vibrance

* Address code review comment
2020-06-09 08:34:10 -07:00
Pixelflinger
1feca23477 don't attempt to call Android private APIs
This used to be tolerated, but no more with recent versions of android.
2020-06-08 16:18:33 -07:00
Romain Guy
b4d2a1991a Add new curves color grading tool (#2651)
* Add new curves color grading tool

* Add release notes
2020-06-08 12:17:53 -07:00
Romain Guy
3e6ee4ca5e Fix libimageio's HDR format decoder (#2653)
See https://cbloomrants.blogspot.com/2020/06/widespread-error-in-radiance-hdr-rgbe.html
2020-06-08 11:48:11 -07:00
Pixelflinger
ee6ddf675e syscall (futex) errors are returned in errno
this fixes a problem where our implementation of Condition would not
handle timeouts properly
2020-06-06 15:50:38 -07:00
@roxlu ☾
7e6c38d098 Fix: cannot use parts index for material index. (#2652)
* Fix: cannot use parts index for material index.

* Fix formatting

Co-authored-by: Romain Guy <romainguy@curious-creature.com>
2020-06-06 10:42:53 -07:00
Ben Doherty
7a8755b5b2 Implement framebuffer fetch for Metal backend (#2648) 2020-06-05 17:31:12 -07:00
Pixelflinger
6461370cb8 more debug code to help catch an ANR
- assert that shutdown() is called from the main thread
- attempt to catch whether CommandBufferQueue::mExitRequested gets corrupted
  (which could explain the ANR).
2020-06-05 14:50:16 -07:00
Ben Doherty
e56882d20f Update tinyexr to 944c740 (#2644) 2020-06-05 12:22:28 -07:00
Philip Rideout
43f7bad8a3 Kotlin cleanup 2020-06-05 08:23:25 -07:00
Romain Guy
31bdb61047 Add PQ transfer functions 2020-06-04 18:18:01 -07:00
Romain Guy
2fcca9677d Add Ushimura tone mapping operator
Also fix potential negative values when applying white balance
during color grading.
2020-06-04 15:17:08 -07:00
Philip Rideout
a4094193c3 gltfio: fix AABB when instancing is enabled
If a client opts in to AABB computation and uses instancing, the AABB
would be clobbered with an infinite box.

Fixes #2639
2020-06-04 14:06:50 -07:00
Romain Guy
1935598a7d Add Java bindings for ColorGrading (#2638) 2020-06-04 11:03:15 -07:00
Romain Guy
6c3b7a2282 Update RELEASE_NOTES.md 2020-06-03 19:05:37 -07:00
Romain Guy
23b62e2d12 Add ASC CDL (Color decision list) to color grading (#2635)
A CDL is made of slope/offset/power, and is roughly equivalent
to lift/gamma/gain.
2020-06-03 19:01:22 -07:00
Philip Rideout
b281022eb0 sample-page-curl: flip the backface image. 2020-06-03 12:07:43 -07:00
Philip Rideout
910c2e9b0e Vulkan: implement insertEventMarker.
Note that pushGroup / popGroup are already supported.
2020-06-03 11:54:36 -07:00
Romain Guy
9007de03d9 Update README.md 2020-06-02 22:56:11 -07:00
Romain Guy
1aa57fc425 Color grading: add saturation and contrast (#2627)
* Add transforms for ACEScct and enabling/disabling color grading in sample

* Add saturation and contrast adjustments

* Rename ACES to ACES_LEGACY and introduce ACES

ACES_LEGACY is ACES with a brightness boost to match our old
tone mapping operator.
2020-06-02 22:54:00 -07:00
Philip Rideout
7418fc0222 gltfio: JNI bindings for get-by-name.
Tested in Android Studio by starting sample-gltf-viewer and typing the
following into the debugger:

    modelViewer.asset!!.getFirstEntityByName("Drone_Body")
    modelViewer.asset!!.getEntitiesByName("Drone_Body")
    modelViewer.asset!!.getEntitiesByPrefix("Drone")
2020-06-02 18:38:36 -07:00
Philip Rideout
9437907eb4 ModelViewer now uses a coroutine. 2020-06-02 18:36:49 -07:00
Philip Rideout
91a009f94c Add new async method to ModelViewer.
If you now try loading Bistro, the skybox shows up fairly quickly.
This works by moving AssetManager uncompression off the UI thread.
2020-06-02 18:36:49 -07:00
Mingwei Samuel
ca6b1860be Fix typescript View set/getAmbientOcclusion wrong type 2020-06-02 16:40:50 -07:00
Romain Guy
fbb8742cbd Add new color grading feature: shadows/mid-tones/highlights (#2623)
* Add new color grading feature: shadows/mid-tones/highlights

This feature can be used to color correct specific tonal ranges.
The tonal zones can be precisely controlled.
2020-06-02 12:28:38 -07:00
Philip Rideout
6c173489d7 gltfio: Add get-by-name and get-by-prefix methods.
Java bindings will be forthcoming in a separate commit.
2020-06-02 10:17:12 -07:00
Philip Rideout
0abe262094 Patch hat-trie to remove exceptions. 2020-06-02 10:17:12 -07:00
Philip Rideout
bd72f1fd6a Add hat-trie to third_party. 2020-06-02 10:17:12 -07:00
Philip Rideout
28912b6f57 filamat-android: fix string leaks 2020-06-02 10:16:41 -07:00
Philip Rideout
a3e336921e gltfio: improve performance by assuming assets are well-formed.
glTF assets are required to provide min/max attributes for POSITION,
so in theory we never need to compute the AABB. However the option is
still there.

This PR also makes it so that Java clients can choose this option,
previously it was hardcoded for all non-native clients.
2020-06-01 10:30:09 -07:00
Romain Guy
524da0af28 Update RELEASE_NOTES.md 2020-06-01 09:37:21 -07:00
Philip Rideout
adccf9f432 gltfio: remove details namespace 2020-06-01 09:19:18 -07:00
Romain Guy
c49ffcc354 Add channel mixer and docs to ColorGrading (#2618) 2020-06-01 09:07:34 -07:00
Romain Guy
50adc1f661 Add per-view color grading LUT (#2615)
* Add the ability to set a ColorGrading LUT per View

In this change, material_sandbox allows to change the tone mapping
operator at runtime.

* Add Mathematica notebook used to explore white balance

The implementation is meant to reproduce the temperature/tint sliders
founds in Adobe Lightroom. The temperature can be offset from 2,000K
to 50,000K using a slider between -100 and +100 (-1.0 to 1.0 in our
API). The range of tint was modelled after the range used for the
temperature.

* Fix various issues

- A refactoring wrongly remamed the color grading pass
- Setting a View's ColorGrading to null selects the
  default color grading options

* Implement white balance in ColorGrading
2020-05-31 19:24:42 -07:00
Romain Guy
b77e024de9 Introduce ColorGrading API (#2613)
* Introduce ColorGrading API

A ColorGrading object will eventually be settable on a View to
choose the tone mapping and other color transformations.

There is currently only a single default ColorGrading instance
used by all views.

* Use raw function pointers
2020-05-29 18:54:48 -07:00
Pixelflinger
1f77fb5995 minor cleanup of PostProcessManager ctor
make sure all fields are always initialized and the IDE stops 
complaining.
2020-05-29 18:44:48 -07:00
Philip Rideout
bf1f32e308 gltfio: Use JobSystem to compute bounding boxes. 2020-05-29 18:13:49 -07:00
Philip Rideout
2c6042bd44 Add systrace markers to gltfio. 2020-05-29 18:13:49 -07:00
Philip Rideout
96c770ad9e gltfio: Use JobSystem to compute tangents. 2020-05-29 18:13:49 -07:00
Ben Doherty
b1563dabe9 Metal: use render target height to adjust viewport when blitting (#2610) 2020-05-29 16:08:47 -07:00
Romain Guy
3ef37f8925 Prep work for proper color grading (#2611)
* Prep work for proper color grading

* Bring back local colorGrading bool to drive that pass

* Fix formatting issue

* Add missing case for the color grading pass

* Fix formatting issues

* Formatting issues
2020-05-29 15:29:15 -07:00
Philip Rideout
ede09e28e3 gltfio: add JavaScript bindings for instancing. 2020-05-29 09:22:17 -07:00
Philip Rideout
81ea280ea9 gltfio: add Java bindings for instancing. 2020-05-29 09:22:17 -07:00
Philip Rideout
92c017bdd3 Simplify WebGL context creation. 2020-05-29 09:09:49 -07:00
Philip Rideout
6870d360cd gltfio: Simplify FilamentInstance. 2020-05-29 07:43:44 -07:00
Philip Rideout
2d62daf5e8 Add sample for testing glTF instancing.
Fixes #1513.
2020-05-29 07:43:44 -07:00
Philip Rideout
83cff32856 gltfio: Add support for instanced animation.
When animation is applied to the master asset, all instances are
animated.

Instances can also be individually animated via the Animator in
FilamentInstance.

Fixes #1513.
2020-05-29 07:43:44 -07:00
Philip Rideout
8de730f76c gltfio: Add support for simple instancing.
This adds createInstancedAsset() to AssetLoader, which creates a master
asset and a set of slave instances. Vertex buffers, index buffers,
textures, and material instances are shared. Entities and components are
duplicated.

Instances have their own API object that is very simple. Light sources
and material instances are not instanced, so are not accessible through
the instance API object.

The master-slave ownership model lets us avoid complex shared ownership
semantics. The existing cache structures in AssetLoader allow the
implementation of this feature to be fairly simple.

The master asset exposes the union of all entities and allows clients to
modify all instances en masse if they wish. This design also works
naturally with ResourceLoader, which does not need to know about
instancing. For example, asynchronous loading is completely unchanged;
the dependency graph simply contains the union of entities across all
instances.

Support for animation is added in a subsequent commit.

Fixes #1513.
2020-05-29 07:43:44 -07:00
Romain Guy
1f29df6da4 Add a note about AGP 4.0.0 2020-05-28 14:05:20 -07:00
Philip Rideout
c087eb6825 gltfio: Add Java / JavaScript bindings for lights. 2020-05-28 11:51:35 -07:00
Pixelflinger
038c35fbda add a few systraces during init 2020-05-28 11:28:22 -07:00
Ben Doherty
80fcd133de Add correct scheduleDestroy calls to Metal backend (#2600) 2020-05-27 15:54:54 -07:00
Pixelflinger
62d0f9f033 perfcounters are now disabled by default
To enable some basic profiling of the gl thread using performance
counters, the "filament.perfcounters" property must be set to 1
(before the Filament Engine is created):

    adb shell setprop filament.perfcounters 1

This is so that filament doesn't interfere with simpleperf by default.
2020-05-27 15:53:45 -07:00
Pixelflinger
1e65b4d8af load post process materials lazily
We aim to reduce start-up time and memory usage.
2020-05-27 11:17:10 -07:00
Pixelflinger
f3731fa797 cleanup and code reformatting
This change mostly reorders PostProcessManager's methods roughly
in order that appear in the pipeline.
2020-05-27 11:17:10 -07:00
Romain Guy
28f031e95f Update RELEASE_NOTES.md 2020-05-27 10:52:04 -07:00
Jaime Blasco
5104318fff Initialize DisplayHelper when using textureView in ModelViewer (#2598) 2020-05-27 10:10:13 -07:00
Pixelflinger
68f0ab6312 Implement ACES tone mapping
this leverages the new LUT based tone mapping
2020-05-26 23:46:37 -07:00
Pixelflinger
62a591bc73 Add a new tone mapping option using a LUT
This is now the default, and the tone mapper used
is now the same on desktop and mobile.
In the future this will allow us to implement many features such as
color grading at no cpu cost.
2020-05-26 23:46:37 -07:00
Benjamin Doherty
0f6a06a2e1 Add 3D texture support to Metal 2020-05-26 23:46:17 -07:00
Pixelflinger
b620a5e358 Add support for 3D textures in the vulkan backend 2020-05-26 23:45:35 -07:00
Pixelflinger
0d652d61f8 fix typo causing textureGather to always be used 2020-05-26 17:59:01 -07:00
Ben Doherty
1b033c7de3 Implement MRT for Metal (#2590) 2020-05-26 17:38:37 -07:00
Pixelflinger
eb5eb6c827 fix EGL config selection 2020-05-26 17:22:30 -07:00
Philip Rideout
0e437d244f Vulkan: fix dummy type for disabled attribs.
OpenGL allows vertex shaders to consume attributes that are never
assigned values from a vertex buffer. When this occurs, GL provides a
default zeroed-out value, or a value from the most recent call to
`glVertexAttrib*v`.

Vulkan does not allow this, so our Vulkan backend provides dummy data by
re-using the position buffer, which we know exists. This was an existing
hack, but it did not always assign a compatible type, which resulted in
validation spew with gltf_viewer + BusterDrone.

This fixes one of the two bugs reported in #2573.
2020-05-26 13:20:06 -07:00
Philip Rideout
9024b4afd7 gltfio: fix vertex attribute type mismatch.
Vulkan complains if a pipeline declares an integer vec2 attribute but
the shader consumes it as "vec2" rather than "ivec2". gltfio was doing
this when supplying dummy texture coordinates.

This fixes one of the two bugs reported in #2573.
2020-05-26 13:19:52 -07:00
Pixelflinger
62ff7b7d0a Improve AO buffer upsampling
Since AO is computed at 1/4 resolution, it is necessary to upsample
the AO buffer. Until now this was done with a bilinear tap, which is
less than ideal as it can creates jaggies at edges.

High quality upsampling can now be enabled and uses a bilateral filter.
The cost is about 2.0 ms at 250MHz on Pixel 4. ES3.1 is required.
2020-05-26 12:59:47 -07:00
Pixelflinger
d1ed4f837c improve SSAO quality
SSAO starts at 1/4 resolution, and because we used derivatives
to calculate a cheap pre-blur, the output was mostly 1/4 resolution
of that, leading to 1/4 of the destination pixels being mostly identical.
This, in turn caused sampling issues when reading the SSAO buffer during
the color pass.

We fix this by getting rid of the pre-blur, and increasing slightly the
size of the gaussian blur from 9 samples to 13, which increases the
SSAO pass time by 20%, or 0.3ms at 430 MHz on Pixel 4.

With this change and bilinear filtering in the color pass, we get rid
of all the sampling artifacts.
2020-05-26 12:59:47 -07:00
Pixelflinger
d62f664957 ssao: restrict the scaling to 0.5 and 1.0
until now we allowed any resolution for SSAO, but it didn't make
much sense, especially that the depth pass is now used for other things.
To keep things more manageable, we only allow 0.5 and 1.0 scale
factor settings (respectively quarter and full resolution).
2020-05-26 12:59:47 -07:00
Philip Rideout
6311b538e1 Add "if" when compiling subpass material.
This avoids error spew on some platforms such as Chrome + WebGL 2.0
2020-05-26 11:03:55 -07:00
Philip Rideout
58bb1f61e6 Add JS bindings for DoF.
Adding this for completeness, although the feature triggers a known
issue with Chrome's WebGL implementation that emits an error when
source and destination textures of a draw call are the same.
2020-05-26 10:06:40 -07:00
Mathias Agopian
8415d18401 Fix refracted objects drawing order (#2577)
Refracted objects could be drawn on top of opaque objects that were
closer to the camera.

Du to a typo, we were not reusing the existing depth buffer during the
refraction pass.

Fixes #2576
2020-05-23 17:08:53 -07:00
neshume
6df1265bef Fix compilation issues under ubuntu 20 and latest clang (#2562)
Co-authored-by: neshume <alex.andel@gmail.com>
2020-05-23 17:08:19 -07:00
Philip Rideout
dc51dc197c Gradle: update old property name.
I forgot to update this in 0b1fa7f.
2020-05-22 23:28:30 -07:00
Philip Rideout
1292610289 Vulkan: fix synchronization issues with timestamps.
This contains the following two fixes, but the second fix is more
important because it prevents an actual validation error on Android.

1. The query pool bitset was written in the main thread but read
   in the driver thread, this is now protected with a mutex.

2. Querying a timestamp before it has been written into the command
   buffer was still causing validation errors, despite the fact
   that we are now properly using the AVAILABILTY flag. This is a
   CPU-side synchronization problem and can therefore be fixed using
   std::atomic<bool>.
2020-05-22 15:40:37 -07:00
Romain Guy
e9d1e3a82e Stop using deprecated APIs for incremental builds (#2574) 2020-05-21 22:15:55 -07:00
Philip Rideout
c749f7e798 Emit a one-time warning for VK_SUBOPTIMAL_KHR.
This was sometimes causing a cascade of log messages and swap chain
re-creations on Android.

To support resizing, we still re-create the swap chain when encountering
VK_ERROR_OUT_OF_DATE_KHR.

Suboptimal means: "A swapchain no longer matches the surface properties
exactly, but can still be used to present to the surface successfully."
2020-05-21 15:04:08 -07:00
Romain Guy
f5068457f2 Update README.md 2020-05-21 14:44:34 -07:00
Pixelflinger
3a3cd1c0ec Better fix iOS lack of GL_EXT_multisampled_render_to_texture 2020-05-21 11:49:54 -07:00
Philip Rideout
7dfe26def8 Vulkan: update instructions for enabling validation. 2020-05-21 11:29:27 -07:00
Philip Rideout
3b3dc0af81 Vulkan: refactor the ENABLE_VALIDATION flag.
It is convenient to control the debug_info extension and the validation
layers from one central place. This makes it easier to force-enable
validation in Release builds to validate optimized shaders.
2020-05-21 10:46:53 -07:00
Philip Rideout
0e38cc770d filamat: generate spirv 1.0 rather than spirv 1.3
Since we are still on Vulkan 1.0, we cannot use SPIR-V 1.3.
If we try to do so, this error is generated:

    Invalid SPIR-V binary version 1.3 for target environment SPIR-V 1.0

In non-optimized builds, we were already generating spirv 1.0, but
when we enabled the shader optimizer, we generated spirv 1.3.

This bug has actually been around forever, but we did not notice because
we were only invoking the optimizer in release builds, which does not
enable validation.

We cannot upgrade Vulkan 1.1 because the latest LunarG SDK for macOS
does not support it.
2020-05-21 08:41:53 -07:00
Ben Doherty
c0eb058728 Shadow cascades: adjust near / far planes to tightly bound scene (#2537) 2020-05-20 16:31:13 -07:00
Pixelflinger
8b515ee4c2 Make MSAA fast(er) again on Mobile
Due to a typo that became relevant when we switched the gles headers to
3.0 from 3.1, MSAA started to take the emulated path.
2020-05-20 11:53:27 -07:00
Philip Rideout
65e286e7de Vulkan: fix version selection. 2020-05-19 17:58:21 -07:00
Philip Rideout
cdd099951a sample-page-curl: add rigidity parameter. 2020-05-19 16:48:55 -07:00
Philip Rideout
432ed50cb3 sample-page-curl: use inverseTonemap() etc. 2020-05-19 16:48:55 -07:00
Philip Rideout
d4a396d52f matinfo / matdbg: fix SPIRV version, add validation.
The value we pass to spvContextCreate() is not SPV_ENV_UNIVERSAL_1_3,
which is what we use in GLSLPostProcessor.

Also add a call to spvValidateBinary(), which would have caught this
oversight.
2020-05-19 16:48:36 -07:00
Ben Doherty
97c9ad7599 Metal: implement lod clamping to fix IBL bug (#2556) 2020-05-19 15:40:07 -07:00
Philip Rideout
15e2447cb5 Vulkan: fix usage of timestamp queries. 2020-05-19 14:17:03 -07:00
Philip Rideout
21ed172c55 Vulkan: add support for sync objects.
This allows FrameSkipper to work on desktop.

Similar to the GL backend, we can only query the fence from tick().
The Vulkan spec stipulates that a fence object cannot be accessed by
more than one thread simultaneously. My initial implementation violated
this, which was caught by the validation layer.
2020-05-19 14:16:07 -07:00
Pixelflinger
c619f089e7 add support for 3D textures
Only gl backend in this PR.
2020-05-19 14:09:16 -07:00
Pixelflinger
29db39b6a7 Use a subpass for tone mapping when possible
This allows to never store/load to main memory the HDR color buffer,
saving precious bandwidth. This mode relies on the
ext_framebuffer_fetch extension being present and can't be enabled
with certain features (currently msaa, Bloom, DoF).

This will eventually be supported on Metal and Vulkan as well.
2020-05-19 12:25:41 -07:00
Pixelflinger
b50f7dd7de Add isFrameBufferFetchSupported() to the backend API 2020-05-19 12:25:41 -07:00
Pixelflinger
6df20f3083 Add a private property to materials to control framebuffer_fetch
this is intended to be temporary until we properly add support
for vulkan's subpasses. this PR just helps us activate
ext_framebuffer_fetch on select materials.
2020-05-19 12:25:41 -07:00
Philip Rideout
5f34b8974f Fix buffer size bug in sample-page-curl. 2020-05-18 14:34:46 -07:00
Ben Doherty
bf13f76dea Fix, Metal validation error with SSR and post-processing turned off (#2550) 2020-05-18 13:17:37 -07:00
Philip Rideout
92048e6b65 filagui: Fix "1 leaked FScene" warning.
Fixes #2542.
2020-05-18 11:51:23 -07:00
Ben Doherty
c37c04762d Fix Metal memory leak inside MetalTimerQuery (#2548) 2020-05-18 11:48:16 -07:00
Pixelflinger
53a8fd94ba get rid of our details namespace
in practice it wasn't really useful, and it'll save some binary
space. everything is still isolated in the filament namespace.
2020-05-18 10:51:46 -07:00
Philip Rideout
b4d16ab3b5 Tweak WebGL build settings. 2020-05-18 10:02:21 -07:00
Philip Rideout
0b1fa7fc80 Enable Vulkan for Android by default.
The presence of a special Gradle property is now used to exclude Vulkan
support from the build. By making Vulkan "always on" for local
development, we can avoid stale CMake cache issues that arise from
toggling the Gradle property. It also lets you avoid adding the flag
to Android Studio preferences.

This is motivated by testing and does not indicate production readiness.
Clients still need to pass VULKAN into the Engine constructor to select
the Vulkan backend.

To keep APK size down and keep CI fast, we are continuing to exclude
Vulkan from official Android builds.

After syncing this change, you might need to use `./build.sh -c` to
clobber various build caches.
2020-05-18 09:34:55 -07:00
Romain Guy
010ce1c069 Update README.md 2020-05-16 14:33:07 -07:00
Romain Guy
f6c3663789 Update RELEASE_NOTES.md 2020-05-16 14:32:17 -07:00
Philip Rideout
d49d0f1762 Add JavaScript bindings for setVisibleLayers. 2020-05-15 12:53:02 -07:00
Ben Doherty
8780d7aae5 Bump version to 1.7.0 (#2541) 2020-05-15 10:41:51 -07:00
Ben Doherty
1ac6f5bbfe Cast shadows by default in gltf_viewer (#2538) 2020-05-15 09:43:21 -07:00
Philip Rideout
764d4198bc Add headless support to FilamentApp and frame_generator.
These changes make it easier to test headless rendering in macOS.

I verified that this works using the frame_generator tool, however
it requires the fixes in PR #2529.
2020-05-14 16:41:39 -07:00
Philip Rideout
d5d77a46ec macOS: fix headless rendering. 2020-05-14 16:38:07 -07:00
Philip Rideout
fb8b9af8fd FilamentApp: do not recreate SwapChain upon resize.
This is done for consistency with the Android samples. Tested with
gltf_viewer against Vulkan, Metal, and OpenGL. Dragged window between
high DPI and low DPI displays.

Since resizing does not trigger the "NSView has changed" handler in
PlatformCocoaGL, it now must to detect a resize in order to make the
required call to NSOpenGLContext::update() as per the following
documentation.

https://developer.apple.com/documentation/appkit/nsopenglcontext/1436135-update

Fixes #2528
2020-05-14 16:38:07 -07:00
Ben Doherty
f26b556fce Metal: allow swapchain size to change (#2535) 2020-05-14 15:47:49 -07:00
Pixelflinger
9e11e52c92 always hold a global ref on the surfacetexture
We were not holding a global ref on more recent version of android,
this made the Stream API inconsistant. 
Filament now always keeps a global ref on the surfacetexture while in
use.
2020-05-14 15:27:15 -07:00
Pixelflinger
52573ecd95 don't kick the driver thread after each framegraph pass
this was a misguided optimization, on low-end devices this actually
has a large overhead (presumably because of the smaller cache and
increased branch missprediction as well as extra synchronization).

on some low-end devices we see the gl thread go from ~40ms to ~10ms
with the gltf sample.
2020-05-13 19:36:19 -07:00
Pixelflinger
79995349d8 use systrace when EXT_debug_marker is not supported
EXT_debug_marker is not supported GL debuggers won't show these
markers, so as an alternative, we dump them in systrace.
2020-05-13 19:36:03 -07:00
Pixelflinger
e31ebb7a82 Fix a few issues with dithering
- only triangular noise needs to be scaled between +/-1, other noises
  have a uniform distribution and need to be scaled between +/-0.5

- all dither routines work in RGBA

- fixed FXAA in opaque mode when dithering modified the alpha channel
  (which is used by FXAA). This fixes flickering when FXAA and dithering
  was enabled.

- use triangular noise dithering on mobile and desktop. The cost in
  not measurable on a pixel 4 / 1080p, and the quality is better.

- refactor dithering code a bit such that:
  - noise methods are not temporal
  - all dither functions have the same structure
2020-05-13 17:16:58 -07:00
Pixelflinger
b4f09325f1 PerViewUib header and .cpp padding didn't match
It wouldn't really cause any issues, because still.
2020-05-13 10:58:23 -07:00
Mathias Agopian
ee3c3d0965 debug option to track Entities (#2526)
* debug option to track Entities

Set FILAMENT_UTILS_TRACK_ENTITIES to true when building libutils to
activate entity tracking. This adds two public methods:

getActiveEntities() and dumpActiveEntities() the later displays the
stack trace of where the remaining entities were allocated.

This is useful for tracking leaks.

* Update libs/utils/include/utils/EntityManager.h

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

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2020-05-12 17:55:39 -07:00
Mathias Agopian
d08a4e8bd9 Very basic SwiftShader support (#2523)
* Very basic SwiftShader support

- we only provide SwiftShader's khornos headers in third_party

- swiftshader itself must be available on the host (for instance it
  can be compiled from source).

- to enable pass -DFILAMENT_USE_SWIFTSHADER=ON option to cmake

- only GLES 3.0 is supported. Vulkan is not yet supported.

CMake should find the swiftshader libraries automatically, but if
they're installed in a non-standard place, the environment variable
SWIFTSHADER_LD_LIBRARY_PATH can be set to that place.


We also use the GLES 3.0 headers everywhere, since we don't rely on 3.1
at this point.

* add a tnt folder with a README
2020-05-12 17:45:16 -07:00
Philip Rideout
0a9236c2eb Make JNI constructors private unless they take Engine.
This removes (rather than deprecates) all public constructors that
take a native pointer without an accompanying Engine.

Most notably, MaterialInstance had a public pointer constructor which
is now package private. This means that FilamentAsset needs an Engine,
so it now takes the one from AssetLoader.
2020-05-12 15:41:19 -07:00
Philip Rideout
0a61faa57a KtxLoader should pass Engine to Texture constructor. 2020-05-12 10:57:21 -07:00
Philip Rideout
26520c8d23 filament-utils: Improve ModelViewer flexibility. 2020-05-12 10:57:21 -07:00
Pixelflinger
64b3d7807b Fix Entity leaks with Camera
- When creating a Camera component, it is the responsibility of the caller
to destroy the Entity. ShadowMap didn't do that, so it would leak two
entities.

- When destroying a Camera component with the legacy (and deprecated)
API, Engine::destroyCamera() should destroy the associated Entity
(and was documented as doing so). However, it actually didn't.

- don't use the static EntityManager is ShadowMap.
2020-05-12 10:08:13 -07:00
Pixelflinger
ec77086186 only libbackend should link against gl/vlukan/etc...
filament itself should be agnostic to the rendering api
2020-05-12 10:07:53 -07:00
brian.wang
0187caf10f Fix minor bug in Vulkan backend on Windows
* fix compile error when vulkan

* matc:print shaders support

* fix link error

* ussage for matc print flag

Co-authored-by: brian.wang <brian.wang@noitom.com>
2020-05-12 08:59:25 -07:00
Philip Rideout
823f5c9c1f WebGL: upgrade and accommodate EMSDK.
Fixes #2515.
2020-05-11 13:58:07 -07:00
Philip Rideout
9a47178b3d gltfio: expose getMaterialInstances to Java.
Tested locally by hacking gltf-viewer on Android, added the following
lines to MainActivity:

```kotlin
for (mat in modelViewer.asset!!.materialInstances) {
    Log.d("gltf-viewer", mat.name)
}
```
2020-05-11 10:39:13 -07:00
Ben Doherty
a3fb5c41f1 Make note of VS2019 for building Android on Windows 2020-05-11 09:47:14 -07:00
Ben Doherty
58df2681dd Fix unused variable in release (#2504) 2020-05-11 09:33:51 -07:00
Kostiantyn Zghirovskyi
5ef816ef2a Clarify Windows build instructions (#2507) 2020-05-11 09:33:14 -07:00
Romain Guy
91f052a9b0 Clarify doc 2020-05-10 14:15:42 -07:00
Romain Guy
6a0a2d965e Update documentation 2020-05-09 15:13:25 -07:00
Kostiantyn Zghirovskyi
2260fe5b62 Fix filament-utils-android build on Windows (#2508)
* Fix filament-utils-android build on Windows

* Update build.gradle

* nit: use char version instead

* Fix No signature of method: java.lang.String.replace() is applicable for argument types: (Character, String) values: [\, /]
2020-05-08 16:57:16 -07:00
Pixelflinger
e07f0dd244 Texture(Engine, long) instead of Texture(long)
deprecated Texture(long nativeTexture) in favor of
Texture(Engine, long nativeTexture), there is no difference
currently,  but in the future Texture(Engine, long nativeTexture) 
will be able to validate the native pointer.
2020-05-08 15:39:14 -07:00
Pixelflinger
d194eec0ad report to java when an object can't be destroyed
The JNI layer already does this, but can only track objects it created,
sometimes developers might create filament objects on the native side
and wrap them into java objects and this might cause a failure to
detected when objects are double-destroyed.

However, this can often be caught by the native code -- so, when the
native side is asked to destroy an object that doesn't exist, we now
return an error (exception if enabled) and we throw an exception
on the java side.

Filament typically doesn't do this kind of tests, however these bugs
can be very hard to find, and the cost is small.
2020-05-08 15:39:14 -07:00
Pixelflinger
addf325d42 better handling of invalid handles
- all backend return nullptr when handle_cast<> is called with
  an invalid handle. this ensures a prompt crash on all backends rather
  than different behaviors, some including potential memory corruptions.
  assert() in debug builds. The proper way to check is to cast the
  handle to bool.

- be more consistent in the GL backend about where we check for the
  validity of handle -- which is basically nowhere, except for destroy
  (because we have the same semantic than free(nullptr) -- i.e. no-op.
  Other places are treated like bad pointers, and as per above
  handle_cast<> will return nullptr.

- make sure we don't call FScene::updateUBOs with an invalid handle
  when the scene is empty
2020-05-08 15:39:14 -07:00
Pixelflinger
c019781471 only log "no texture bound" in debug builds
This is way to verbose in release builds, and since it's not
a bug issue on GLES, we silence this for now.
2020-05-08 15:39:14 -07:00
Pixelflinger
de849fa21f removed a wrong assert() 2020-05-08 15:39:14 -07:00
Philip Rideout
072d17d64f gltfio: use the new material name feature.
To see proof that this works, use gltf_viewer with -u and examine the
node hierarchy. You will now see the correct material names instead of
the ubershader names.
2020-05-08 11:24:38 -07:00
Philip Rideout
38b9cf4fe3 Vulkan: add support for resizing the window.
Fixes #334.
2020-05-08 09:46:49 -07:00
Philip Rideout
d0a8c6b4fa Vulkan: refactor destroySwapChain. 2020-05-08 09:46:49 -07:00
Philip Rideout
ab2ae245ba Vulkan: refactor createVkSurfaceKHR. 2020-05-08 09:46:49 -07:00
Philip Rideout
f53f03b5dd Java MaterialInstance::getName now creates string lazily. 2020-05-08 09:44:49 -07:00
Philip Rideout
474fe9c5ed Change behavior of MaterialInstance::getName. 2020-05-08 09:44:49 -07:00
Philip Rideout
c3c8293862 MaterialInstance now has an optional name.
When no name is provided during instance creation, it does NOT inherit
the name of its parent material. This is because instances should be
lightweight and users can already do instance->getMaterial()->getName().

In a subsequent PR, this feature will be exercised and tested via the
gltfio AssetLoader.

Fixes #2485.
2020-05-08 09:44:49 -07:00
Ben Doherty
3c42ace496 Fix, don't sample from cascades without visible shadows (#2501) 2020-05-07 16:50:34 -07:00
Romain Guy
2702ef123c Update README.md 2020-05-07 13:26:57 -07:00
Romain Guy
89e76fde57 Update README.md 2020-05-07 13:18:23 -07:00
Romain Guy
37c8f1d8ea Update README.md 2020-05-07 13:16:43 -07:00
Romain Guy
8416553724 Update README.md 2020-05-07 13:15:12 -07:00
Romain Guy
f3baecc4be Update README.md 2020-05-07 13:11:20 -07:00
Ben Doherty
89df8355aa Fix build warning (#2499) 2020-05-06 18:30:58 -07:00
Ben Doherty
0e00dbb967 Add up and down movement to free flight camera (#2494) 2020-05-06 18:30:43 -07:00
Pixelflinger
786dbdc6e4 fix JNI objects allocation and memory corruption
- we were allocating objects with a destructor in the command stream
  which is always invalid because there is no guarantee that when 
  the callback is called, the underlaying memory is still valid
  (and it wasn't).

- AutoBuffer move-ctor wasn't moving some of its state, which would
  lead to destroying the same ref several times.
2020-05-06 18:08:13 -07:00
KJ Liu
920dc6b167 AssetLoader now loads names for mesh-free nodes. 2020-05-06 17:59:20 -07:00
Pixelflinger
809379b93d only implement flushAndWait() debugging on android
it's causing some unrelated problem on the iOS simulator, and we're
looking for an Android bug anyways.
2020-05-06 17:42:48 -07:00
Ben Doherty
4701945c87 Add rudimentary cascading shadow map support (#2482) 2020-05-06 17:20:04 -07:00
Kostiantyn Zghirovskyi
2c79f4c480 Update building instruction on (#2496) 2020-05-06 16:14:38 -07:00
Philip Rideout
cc29359897 gltfio: fix unbound texture warnings in ubershader mode. 2020-05-06 15:24:21 -07:00
Philip Rideout
b54000ccb9 Add CMAKE_EXPORT_COMPILE_COMMANDS. 2020-05-06 12:21:49 -07:00
Philip Rideout
c65194fce1 gltfio-lite: fix UBO errors. 2020-05-06 09:09:56 -07:00
Pixelflinger
d8e2e60692 remove CreateEliminateDeadMembersPass which breaks UBO layout
this fixes a crasher when using --optimize-size
2020-05-05 18:17:31 -07:00
Philip Rideout
fb643eb422 Update web site and JS tutorials.
This updates the tutorial markdown, fixes up the literate programming
Python script, and updates the web site itself.

The doc build script now uses a Pipfile instead of "requirements.txt",
which I find less frustrating since it does not interfere with other
Python projects on your machine.

Fixes #2483.
2020-05-05 12:39:25 -07:00
Pixelflinger
e80ea979a4 improvements to DoF
- bokeh rotates with the aperture diameter
- match sample count on cpu and cpu sides which affects CoC calculation
- feather blur radius to avoid visible "steps" in bokeh size
2020-05-05 11:38:32 -07:00
Romain Guy
3e5fe994b9 Fix default lighting intensities in ModelViewer
They were waaay too high
2020-05-05 00:25:19 -07:00
Romain Guy
05def1a789 Update AGP 2020-05-04 17:55:39 -07:00
Philip Rideout
b36d29ef77 Vulkan: fix array textures.
This fixes a crash with `lightbulb -m`.

- During VkImage creation, the subresource depth should be 1 since it is
  meant for 3D textures.
- Render targets should select a single level from an array texture, not
  all of them.
- Add debug_trap to validation errors to make them easier to debug.
2020-05-04 15:51:27 -07:00
Pixelflinger
898ae083ee asserts that the engine is not terminated in flushAndWait() 2020-05-04 14:29:01 -07:00
Nakshathru Ajay
9c75c1ecfa Adding support for openjdk 13 (#2477)
Updated gradle version to 6.3 for openjdk 13 support
2020-05-04 09:15:12 -07:00
Pixelflinger
13767c3bb4 Don't use gl_FragCoord anywhere as it breaks with custom viewports
This fixes dynamic lighting and SSAO when a viewport is not in 0,0.
In practice this currently happens only when all post-processing is
disabled.

Instead of using gl_FragCoord we introduce a new API, 
getNormalizedViewportCoord(), which as the name implies returns
normalized [0, 1] viewport coordinates with origin at the bottom-left,
on all platforms.

This is implemented in this PR by interpolating gl_Position.
2020-05-01 23:51:17 -07:00
Pixelflinger
064ebd56e0 Reduce DoF sample count from 25 to 11
We keep very the same (or very close) quality by exploiting h/w
filtering. On the flip side, this is not compatible with dithering,
which is removed here.
2020-05-01 23:50:49 -07:00
Pixelflinger
b514b2e996 GL backend: Fix an issue with discardEnd flags
In OpenGL with use glInvalidateFramebuffer() for hinting controlling
the load/store of tiles. However, glInvalidateFramebuffer() conceptually
destroys the content of the framebuffer attachment.

This causes a problem when we want for instance to use a buffer for
reading only (e.g. a depth buffer) in multiple passes. In such
scenario, the attachment will be marked as "discard" (which is a
misnomer for storeOp==DONT_CARE in vulkan parlance), without the
intention of making the buffer invalid.

We fix this by ignoring the discardEnd flags entirely if a buffer
has not been written. In this case, we relying on the driver to not
write the tiles out -- but we don't have any other way to express
this in GL.

This issue cannot be encountered currently because the framegraph 
is not aggressive enough setting the discardEnd flags.
2020-05-01 18:19:23 -07:00
Philip Rideout
8c7fbb2e01 Fix stale IBL string in shadowtest sample. 2020-05-01 16:45:59 -07:00
Ben Doherty
3e67f628ee Bump version to 1.6.0 (#2474) 2020-05-01 15:58:56 -07:00
Pixelflinger
3bd1afedbd compute bitangeant in fragment shader
This saves 4 varying components.
Fixes #2092
2020-05-01 14:41:03 -07:00
Pixelflinger
f19533b149 fix a arithmetic error in SSR when a symmetry was present
Make sure that Camera returns a positive field-of-view, even when
the projection matrix has a symmetry (negative scaling).
2020-05-01 10:15:07 -07:00
Pixelflinger
dc5c48de33 fix a couple missing 'highp' qualifiers 2020-05-01 10:14:44 -07:00
Ben Doherty
fc4b88b5e9 Fix incorrect lightspace 2D bounds calculation for stable shadows (#2468) 2020-05-01 08:56:09 -07:00
Philip Rideout
116b475161 Both Vulkan timestamps should use BOTTOM.
As per the spec:

```
vkCmdWriteTimestamp latches the value of the timer when all previous
commands have completed executing as far as the specified pipeline
stage, and writes the timestamp value to memory.
```
2020-04-30 13:37:21 -07:00
Philip Rideout
cab4a660d3 Vulkan: fix race condition with queries. 2020-04-30 13:37:21 -07:00
Philip Rideout
72dafa4887 Vulkan: add support for timer queries. 2020-04-30 13:37:21 -07:00
Pixelflinger
4e873e8007 A new depth of field (DoF) post-process effect 2020-04-30 13:22:28 -07:00
Ben Doherty
64609cc4aa Update RELEASE_NOTES.md 2020-04-30 10:15:46 -07:00
Ben Doherty
8dc526b536 Update RELEASE_NOTES.md 2020-04-30 10:14:24 -07:00
Ben Doherty
0769aabf29 Add intensityCandela API to LightManager (#2465) 2020-04-30 10:12:09 -07:00
Pixelflinger
db53ce62ad fix LightManager::forEachComponent()
the Instance id was off-by-one and didn't match the
given entity.

in gltf_viewer this caused contact shadows to not work
when there was only a single directional light
2020-04-30 00:23:39 -07:00
Ben Doherty
d91eb1180f Respect all of ShadowOptions when building a light (#2463) 2020-04-29 08:46:41 -07:00
Philip Rideout
89d47eb05a Vulkan: fix lots of validation errors. 2020-04-29 08:45:23 -07:00
Ben Doherty
e985546e81 Set a clear color when no IBL is present (#2440) 2020-04-28 17:57:12 -07:00
Romain Guy
8036d65adf Don't trip assert in debug 2020-04-25 17:01:28 -07:00
Romain Guy
6a95807105 Better fix for texture unit spew 2020-04-25 16:55:30 -07:00
Romain Guy
0a387e16d9 More key fixes for ImGui 2020-04-25 16:15:32 -07:00
Romain Guy
1ec45c670b Fix more ImGui key clashes 2020-04-25 16:10:53 -07:00
Romain Guy
5a9ebf8db0 Always bind the structure sampler (#2462) 2020-04-25 14:33:48 -07:00
Romain Guy
abd852a9aa Improve matinfo output 2020-04-25 14:17:38 -07:00
Romain Guy
2c29c67df0 Cleanup on exit 2020-04-25 14:10:13 -07:00
Romain Guy
1d73027df6 Use a different key for spotLightEnabled 2020-04-25 13:59:36 -07:00
Romain Guy
54a4545ac5 Update README 2020-04-25 10:37:13 -07:00
Romain Guy
14ce9e30b9 Make the build more quiet (#2457)
* Make the build more quiet

* Add mising include
2020-04-25 01:13:30 -07:00
Romain Guy
cc6361e4f9 Make CI scripts safer (#2456)
- Added an extra README file detailing what the scripts are for
- The scripts now display a warning and a prompt before requiring user confirmation to continue
- The system install commands are only executed in CI environments (ninja and cmake being installed as root without checking for the environment was a leftover from a previous non-GitHub based CI setup)
2020-04-25 01:03:29 -07:00
Ben Doherty
45ce2d3a17 Fix crash when using free flight and hovering outside of the window (#2454) 2020-04-24 15:38:15 -07:00
Pixelflinger
1b6c25ce68 some old adreno drivers don't support bool in UBOs
Fixes #2418
2020-04-24 15:10:37 -07:00
Philip Rideout
e10530d3bb Vulkan: fix InvalidImageLayout validation errors.
It is illegal for shaders to sample from images that have a blit layout.
2020-04-24 08:47:19 -07:00
Pixelflinger
043cdcfcff simpify froxel GPU data structure
instead of storing two counters for point and spot lights, we now
only have a single counter for both, and the light data structure
has a type, the shader can use to decide what to do -- instead of
using two loops. In practice spot and point light code is very similar 
anyways. 

This simplify a lot the CPU side (as in make it less complex) and frees
up 8-bits in the per-froxel GPU data structure.
2020-04-24 01:42:27 -07:00
Pixelflinger
880bf0f061 remove the froxel remaping (unused) code
this was just an experiment, we'll never use it.
2020-04-24 01:42:27 -07:00
Philip Rideout
7bbea3e503 Vulkan: add support for 2D texture arrays.
In Vulkan, the arrayness of a texture is an aspect of the "image view",
not the image itself.

In my earlier attempt I used VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT on
the image, which MoltenVK does not support. Confusingly, that flag is
actually meant for rendering into a slice of a 3D texture, which we are
not doing.

Vulkan is hard.
2020-04-23 13:03:18 -07:00
Mathias Agopian
f8e0cedcdb Add java doc for LightManager (#2441)
* Add java doc for LightManager

Co-Authored-By: Ben Doherty <bendoherty@google.com>

Co-authored-by: Ben Doherty <bendoherty@google.com>
2020-04-23 11:02:57 -07:00
Pixelflinger
2a2c339cf5 improve code that generates froxel planes
we can calculate each plane direction from its clip-space equation
(which is trivial), instead of back-projecting 2 points and computing
the cross-product
2020-04-23 10:59:13 -07:00
Benjamin Doherty
9dcb1181f3 Fix camera mode optstr 2020-04-22 16:38:22 -07:00
Ben Doherty
09d9bbb035 Add camera flag to gltf_viewer and material_sandbox (#2438) 2020-04-22 15:23:18 -07:00
Philip Rideout
354d3222cb Vulkan: fix bad depth clears.
The Vulkan backend was failing to clear the depth buffer in apps that do
not have a textured skybox, such as hellotriangle.
2020-04-22 15:22:32 -07:00
Philip Rideout
e6be4c312b Fix warnings. 2020-04-22 15:19:37 -07:00
Philip Rideout
0e2cf44ca4 Skybox now binds dummy texture.
This fixes unbound sampler warnings, as seen in our hellotriangle app.
2020-04-22 13:08:20 -07:00
Ben Doherty
2e0e19d9ce Add a new free flight camera manipulator (#2436) 2020-04-22 13:04:19 -07:00
Pixelflinger
63b863d55d fix yet another froxelization bug
This came up when trying to use a very small number of froxels like
1x1x1 (just one!). 

Some froxels where not detected as used when scanning horizontally,
this would happen when a sphere was fully inside a froxel (i.e. not
actually intersecting any planes), and this was the very last
column on the right.

Now we use the same code we use for Z and Y (which where working fine)
for the X loop.
2020-04-22 11:51:51 -07:00
Pixelflinger
39c85dcbbb handle the case where we have only a single z-slice 2020-04-22 11:51:51 -07:00
Pixelflinger
45119fe15b fix a floating-point exception when the viewport is too small
this could lead to w/h froxel count to be 0, later leading to
divide-by-zero. There could also be a case where the viewport itself
had w/h of zero, also leading to divide-by-zero exception.
2020-04-22 11:51:51 -07:00
Pixelflinger
44c6ba2618 more clear fixes
- there was a case where setting a clear color on the Renderer
  would clear a blended view with that color instead of transparent
  pixels.

- move configuring the ui view into ImGuiHelper

- fix gltf_viewer sidebar so its background is not uninitialized
2020-04-22 00:43:37 -07:00
Pixelflinger
af48d7cff1 add a warning log when there is no texture bound to a used texture unit
sometimes this happens because the shader actually doesn't use the
texture (e.g. in a uber shader model), however this is an error in
metal and vulkan.
2020-04-22 00:43:14 -07:00
Philip Rideout
277a999bca Fix swizzle warning in WebGL. 2020-04-21 13:51:00 -07:00
Ben Doherty
f231368031 Update README on supported iOS version 2020-04-21 10:06:03 -07:00
Philip Rideout
a55b75a739 Remove monkey mesh dependency from samples.
The only apps that need this filamesh are suzanne and hellopbr. This
change allows us to modify + test Filament without re-invoking resgen.
2020-04-20 18:25:43 -07:00
Philip Rideout
f51a6aacc8 Update cgltf to fix memory leak. 2020-04-20 16:24:27 -07:00
Philip Rideout
cc61707cc2 Improve build turnaround by breaking dependencies.
This adds a new "backend_headers" target because small changes to any
backend cpp file was resulting in a huge build, causing materials to be
rebuilt, etc. Note that filabridge only needs DriverEnums, nothing else.
2020-04-20 15:37:21 -07:00
Romain Guy
e7268a0d1a Update README.md 2020-04-20 14:57:58 -07:00
Romain Guy
94f5dcc984 Update README.md 2020-04-20 14:57:13 -07:00
Romain Guy
030e97b381 Update screenshots in README.md 2020-04-20 14:56:00 -07:00
Pixelflinger
760ec8861a fix an SSAO bug with transparents objects
it's not good enough to clear the SSAO buffer, we also need to clear
*all* buffers involved in the final SSAO buffer, in particular the
bilateral blur buffers.
all this clearing is needed because we ignore skybox pixels based on the
depth buffer test, yet we need an initialized buffer.
2020-04-20 13:24:12 -07:00
Philip Rideout
4c1fb83379 sample-page-curl: move license file out of resources 2020-04-20 12:24:12 -07:00
Philip Rideout
0e39423506 Vulkan: improve staticness and constness. 2020-04-20 10:16:28 -07:00
Ben Doherty
cb53a68d71 Fix race condition with Metal timer queries (#2413) 2020-04-20 09:33:22 -07:00
Romain Guy
06593a97bb Add new --mip-levels option to mipgen (#2421)
This option (short: -m) can be used to limit the number of mip
levels generated. Using -m 1 allows to use mipgen as a cheap-ish
image converter.
2020-04-18 16:43:39 -07:00
Romain Guy
c28d9ddb9d Fix support of paletted images and alpha channel in imageio (#2420) 2020-04-18 16:32:05 -07:00
Romain Guy
038cecd8e2 Fix emissive 2020-04-17 18:46:16 -07:00
Philip Rideout
26f6349487 Update MoltenVK, enable validation. 2020-04-17 17:53:40 -07:00
Romain Guy
ddef5ec3c4 Change how emissive works (#2415)
Emissive was previously defined in exposure compensation stops, which
was confusing to many. It is now a value in nits, with the alpha
channel controlling how much the camera exposure affects the emissive.
At 0, the emissive value is just added to the final pixel color, at
1 the emissive value is multiplied by the exposure just like with
regular lights.

The intensity of the emissive property can be computed from an
exposure value (EV) easily with the following formula:

emissive.rgb = emissive.rgb * pow(2.0, EV - 3.0);

This formula is available as Exposure::luminance(float) already
in Filament.
2020-04-17 17:42:21 -07:00
Pixelflinger
56285d6227 improve contact shadows support
- contact shadows are now supported for point and spot lights
- and are now independent from regular shadows, that is they can
  be enabled without enabling regular shadows

The only limitation currently is that the distance and step count for
ALL contact shadow are taken from the directional light options.
2020-04-17 17:40:32 -07:00
Philip Rideout
0691283a99 Fix crash in "strobecolor" test. 2020-04-17 11:49:50 -07:00
Philip Rideout
1e4fa12f21 Fix IBL in hellopbr. 2020-04-17 11:47:55 -07:00
Philip Rideout
e20442cad7 Use default backend in shadowtest. 2020-04-17 11:42:15 -07:00
Ben Doherty
6555e09a96 Metal backend: get rid of non-const global variables (#2406) 2020-04-17 11:31:41 -07:00
Philip Rideout
bee9ab31bc Add new Android demo: sample-page-curl.
Pure Java app that demonstrates custom vertex shader animation and
two-sided texturing.
2020-04-17 11:12:55 -07:00
Romain Guy
6ef7f82df8 Fix debug builds 2020-04-17 10:59:39 -07:00
jaynus
6f38aaea31 Add USE_STATIC_LIBCXX to CmakeLists.txt for the ability to toggle whether to compile with static or dynamic libc++. The current configuration forces static libc++ compilations (#2410) 2020-04-17 10:23:48 -07:00
Philip Rideout
98b17780fb matc: do not crash when material passes bad out arg.
Our enum-to-string converter was throwing an exception rather than
printing a friendly error message in some cases.

To be specific, I hit this when writing:

    vec3 worldTangent;
    toTangentFrame(mesh_tangents, material.worldNormal, worldTangent);
2020-04-16 17:49:55 -07:00
Pixelflinger
3159bb2516 texture swizzling is immutable
texture swizzling is now set at creation time to accommodate 
vulkan/metal texture immutability
2020-04-16 15:23:38 -07:00
Pixelflinger
6054a28b78 fog: correct for exp2 used in the shader 2020-04-16 15:02:29 -07:00
Romain Guy
1ccb311266 Really fix the continuous builds 2020-04-16 12:44:21 -07:00
Romain Guy
8587d6b15d Fix continuous builds 2020-04-16 12:09:48 -07:00
Romain Guy
2ad1e9a9a8 Safer build script (#2403)
Fix a ton of warnings, mostly around escaping values to avoid
splitting.
2020-04-16 11:35:40 -07:00
Romain Guy
9b1a0e2f58 Remove of static JNI fields (#2400)
Static JNI lookups were causing issues with multiple libraries.
We now do the lookups when we need them as they are effectively
just hashmap lookups and we do them only in places where the
work we need to perform will be much larger than a simple hash
map lookup anyway.

This chane also manually registers filament-utils JNI bindings
to get rid of unnecessary symboles. We should do the same for
other Filament libraries (the symbols are pretty long and
we now have many of them).
2020-04-16 09:00:54 -07:00
Pixelflinger
e7df636368 fix spotlight documentation and clamping
filament spotlights use half-angles, which is the same as gltf.
2020-04-15 22:00:26 -07:00
Pixelflinger
afade93bad Fix a froxelization bug
we would be short by one froxel on the left, usually this wasn't
a problem due to the light falloff.
2020-04-15 22:00:10 -07:00
Pixelflinger
8ae8dd59b1 fix a strange static initialization problem on macOS
It looks like using `half` during static initialization causes issues,
where sometimes these values are not initialized correctly.
The problem goes away when some other random static initializer 
executes, which suggests a race, except there is only a single thread
at that point.

I think for some reason `half4` are not put in the data section where
float4 are.

note: we don't understand the exact issue yet
2020-04-15 19:13:50 -07:00
Romain Guy
bf97e7e15a Add ground-truth option to cso-lut (#2398)
The ground truth is computed using a Monte Carlo simulation.
2020-04-15 14:51:52 -07:00
Romain Guy
b29311f23e Use a simplified fast acos() for specular AO (#2397)
The two spherical caps used in the intersection computations
have angles in the range 0..pi/2.
2020-04-15 14:48:46 -07:00
Romain Guy
5d3cceb2bf Fix typos in documentation 2020-04-15 10:58:13 -07:00
Philip Rideout
c52f8908f8 Vulkan: populate all fields of VmaVulkanFunctions. 2020-04-15 10:02:39 -07:00
Pixelflinger
cb5fcbc784 get rid of the static list of Engines
Originally it was used for validating the Engine* used, but this
makes no sense (no reason to validate this pointer more than any
other one).

The list also made sure that Engine instances were automatically 
destroyed when the filament library was unloaded, but again, there
is no reason to do this -- it's C++ after all!
2020-04-14 18:48:40 -07:00
Mathias Agopian
ca7ef8cbae Fix point/spot lights when viewport is not in 0,0 (#2392)
the problem was that the actual viewport's origin can be different
from the viewport set by the user, for instance when the view is
rendered in an intermediate buffer.
2020-04-14 18:48:04 -07:00
Pixelflinger
ed326e1e68 Implement texture swizzling 2020-04-14 18:46:21 -07:00
Romain Guy
8094955fc1 Add new tool cso-lut (#2394)
* Add new tool cso-lut

This tool is for internal usage only. It computes a 3D lookup table
for cone/sphere occlusion computations. These can be used to implement
specular occlusion, directional ambient occlusion, etc.

* Improve generated comment

* Fix Windows build
2020-04-14 18:22:56 -07:00
Pixelflinger
d31f57eb22 ssao blur: don't forget to attach the depth buffer
the depth buffer in this case is only used for 
skipping the skybox
2020-04-13 15:54:44 -07:00
Pixelflinger
ada5444997 fix issues with ignoring beginFrame() return value
ignoring beginFrame() return value is allowed, but doing so would
leave filament in an invalid state.

we now make sure that we don't execute any code after determining whether
the frame should be skipped, and execute the remainder of beginFrame() 
upon the first call to render(View*).

We also make sure the FrameSkipper can deal with its endFrame() being 
called when the current fence hasn't signaled.
2020-04-13 15:54:29 -07:00
Romain Guy
3c26c2cec1 Fix another typo 2020-04-13 15:47:43 -07:00
Romain Guy
7cdc0c032f Fix typos 2020-04-13 14:27:31 -07:00
Philip Rideout
854fcc7eac Desktop samples now use default backend.
There is nothing specific to Vulkan in these tests, I meant to remove
the backend override when I removed the `vk_` prefix last week.
2020-04-13 13:55:32 -07:00
Ben Doherty
0e82fdbddd Use the correct size for the ImGui glyph atlas (#2386) 2020-04-13 12:56:55 -07:00
Ben Doherty
f26b761d72 Revamp MetalFence and implement Metal sync objects (#2380) 2020-04-13 10:22:42 -07:00
Philip Rideout
167493b85c Update Skybox / Clear API for web. 2020-04-10 17:06:47 -07:00
Pixelflinger
7fc60db151 update Release Notes 2020-04-10 17:05:40 -07:00
Mathias Agopian
1b36f82c1e API BREAKAGE: this change aims to fix multi-view support (#2376)
* API BREAKAGE: this change aims to fix multi-view support


What has changed:
- View doesn't have a notion of clear color anymore
- View doesn't have a notion of discard flags anymore
- The clear color and color-buffer discard/clear flags are moved to Renderer
- Skybox can now be set to a constant color
- View have a blend-mode

What does is all mean:
"Clearing" (i.e.) setting its background is now handled by Skybox, by
setting a constant color to the Skybox. This should take care of
drawing views side by side.

When a view needs to be drawn on top of another, it's BlendMode needs to
be set to TRANSLUCENT and of course and, generally, it wither won't have
a skybox, or will have one that sets some translucent pixels.

As an optimization, a View with BlendMode::OPAQUE will have its
background cleared with the color specified in Renderer.

If the SwapChain already has some content, it's now possible to set
the Renderer to not discard the content, together with TRANSLUCENT views,
it's possible to draw on top of that content.


It is NOT possible to share depth/stencil buffers between views.

Fixes: #2369, #2372, #2364

* Address reviewers comments.

Note: WebGL is still broken with this PR
2020-04-10 15:54:14 -07:00
Romain Guy
95c8dd0185 Update README.md 2020-04-10 11:26:06 -07:00
Ben Doherty
63801d2460 Implement headless swapchains on Windows (#2374) 2020-04-09 15:09:18 -07:00
Ben Doherty
a60ee4914f Fix getRootAssetsPath on Windows (#2375) 2020-04-09 13:01:25 -07:00
Mathias Agopian
d4f9ede84b improve DisplayHelper to handle frame rate changes (#2366) 2020-04-09 11:32:22 -07:00
Pixelflinger
6bb909bd0e newly created color buffers were not cleared properly
there were cleared with the view's clear color instead of 0
2020-04-09 11:30:31 -07:00
Romain Guy
c5a5d15fe3 Fix Vulkan linking with specific versions of CMake 2020-04-09 08:50:44 -07:00
Romain Guy
c69547f8ea Only build x86 and arm64-v8a in presubmit (#2370)
* Only build x86 and arm64-v8a in presubmit

* Pass the ABI arguments to the build script

* Pass comma delimited list to Gradle
2020-04-08 18:43:15 -07:00
Romain Guy
1ef3535ba7 Expose Java API to control discard flags (#2368)
* Expose Java API to control discard flags

This change also adds the new sample sample-multi-view that shows
how to use discard flags to render multiple views.

* Disable clears
2020-04-08 16:03:49 -07:00
Romain Guy
3945c232d7 Build all ABIs by default with Gradle 2020-04-08 15:36:49 -07:00
Romain Guy
db18b2e07b Add the ability to build speific ABIs for Android (#2367)
For instance to build only 64 bit variants:
./build.sh -q x86_64,arm64-v8a release

This change also cleans up build.sh and Gradle files.
2020-04-08 15:06:47 -07:00
Pixelflinger
a9814f8a88 Improve dynamic resolution tracking
This new code is better able to reach the desired target as it 
continuously evaluates the best scale factor based on the current
known state.
2020-04-08 11:27:34 -07:00
Pixelflinger
2adfb259c6 fix shader overflows leading to black pixels
we clamp the output of post_process materials to 0,FLT16_MAX
2020-04-08 11:27:18 -07:00
Pixelflinger
240d8cd79b improve latency a bit
we now flush the backend (e.g. GL) after the color pass, this a 
good time because a lot of GPU work has been queued by that point, this
allows the GPU to start while we queue the post-processing commands.
This reduces latency by about 2.5ms on pixel4.
2020-04-08 11:27:03 -07:00
Romain Guy
85c563b628 Fix BusterDrone
Some parts where marked as transparent but they truly are opaque.
This was causing issues with SSAO.
2020-04-08 11:18:56 -07:00
Philip Rideout
68a78a77a8 gltfio-lite: remove tex matrices, spec-gloss, etc.
gltfio-lite now has its own template file rather than re-using the
ubershader one, which allows us to optimize the materials by removing
support for various glTF extensions like texture matrices,
specular-glossiness, and clear coat.
2020-04-07 20:36:05 -07:00
Philip Rideout
ad27d10503 Do not clobber VK_ICD_FILENAMES.
Fixes #2343
2020-04-07 16:28:01 -07:00
Philip Rideout
1366e3dcd1 gltfio: simplify skinning processing.
Moved all the skinning processing into one place.
2020-04-07 16:23:46 -07:00
Romain Guy
52086fe4d5 Remove debug code 2020-04-07 15:55:52 -07:00
Logan Lawrence
d99f9cffb2 GEOSP-97 Added javascript binding 2020-04-07 13:09:48 -07:00
Logan Lawrence
33cbc6bba3 GEOSP-97 Added comments 2020-04-07 13:09:48 -07:00
Logan Lawrence
7794cd4c65 GEOSP-97 Removed some unnecessary changes 2020-04-07 13:09:48 -07:00
Logan Lawrence
574058e81e Added and updated javascript bindings 2020-04-07 13:09:48 -07:00
Pixelflinger
3ad4f2eceb fix a some problems with timer queries in the OpenGL backend
in OpenGL we need to check the status of queries on the gl thread,
so we did this in when beginFrame was called -- however, this is
too late, because beginFrame is asynchronous, so we were always
behind by 1 frame.

we fix this by running the callbacks more often.
2020-04-07 12:16:09 -07:00
Alexey Pelykh
56d9e1f727 Fix Gltfio.init(): call Filament.init() as well 2020-04-07 10:01:51 -07:00
Romain Guy
7c8849065c Update release notes 2020-04-07 09:38:23 -07:00
Romain Guy
bf0dc32ee3 Change specularAmbientOcclusion from boolean to enum (#2352)
The user can now choose amongst 3 specular AO methods:
- None, specAO is off
- Simple, specAO is inferred from roughness and diffuse AO
- Bent normals, specAO is computed accurately from cone intersections

The last method is more expensive but produces the best results.

This change also fixes a few issues:
- Rename materialRefraction() and materialRefractionType() for
  consistency
- Fixes user time in shaders
2020-04-07 09:19:48 -07:00
Pixelflinger
887f8e8a1c better GPU timings on Android
On drivers that don't implement timer queries properly, we use
fences instead, however we can't use a fence to determine the start
time of the GPU work (only the end time). To workaround this we
use the last call to glFlush() as a proxy.
At least on Pixel it works very well.

We also remove all mid-frame calls to flush(), we did this to kick
cpu work early, but it's not as efficient as overlapping the work
with the previous frame, it increases latency a bit though.
2020-04-07 00:30:59 -07:00
Pixelflinger
b1f95646d9 Add "sync" objects to the driver
A sync object for us is like a fence that cannot be waited on. It can
only be queried.
This is useful for filament to know if (not when) some previous
commands have finished executing.

In OpenGL this is different from "fences" which only exist in EGL and
can be waited on from any thread.
"sync" objects correspond to GLsync object in OpenGL and are widely
supported, as opposed to EGL fences.

So we use the term "fence" to refer to synchronization object that are
external to OpenGL and the term "sync" for the native gl synchronization
objects. This distinction may or may not exist in other APIs.


rewrite the FrameSkipper to use this, which enables it on MacOS.
2020-04-06 21:09:28 -07:00
piggie
a282da78cd Adds texture support to filagui
Stores font texture as RGBA instead of R. This is because the ui material will not be compatible for RGBA textures, as it is expecting an R texture. I was unable get a texture with ALPHA format to function as I wanted.

This also removes material instance caching by scissor rect. Instead it just assigns the scissor rect to each new primitive, as well as an optional texture.
2020-04-06 19:21:20 -07:00
Pixelflinger
746e273336 rework how dynamic resolution scaling is specified
- now the DynamicResolutionOptions don't specify the target frame rate,
  they only specify how to scale this given view

- there is a new FrameRateOptions setting on Renderer, which is used
  to specify the desired target frame rate for the whole Renderer

- the frame rate is now specified as a "frame interval" in units of
  the display frame period.

- the display frame period is (indirectly) set via DisplayInfo.

In other words, the use must set (and update) DisplayInfo properly
(the default are reasonable, but assume 60 Hz). They must also set the
desired interval (default is 1, which is probably what you want).
Finally they must enable dynamic scaling per View, the defaults are
also reasonable.

Currently Renderer doesn't attempt (yet) to actually target the
requested frame rate, so it's up to the caller to push frames at the
desired speed. however, dynamic resolution, like before, will attempt
to shrink work to fit the target.
2020-04-06 16:55:24 -07:00
Pixelflinger
b2dd6683be Add a way to query and set Display information
Renderer can now be given a DisplayInfo that contains some
important information about the current display. This will be used
for frame-pacing and dynamic-resolution.

This is most relevant on Android, where we can accurately query these
parameters. Added support for that in our samples.


This also sets the minSDK to 19 (including gltf viewer's), since this is
the version we support. We were cheating before by under-reporting our
minSdk.
2020-04-06 16:55:24 -07:00
Pixelflinger
526898e7d6 add vsync timestamp to Renderer::beginFrame() API 2020-04-06 16:55:24 -07:00
Pixelflinger
00f1c3dae9 [GL backend] ensure that Handle<> are synchronously constructed
Until now, only the memory of Hw handes was allocated synchronously,
handles were constructed later asynchronously. This was error prone
with the few (but growing) synchronous calls we have.

Now we have an init<> call that allocates and constructs handles synchronously,
the asynchronous construction if needed, is still performed with construct<>,
which is now implemented as "destroy+construct", this is okay because
most of our handles have trivial dtors.

This fixes a race with TimerQuery and Fence. Fences are still not fully 
working though, but at least won't access uninitialized memory.
Currently backend fences MUST be used trough FFence.
2020-04-06 16:44:35 -07:00
Ben Doherty
bb88487b79 Fix test_material_parser build issue creating resource directory (#2350) 2020-04-06 15:33:25 -07:00
Romain Guy
92b7ee97f5 Kill specular AO at low roughness (#2348)
On metals (made only of specular light), specular AO can
create large black spots. This change simply kills specular
AO to avoid this artifact. In practice we should take into
account multiple bounces but this is rasterization...
2020-04-06 15:30:32 -07:00
Romain Guy
72056ee9e3 Fix support for 565 textures (#2347)
* Fix support for 565 textures

This requires exposing a new USHORT_565 pixel data type.

* Update JS bindings
2020-04-06 12:01:41 -07:00
Romain Guy
6330b1625c Udpate to AGP 3.6.2 2020-04-06 09:28:54 -07:00
Benjamin Doherty
27f4504dfc Implement timer queries for Metal backend 2020-04-03 18:10:39 -07:00
Pixelflinger
fb0e89d969 fix a race-condition in JobSystem
mThreadMap needs to be protected as it's accessed from multiple threads.
2020-04-03 17:25:17 -07:00
Ben Doherty
2ad932f345 Convert from half to full angles for gltfio spot lights (#2340) 2020-04-03 17:06:03 -07:00
Philip Rideout
d8ac60009c FilamentApp: use angle bracket syntax for includes. 2020-04-03 16:28:38 -07:00
Philip Rideout
37e2f46e10 Move FilamentApp into libs/filamentapp.
This will make it easier to migrate gltf_viewer into tools.

This is not a rewrite of FilamentApp, just a baby step.
2020-04-03 16:28:38 -07:00
Romain Guy
17dd44fd91 Fix documentation bug: the definition of SPOT and FOCUSED_SPOT was inverted. 2020-04-03 15:53:33 -07:00
Philip Rideout
26297feba7 WebGL: fix typo in default SSAO options. 2020-04-03 12:37:40 -07:00
Philip Rideout
05bc60f953 Bump version number to 1.5.2 2020-04-02 17:15:04 -07:00
Ben Doherty
df2caf4f62 Expose setCulling to public RenderableManager API (#2331) 2020-04-02 17:07:19 -07:00
Philip Rideout
2dbe0b64be gltfio misc fixups 2020-04-02 14:54:19 -07:00
Philip Rideout
c79f5a1a29 JobSystem: replace TLS with tid mapping. 2020-04-02 14:53:20 -07:00
Philip Rideout
e072e30841 Expose Engine's JobSystem. 2020-04-02 14:53:20 -07:00
Pixelflinger
aa770d54ae fix a potential use-after-free
It's possible for a timer query to be destroyed before the result is
known, in this case, we don't want to write through that pointer!
2020-04-02 12:02:21 -07:00
Romain Guy
559642d54c Move IBL settings in their own category 2020-04-02 10:49:07 -07:00
Philip Rideout
583157d4ef Remove vk_ prefix from desktop samples. 2020-04-02 09:06:50 -07:00
Philip Rideout
44422b3d69 Remove gltf_baker and related libraries. 2020-04-02 09:06:29 -07:00
Philip Rideout
f084e50829 Remove old bloom samples to avoid confusion.
These should not be confused with our core bloom feature. For testing
the RenderTarget API, it would be better to create a small focused demo.
2020-04-02 09:05:36 -07:00
Pixelflinger
e8a7d9f0c2 add support for timer queries in the backends
This adds a simple query API to the backend.
There are 2 methods to create/destroy queries, which are
essentially futures.  And 3 methods to mesure elapsed time:
beginTimerQuery/endTimerQuery and getTimerQueryValue.
The begin/end pair is not nestable.

On the GL backend side, there are 2 implementations of this, one uses
arb_timer_query or disjoint_timer_query, the other uses fences.
We need both implementations because on some GPUs, including
qualcomm's elapsed-time timer query is useless, as it measures
cpu time. 

Metal/Vulkan implementations will be part of subsequent PRs. Vulkan
will be able to implement this with vkWriteTimestamp which is
reported to be accurate.

An immediate benefit is that we can now get frame times on MacOS, which
should allow it to use dynamic-resolution.
2020-04-01 22:18:50 -07:00
Pixelflinger
a389de3deb enable dynamic-resolution in android gltf viewer 2020-04-01 22:18:50 -07:00
Romain Guy
06eca637b0 Remove a mul from specular AO computations 2020-03-31 22:55:05 -07:00
Romain Guy
201bd2c845 Fix release action 2020-03-31 18:09:29 -07:00
Romain Guy
e6500a8b3b Update web docs 2020-03-31 18:07:40 -07:00
Romain Guy
db6636aff8 Preserve dependency version 2020-03-31 17:39:21 -07:00
Romain Guy
ef35654ce9 Update to v1.5.1 2020-03-31 16:06:44 -07:00
Pixelflinger
4248eb148e fix uninitialized variable which could cause clearing errors 2020-03-31 15:31:54 -07:00
Pixelflinger
73c2a87444 fix a clearing bug with imported rendertargets
the view clear flags would not be honored when rendering directly
into an imported render target.

note: now that this works this could cause an issue when using
multiple views side-by-side and one of them doesn't have a skybox,
that view will trigger a clear of the whole buffer (because clears
clear everything, not just the viewport).
A solution will come in a later PR.

Fixes #2312
2020-03-31 15:31:38 -07:00
Philip Rideout
55d0063ced Fix "no texture bound" warnings in WebGL. 2020-03-31 15:20:18 -07:00
Ben Doherty
ca70489556 Add a material parser presubmit check (#2313) 2020-03-31 15:04:01 -07:00
Philip Rideout
8d817ac787 ShadowMap: Fix potentially wrong EntityManager. 2020-03-31 14:39:09 -07:00
Romain Guy
9a550d69b8 Fix Github actions 2020-03-31 09:33:28 -07:00
Romain Guy
07d6aebafc Update release action 2020-03-30 21:48:41 -07:00
Romain Guy
32604e2c57 Fix sample-textured-object 2020-03-30 18:54:46 -07:00
Romain Guy
adb107afc2 Fix sample-gltf-viewer 2020-03-30 18:53:14 -07:00
Romain Guy
8d9bd5f4fa Fix flavor dependencies, introduce flavors for filament-utils 2020-03-30 18:28:18 -07:00
Ben Doherty
c88bbc21d0 Link hello-gltf iOS project with Draco (#2311) 2020-03-30 17:11:49 -07:00
Romain Guy
917edec0a7 Update RELEASE_NOTES.md 2020-03-30 16:22:45 -07:00
Philip Rideout
34959dd5e8 New version number for release notes, npm, maven. 2020-03-30 16:19:37 -07:00
Ben Doherty
82ab74efb0 Update RELEASE_NOTES and LightManager documentation for spot shadows (#2310) 2020-03-30 16:14:07 -07:00
Pixelflinger
968dbdb847 make sure "structure" pass is culled when not needed
the structure (depth path) wasn't culled even if both ssao and
contact-shadows were disabled.
2020-03-30 16:13:41 -07:00
Philip Rideout
e43466d2bc Enable Draco for WebGL and iOS. 2020-03-30 15:58:55 -07:00
Philip Rideout
cdf03f91c9 Apply Draco compression to FlightHelmet. 2020-03-30 15:58:55 -07:00
Philip Rideout
abe70caeae Bump material version to prep for release. 2020-03-30 15:58:35 -07:00
Philip Rideout
4891bb6157 Fix SameSite warning for locally run web samples. 2020-03-30 15:58:24 -07:00
Ben Doherty
f5e6ec42b3 Fix draco build with Xcode (#2306) 2020-03-30 15:06:53 -07:00
Romain Guy
92b2dd835d Add support for bent normals (#2303)
* Add support for bent normals

Bent normals can be enabled via the bentNormal property of a material.
When specular occlusion is enabled, bent normals improve the quality
of the computation.

* Save a couple of multiplications in bent specular AO
2020-03-29 17:00:03 -07:00
Philip Rideout
76f0309b58 Remove unused Draco targets from build. 2020-03-27 17:07:55 -07:00
Philip Rideout
d9e9fabec5 Disable unused Draco features. 2020-03-27 16:32:44 -07:00
Philip Rideout
a922e914b4 Enable Draco for Android. 2020-03-27 16:32:44 -07:00
Philip Rideout
4b7677fd13 Apply Draco compression to BusterDrone. 2020-03-27 16:32:44 -07:00
Ben Doherty
0474a6b8b5 Try to fix Windows build by reducing disk space footprint (#2301) 2020-03-27 16:05:50 -07:00
Philip Rideout
241f08bd74 Draco: do not add files to the build root. 2020-03-27 13:59:41 -07:00
Ben Doherty
b8f8067a87 Support lights in gltfio (#2288) 2020-03-27 13:56:28 -07:00
Pixelflinger
965777da85 fix an assert() when using custom render targets
we now always mask out target bits that don't exist in the render
target before converting them to GLenums.

Fixes #2285
2020-03-27 13:45:54 -07:00
Romain Guy
ffa62d4236 Check for CMake version before setting the policy 2020-03-27 11:50:21 -07:00
Romain Guy
94a01c6010 Be compatible with CMake 3.10 again (#2296)
* Be compatible with CMake 3.10 again

* Windows fix

* Add CMake changes to patch file
2020-03-27 11:15:18 -07:00
Romain Guy
232bf728c6 Update readme for Windows 2020-03-27 09:31:50 -07:00
Romain Guy
0e367580da Update CMake requirement to 3.12 2020-03-27 09:25:23 -07:00
Romain Guy
40aad197da Fixes various issues (#2292)
* Fixes various issues

- Fix gltf_baker crash
- Fix Python3 discovery on macOS
- Fix TBB CMake warning
- Fix bent normals baking

* Find Python 3 on Windows
2020-03-26 22:53:44 -07:00
Kai Chieh Liu (KJ) 劉凱傑
124fd2c978 Fix NameComponentManager dependency and Android build (#2291) 2020-03-26 20:02:03 -07:00
Philip Rideout
0d32c58e41 gltfio: add support for Draco (desktop only)
This needs a bit more testing before merging, but I wanted to put up the
PR for review. I will look into supporting Android after we land this.

Fixes #1932.
2020-03-26 19:52:26 -07:00
Romain Guy
09fa87ddfa Update README.md 2020-03-26 16:58:51 -07:00
Pixelflinger
cb356606d9 fog improvements
- handle heightFalloff=0 (i.e. fog doesn't depend on height) correctly,
  previously, a divide-by-zero on the cpu side would get in the way.
  The fix is to clamp heightFalloff to a small-enough value, and to
  make sure that this is handled correctly in the shader.

- default fog distance is 0 instead of 1m

- inScatteringSize parameter should be allowed to be large in samples
2020-03-26 16:01:56 -07:00
Kai Chieh Liu (KJ) 劉凱傑
3de9cc1533 Expose Renderable::getLayerMask() (#2289)
TEST: built on mac

Co-authored-by: KJ Liu <kjliu@amazon.com>
2020-03-26 15:31:38 -07:00
Ben Doherty
f1aaf16082 Add spot light controls to material_sandbox (#2270) 2020-03-26 13:29:39 -07:00
Kai Chieh Liu (KJ) 劉凱傑
4c23f7a436 Fix cmakelist to install subdir properly (#2283) 2020-03-25 18:20:24 -07:00
Pixelflinger
2188923153 Fix fog with transparent objects 2020-03-25 17:10:36 -07:00
Romain Guy
2f47bab237 Update README screenshots 2020-03-25 14:23:36 -07:00
prewettg
fe547a7690 Fixes resizing window not resizing the framebuffer on macOS (#2281) 2020-03-25 14:03:49 -07:00
Pixelflinger
b4f5a4a0a0 Fog improvements
- optimized the fog computations
- fixed issues with the skybox
- added the option of getting the fog color modulated by the IBL envmap
2020-03-24 22:29:25 -07:00
Pixelflinger
5929d5d9dd improve quality of diffuse sampling on desktop
We 4-tap filter the diffuse map, which generally is very small
(e.g. 16x16), to improve quality a bit.
2020-03-24 22:28:59 -07:00
Romain Guy
0b7de0ec65 Turn off contact shadows by default in gltf viewer (#2277) 2020-03-24 16:44:48 -07:00
Romain Guy
87ac282014 Export missing headers for NameComponentManager (#2276) 2020-03-24 16:32:48 -07:00
Pixelflinger
e525a7c7c4 enable some more features in lightbulb
spotlight/contact shadows, ssao, fog, bloom.
2020-03-24 16:15:58 -07:00
Romain Guy
8a84c7f0a3 Install all public headers from libutils 2020-03-24 15:46:23 -07:00
Ben Doherty
e462c22a07 Fix MetalBufferPool crash in completion handler (#2273) 2020-03-24 12:35:54 -07:00
Philip Rideout
3ea8a25127 Add Draco 1.3.6 to third_party. 2020-03-24 10:13:13 -07:00
Romain Guy
45df197bd6 Expose libutils APIs that should have been public (#2269)
* Expose libutils APIs that should have been public

* Don't make JobSystem public for now
2020-03-24 09:57:04 -07:00
Philip Rideout
1ecb83bf73 gltfio: Big internal refactoring / simplification.
This replaces the "bindings" structures with simple types that re-use
data structures from cgltf.

This also moves some trivial work from ResourceLoader to AssetLoader,
which simplifies the communication between these two classes.

Motivated by #1932.
2020-03-24 09:22:20 -07:00
Ben Doherty
aefa03291e Fix spot light shadow bugs related to light culling (#2264) 2020-03-23 16:12:44 -07:00
Pixelflinger
6e02fa186a generateMipmap needs at least 2 levels allocated 2020-03-23 15:05:00 -07:00
Pixelflinger
756074d8bd don't generate fog code in post-process materials 2020-03-23 15:04:42 -07:00
Pixelflinger
2caa09bebd Fix IBL mip calculation
The max mip (i.e. mip at roughness 1) was off by one.
2020-03-23 15:04:24 -07:00
Ben Doherty
72a182122a Update spirv-cross to 871c85d (#2262) 2020-03-20 16:59:47 -07:00
Pixelflinger
0688db7da3 fix a shadow clipping bug
In some situations the shadow map would be too aggressively clipped.
This was due to a bug in the box-frustum intersection algorithm, which
could fail when some vertices of the frustum were inside the box, and
some vertices of the box inside the frustum and the total number
of vertices such classified was 8.
2020-03-20 11:13:18 -07:00
Mathias Agopian
0c6d96c407 Add support for basic fog (#2256)
* Add support for basic fog

* address reviewers comments
2020-03-19 18:01:07 -07:00
Pixelflinger
1f48bd3e79 fix contact-shadows with shadow multiplier 2020-03-19 18:00:41 -07:00
Ben Doherty
7103f4f0b3 Share material dictionaries between GLSL / MSL (#2252) 2020-03-19 11:16:01 -07:00
Ben Doherty
210234255c Fix contact shadow GLSL compilation error (#2254) 2020-03-18 10:05:58 -07:00
Romain Guy
73312bc6bb Update README.md 2020-03-17 12:42:23 -07:00
Pixelflinger
6ea9872a3e fix computation of shading_posiiton for clip space domain shader
When reconstructing the position from clip-space, we need to apply
the .w divide.

Also use getWorldFromClipMatrix() directly.
2020-03-17 00:01:50 -07:00
Mathias Agopian
d54ceff7a3 Add support for screen-space contact shadows (#2245)
* Add support for screen-space contact shadows

This CL adds support and always enables it.
toggles and setting in the next CL (same PR).

* Plumb settings for screen-space contact shadows

screen-space contact shadows is handled like a shadow option,
parameters (including on/off) are set in the LightManager, using
the existing ShadowOptions API.

Additionally there is a per-renderable toggle.

Both toggles are off by default.

* Allow contact shadows when shadowing is auto-disabled


Shadowing can be auto-disabled when for instance there are no
shadow casters in the scene. We still allow contact shadows in
that case.

This would allow for instance, to make the vegetation on a terrain
not shadow-casting, and still get some shadowing there by using
contact shadows instead.

* apply micro-shadowing after contact shadows

also, don't compute contact shadows when we know we're fully shadowed.
2020-03-16 22:39:24 -07:00
Ben Doherty
6cf3e86c8a Fix iOS build samples CI (#2249) 2020-03-13 14:34:37 -07:00
Ben Doherty
acc36e8d9b Deprecating Clang on Windows in CMakeLists (#2243) 2020-03-13 12:33:02 -07:00
Pixelflinger
1670e73287 Revert "enable ASAN's -fsanitize=address in debug builds"
This caused failures in CI builds.

This reverts commit c132ede510.
2020-03-13 11:20:47 -07:00
Romain Guy
3b52b89fd6 Update release notes 2020-03-12 19:18:55 -07:00
Pixelflinger
c132ede510 enable ASAN's -fsanitize=address in debug builds 2020-03-12 19:18:29 -07:00
Pixelflinger
4e62e4f696 include alpha-masked objects in SSAO
this helps a lot with vegetations, which often uses alpha masking
2020-03-12 19:17:39 -07:00
Pixelflinger
c0addf22ed Cleanup render loop to prepare for more features
- decouple the depth and ssao passes, so that the depth
  pass could be used by another client, down the framegraph

- set uniforms/samplers from the execute closure of the color pass,
  instead of using a separate pass. This is more correct and it 
  potentially reduces calls to commitUniforms.

- make setSampler check that the value set is different,
  the idea here is that it's much more costly to have to commit the
  samplers rather than having to compare them. Also realistically we
  don't have a lot of samplers in a frame, so that's not a lot of
  compares.

- one downside of this change is that commands for the SSAO pass are
  always generated, we will fix that in an upcoming change.
2020-03-12 14:31:56 -07:00
Romain Guy
880642ef4a Fix crash in glTF sample for Android 2020-03-12 14:27:11 -07:00
Pixelflinger
2f94e5990c workaround a framegraph bug with imported rendertargets
Imported render targets are only partially implemented, which
caused a discard flags bug. It would happen when an imported
 render target is used more than once like when using SSrefr
without tone mapping.  In that case, the 2nd pass would use the same
discard flags as the first pass.
2020-03-11 22:58:22 -07:00
Pixelflinger
4a5ce16322 Trivially make LinearAllocator 16 bytes instead of 24 2020-03-11 17:04:08 -07:00
Pixelflinger
454b08362d minor code cleanups
- go through 'FIXMEs' & `TODOs` and either fix or remove obsolete ones.
- add a few asserts
- fix some comments and IDE warnings
2020-03-11 17:04:08 -07:00
Ben Doherty
f80c584db0 Update glslang to dbb56a1 (#2232) 2020-03-11 12:34:08 -07:00
Pixelflinger
68bcd6c159 fix setting an array mat3 as a parameter of material instance
this actually makes it possible to set mat3s from java.
2020-03-11 12:26:52 -07:00
Pixelflinger
a9a9061f96 update GLSLPostProcessor optimization passes to latest
deactivate "mergeReturnPass" because it triggers a segfault with
AMD drivers on MacOS.
2020-03-11 11:11:28 -07:00
Pixelflinger
196c98fc2a Fix framebuffer clears
We make sure to only (and always) clear newly allocated buffers,
but only clear existing buffers based on the user request. This
should allow to share the depth buffer between drawing two
Views (if post-process is disabled). This should also fix 
a bug where the intermediate buffer wasn't cleared when blending
a view on to of another.

This should fix #2138
2020-03-11 11:11:09 -07:00
Ben Doherty
9ea2e69579 Fix gltf_viewer (#2233) 2020-03-10 17:57:59 -07:00
Ben Doherty
f4da2ef8ec Add support for spot light shadows (#2209) 2020-03-10 17:53:25 -07:00
Pixelflinger
8fb65a19b4 fix utils::ctz() when builtins are not available
Our fallback 64-bits ctz() was completely wrong. 
The unit tests were wrong too.
2020-03-10 15:41:43 -07:00
Ben Doherty
a2c6c34739 Update SPIRV-Tools to 2020.1 / SPIRV-Cross to 65aa0c3 (#2121) 2020-03-10 15:32:41 -07:00
Romain Guy
a2818037b3 matinfo can print dictionaries, shrink Metal dictionary (#2230)
This change adds new commands to matinfo to print dictionaries.
This feature is useful to debug dictionaries, and I just used
it to identify that using a shared dictionary would save ~12 KiB
in the Android build. The macOS build (GLSL + Metal) would go
down to 71 KiB from 136 KiB.

The SPIRV to Metal conversion leaves leading spaces and some
comments. This change also runs the shrinker on optimized Metal
shaders to further reduce the size of shaders.
2020-03-10 11:42:19 -07:00
Romain Guy
02c7a22d43 Remove build time warning 2020-03-10 08:41:28 -07:00
Pixelflinger
f6e993dfc8 fix bloom upsample shaders
We were not using the correct offsets, however because everything
was so blurry, it wasn't obvious that something was wrong.
This should result in a bit smoother bloom effect.
2020-03-08 22:28:25 -07:00
Pixelflinger
8866e2829f Add a quality option to dynamic-scaling
It controls the quality of the upsampling filter. This can help a lot
if heavy scaling is needed to maintain performance, it also helps if
MSAA is not enabled.

There are 3 quality levels, low, medium and high. 1, 4 and 9 bilinear
taps are used for each level respectively. The high quality setting
employs a tent filter.
2020-03-08 22:28:10 -07:00
Matthias Moulin
d016e0f443 Replaced unnecessary std::forward with std::move
`execute` is an rvalue reference and not a forwarding reference, so `std::move` is more appropriate
2020-03-08 22:27:46 -07:00
Pixelflinger
0cbf6f8d76 disable spinlocks on ARMv7
we've had issues with some devices running in arm mode, where they
would throw spurious SIGILL on the WFE instruction used in spin locks.
Since on Android Mutexes are very efficient, we just use that instead.

This might fix #2197
2020-03-07 13:54:58 -08:00
Romain Guy
641b58c409 Be explicit about which NDK to use (#2221) 2020-03-06 16:53:41 -08:00
Romain Guy
5f0204f7b1 Clean build script 2020-03-06 15:36:14 -08:00
Romain Guy
660d1a1800 Enforce NDK 21 2020-03-06 15:24:45 -08:00
Pixelflinger
8d209a16c5 framegraph: destroy resources in reverse order
This is so that render targets are destroyed before their
attachments. In practice it doesn't matter too much, at least
on OpenGL, but it is cleaner.
2020-03-06 11:21:35 -08:00
Pixelflinger
ed786701fc The FrameGraph is now emitting debug markers
A debug marker is emitted for each pass.
This greatly improves debugging with RenderDoc for instance.
2020-03-06 11:21:17 -08:00
Mathias Agopian
4842b1ca13 rework stream operators for libmath
libmath itself doesn't expose any stream operators anymore. However,
libutils is able to automatically print libmath types into its
io::ostream -- however matrices are not formatted nicely.

Added a new optional library, libmathio, that provides std::ostream
operators for all libmath types. libmathio does a better job at
formating matrices.

Also removed apply() and map() from libmath because there were not used
anywhere and they forced us to depend on <functional> in public headers.
2020-03-05 22:50:49 -08:00
Ben Doherty
0990550f45 Fix, mathfwd does not work correctly with MSVC (#2214) 2020-03-05 17:46:21 -08:00
Romain Guy
84b215c3b0 Switch to AGP 3.6.1 2020-03-05 17:11:47 -08:00
Ben Doherty
2a7724f601 Introduce ShadowMapManager class (#2207) 2020-03-05 15:32:00 -08:00
Ben Doherty
b119d763da Fix visibility mask, encode enough SENTINEL commands (#2210) 2020-03-05 15:31:38 -08:00
Mathias Agopian
ff25e6c18f Add support for MRT in the framegraph 2020-03-05 13:17:18 -08:00
Mathias Agopian
2677f05f0d get rid of the 'ignoreScissor' flag in beginRenderPass
The scissor is now always ignored -- i.e. when we clear, the whole
surface is cleared, which echoes how discard flags work. 
Geometry must be used to clear only a sub-region of the screen.

This simplifies a lot of things because we had workaround for Adreno
GPUs, which were slow when clearing with the scissor enabled.
2020-03-05 13:17:18 -08:00
Mathias Agopian
bbfa47bbf0 More MRT support in the GL backend
in particular, we can now clear the proper draw buffer and
basic functionality works (tested on Adreno with systrace)
2020-03-05 13:17:18 -08:00
Mathias Agopian
060c0d2e6f remove discardSubRenderTargetBuffers() which isn't used right now 2020-03-05 13:17:18 -08:00
Romain Guy
414396efb6 Add background color selector to gltf_viewer 2020-03-05 12:58:52 -08:00
Philip Rideout
6825781718 gltf_viewer: fix string lifetime for #2190. 2020-03-05 09:26:27 -08:00
Ben Doherty
2494fff094 Refactor renderable partitioning scheme for spot light shadows (#2195) 2020-03-04 20:46:35 -08:00
Ben Doherty
924422261f Update ShadowMap for spot light shadows (#2206) 2020-03-04 20:20:32 -08:00
Philip Rideout
f81e819901 gltfio: simplify API, privatize bindings.
The binding list can be internalized, clients should instead use
`getResourceUris` and `ResourceLoader` to load external resources.
2020-03-04 16:30:12 -08:00
Ben Doherty
81a2d70251 Use array texture for shadow maps (#2199) 2020-03-04 11:59:25 -08:00
Ben Doherty
3a2a40c76a Add additional shadow info to lights uniform (#2200) 2020-03-04 11:58:51 -08:00
Ben Doherty
6c3fa13e41 Changes to frameUniforms for spot shadows (#2201) 2020-03-04 11:58:31 -08:00
Philip Rideout
0ea2354be5 More TypeScript annotations. 2020-03-04 11:20:01 -08:00
Mathias Agopian
079056cfbc major FrameGraph rewrite (#2202)
Major changes are:

- RenderTarget are now real resources as opposed to ad-hoc objects.
  This allows to remove a lot of code and simply a lot of things.

- ResouceNode now have a level of indirection (i.e. we store a pointer
  to them), which allow fast and more correct implementation of
  moveResource(). 
  A new unit test checks that all scenarios of moveResource with a 
  generic resource are working.

- We have a special version of moveResource that moves a RenderTarget
  resource into a TextureResource -- this shouldn't be allowed, but
  this helps make the API better. What it means is that
  "all rendertargets that use the specified texture as attachment
   are replaced with the given rendertarget".

- In this version there are a lot of limitations when moving
  a rendertarget into a texture resource; be we cover the case that
  is useful to us.
2020-03-04 11:13:29 -08:00
Philip Rideout
1230fccbf9 JavaScript: Expose bloom and SSAO options.
Fixes #2198.
2020-03-04 08:43:20 -08:00
Ben Doherty
73e0facaed Save spot light outer clamped radius in light manager (#2193) 2020-03-03 14:25:26 -08:00
Ben Doherty
94b1ad52fa Add new Shadows uniform buffer (#2194) 2020-03-03 14:25:03 -08:00
Philip Rideout
6878d0d6e6 npm package now has a gl-matrix dep.
Our wasm API does not actually use gl-matrix, but we do import it
from our TypeScript declarations file.
2020-03-03 09:46:53 -08:00
Ben Doherty
76e7568994 Add visibility mask to RenderPass (#2183) 2020-03-02 16:14:52 -08:00
Romain Guy
b176b2f0e6 Remove broken setLensProjection API (#2192) 2020-03-02 14:35:35 -08:00
Ben Doherty
af5805e396 Update XcodeGen and iOS sample projects (#2191) 2020-03-02 12:54:17 -08:00
Romain Guy
b98f45df60 Fix WebGL build (#2189) 2020-02-29 09:14:49 -08:00
Romain Guy
bb2571233d Update RELEASE_NOTES 2020-02-28 23:50:35 -08:00
Romain Guy
00629bac48 Add camera controls to gltf_viewer (#2188)
Exposure: shutter speed, aperture and ISO
Focal length

The shadow plane can now be toggled  at runtime.
2020-02-28 23:46:17 -08:00
Romain Guy
81e7f619eb Try to fix compilation error on Android (#2187)
* Try to fix compilation error on Android

* Try with a newer NDK...
2020-02-28 13:10:16 -08:00
Ben Doherty
b0ab9bb697 Remove unnecessary quotes from shader (#2186) 2020-02-28 10:50:52 -08:00
Romain Guy
ae1e6f43f2 Only compile materials for Vulkan when necessary 2020-02-28 09:51:47 -08:00
Romain Guy
6eba2f145e Properly fetch project properties (#2185) 2020-02-28 09:20:35 -08:00
Romain Guy
13666027cc Switch native code API level back to 21 2020-02-28 07:55:09 -08:00
Ben Doherty
62cef096e1 Refactor computeVisibilityMasks logic, visibility bits (#2179) 2020-02-27 16:28:47 -08:00
Mathias Agopian
af48b60876 split FrameGraphPassResources out of FrameGraph.cpp 2020-02-27 14:15:26 -08:00
Mathias Agopian
b71357a955 Allocators shouldn't crash when allocation fails
The allocator debug code didn't check that allocations where
successful before filling buffers.
2020-02-27 14:15:11 -08:00
Romain Guy
9865a609da Refactor Gradle files (#2180)
We now share all the C++/CMake flags from the root project.
2020-02-27 12:46:01 -08:00
Romain Guy
77bafb295e Fix library loading issue on API level 22 and below (#2178)
This change fixes #2176
2020-02-27 11:30:47 -08:00
Philip Rideout
ba4c9dbd09 Vulkan: use GENERAL layout for render target textures.
This fixes the validation error that occurs when rendering to one
miplevel while sampling from another. It might even be faster since
fewer layout transitions are required.
2020-02-27 09:33:38 -08:00
Mathias Agopian
4e9cf8ac02 Fir a deadlock when exiting on MacOS (GL backend)
Closes #2159

There was two issues:
1) Fence::wait would return prematurely when the the timeout was
   set to WAIT_FOREVER.

2) (At least) when running from the command line, events were not
   read from the main queue. Instead we have to use NSRunLoop instead
   of NSApplication APIs.
2020-02-27 09:33:14 -08:00
Romain Guy
108dae11e9 Add ground shadow option to gltf_viewer (#2174)
* Add ground shadow option to gltf_viewer

The shadow is always positioned at the bottom of the loaded object's
bounding box to ground it perfectly.

* Remove unused include
2020-02-26 17:09:31 -08:00
Benjamin Doherty
16de98291f Fix Metal filtering bug 2020-02-26 16:00:01 -08:00
Benjamin Doherty
547f8917b4 Update comment 2020-02-26 15:58:16 -08:00
Benjamin Doherty
f1da2ca643 Update RELEASE_NOTES 2020-02-26 15:58:16 -08:00
Benjamin Doherty
9e6ea9454f Refactor depth variant 2020-02-26 15:58:16 -08:00
Pixelflinger
fcd7e198c2 First step in reworking how rendertargets work in the framegraph
The ultimate goal is to get rid of the concept of render targets in
the framegraph, and this is the first step. Here RenderTarget doesn't
store the discard flags anymore. These flags are now calculated
per-resource, per-pass.

A side effect of this change is that the discard flags are now slightly
better, as they don't contain attachments that don't exist.
i.e. we won't see the STENCIL flag set for instance.
2020-02-26 15:57:42 -08:00
Pixelflinger
82523bd1d3 Add support for MRT to the backend
- this simply changes the createRenderTarget() API to take an
  'MRT' structure for the color attachment. The MRT structure is
  just a wrapper around an array of four TargetBufferInfo.

- in this PR only implemented for OpenGL
2020-02-26 11:39:57 -08:00
Romain Guy
4ec5fac95c Add support for KHR_materials_clearcoat to gltfio (#2169) 2020-02-26 10:11:34 -08:00
Pixelflinger
7fb3810eb1 cleanup command stream parameter passing
- the tuple<> where we store the parameters should only remove the
  reference, but not decay, so that arrays could theoretically
  be stored (more on this below).

- use std::forward<> instead of std::move<> in Command's ctor, this is
  more appropriate, we just want to forward the arguments unchanged.

- add std::move() to all parameters on the command stream stub, it is
  appropriate here, because we receive parameters by value or r-value 
  references.

All this was an attempt to support C-style arrays as parameters, but
it doesn't work because they are decay'ed to pointers when they
appear as parameters.
2020-02-25 21:29:59 -08:00
Romain Guy
ed2fe83491 Update cgltf to latest (#2168) 2020-02-25 19:21:48 -08:00
Philip Rideout
3fd9c49fb9 Update WebGL docs and website. 2020-02-25 13:50:34 -08:00
Philip Rideout
69c0843d20 MaterialInstance refactor duplicated code. 2020-02-25 13:43:32 -08:00
Philip Rideout
3f7ef9738d Fix regression with getDefaultInstance().
This caused color writes to be disabled in our "hello triangle" samples.

Fixes #2164.
2020-02-25 13:43:32 -08:00
Romain Guy
3cfc6981a4 Only build OpenGL and Vulkan shaders in Android samples 2020-02-25 10:24:25 -08:00
Romain Guy
8b2ea72be2 Fix emissive in unlit shaders
This change applies exposure compensation just like with
lit shaders.
2020-02-25 09:47:06 -08:00
Romain Guy
8eaa1f5e88 Add options to skip samples (#2163)
-DFILAMENT_SKIP_SAMPLES=ON with CMake
-Pfilament_skip_samples with gradle

This change also renames CMake options specific to Filament
to avoid clashes with subprojects.
2020-02-24 18:15:33 -08:00
Pixelflinger
c72f622a87 Minor changes to SAO
- minor uniform optimizations (saves ~0.1ms)
- fix some missing highp precision qualifers
- make it easier to tweak the blur filter
- make sure samples's radius goes from 0 to 1
- update comments
2020-02-24 18:06:49 -08:00
Ben Doherty
8a0505eb6f Fix Metal crash on Catalina (#2161) 2020-02-24 17:18:43 -08:00
Romain Guy
799e837f35 Upgrade to latest AGP 2020-02-24 12:28:29 -08:00
Philip Rideout
4690ce5602 WebGL: Improve the callback API for glTF.
After the native async functionality landed, there was no way for web
clients to be notified that the decoding has finished. This PR changes
the existing `onDone` callback so that it gets called after all textures
have been decoded. (Previously it was called after downloading rather
than decoding.)

This has the side effect of simplifying the API because clients no
longer need to call a finalize function.
2020-02-24 11:38:55 -08:00
Philip Rideout
e972126cea Add missing TypeScript declarations.
This patches up all the holes discovered when I tried porting the
fidelity tests in `model-viewer` to our TypeScript declarations.
2020-02-24 09:35:22 -08:00
Mathias Agopian
db40fd8983 More accurately evaluate the size of MSAA textures 2020-02-22 00:18:30 -08:00
Mathias Agopian
c2db7b8afd fix a crasher when enabling bloom from java 2020-02-21 16:55:59 -08:00
Philip Rideout
f403876784 Fix JNI signature for RenderTarget API.
Fixes #2151
2020-02-21 15:08:47 -08:00
Mathias Agopian
3a9d4c7c77 Another SSAO optimization saving another ~16%
During the SSAO pass, we pack the decoded depth to the GB channels of
the AO texture, which reduces our bandwidth requirements during the
blurring pass, as well as some ALU usage.
It puts SSAO at about 2ms on pixel4/1080p.
2020-02-21 14:15:06 -08:00
Mathias Agopian
e737ece570 rollback misguided "optimization"
use gpu's sin/cos instead of approximation
2020-02-21 14:15:06 -08:00
Philip Rideout
948d19c446 Fix typo in upload script. 2020-02-20 16:31:57 -08:00
Philip Rideout
ee81c9516a gltfio full flavor should use the old aar and maven names.
This should fix the Android build break. We do not want to change the
maven package name for existing gltfio clients.
2020-02-20 15:05:31 -08:00
Pixelflinger
675012a2eb Added a quality level parameter for SSAO
Currently it only selects how many samples are used.
Low,medium,high and ultra respectively map to 7,11,16 and 32 samples.
The default is "low", which is sufficient for most mobile applications.
2020-02-20 11:26:10 -08:00
Pixelflinger
31a4ef10e1 Use a smoother falloff function.
The improvement is really subtle, it makes the SSAO effect a bit 
softer.
2020-02-20 11:26:10 -08:00
Philip Rideout
a0d43d51c9 Add gradle flavor for gltfio-lite.
This cribs the strategy from filamat-lite and also fixes a "more than
one file" gradle error.
2020-02-20 09:45:33 -08:00
Philip Rideout
31035d2b3c Optimize filament-utils (230 KB => 190 KB). 2020-02-20 09:45:33 -08:00
Mathias Agopian
4e8f323e47 Reduced AO processing time by 1/3
This is achieved by computing a small 2x2 box blur in the AO pass
taking advantage of quad shading, which allows to halve the size
of the bilateral blur kernel.

Reducing the size of the blur kernel has a side effect to kick Adreno
gpu into direct mode, which apparently is much faster here.

Overall we go from 3.4ms to 2.4ms on Pixel4.

The quality is impacted, but not severely. This probably assumes 
GPU that have working derivatives.
2020-02-19 22:09:53 -08:00
Pixelflinger
4dd3d7ab5e Greatly improve SSAO quality by using better samples
The power parameter now really controls the contrast. It's default value
is now 1, instead of 0.
2020-02-19 22:09:53 -08:00
Mathias Agopian
63a7bf5ee9 tweak SSAO
- got rid of all the precomputed samples for now, it makes things
  much more simple, and actually doesn't slow things down. Use the
  analytic offsets (spiral) instead.

- use textureLod instead of texelFetch in places where we need to do
  how own clamping, turns out it's faster (as measured on pixel4).

- use a interleaved gradient noise instead of a hardcoded blue noise,
  the difference isn't big.

Overall we're actually 0.2ms faster out of 3.5ms. It's not immediately
clear why, might just be noise.
2020-02-19 22:09:53 -08:00
Romain Guy
0473da9f05 Add support for ccache (#2148)
* Add support for ccache

To benefit from ccache, first install ccache (for instance with
brew install ccache on macOS). On my machine a clean build takes
~5 minutes the first time. A second clean build with ccache enabled
takes 34 seconds.

* Enable more aggressive caching
2020-02-20 11:36:36 +09:00
Pixelflinger
e5447f7417 Cleanp-up PostProcessManager a bit 2020-02-19 14:41:00 -08:00
Ben Doherty
62810d8c87 Rework array texture support (#2136) 2020-02-19 10:52:12 -08:00
Philip Rideout
ca81d48432 gltfio-lite: add BLEND material
This increases the size to 538K.
2020-02-18 11:55:47 -08:00
Philip Rideout
b9c857130a Introduce gltfio-lite.
This is 466 KB insted of the usual 850 KB. It assumes that users do not
need spec-gloss, non-lit, or a special transparency mode.

(uncompressed SO size on arm64)

We can add a new maven project for this next week.
2020-02-18 11:55:47 -08:00
Philip Rideout
a9bbc6d3c4 Fix syntax error in TypeScript annotations. 2020-02-17 09:26:27 -08:00
Pixelflinger
3a273b1837 fix a typo when thresholding for bloom
- also use step() to implement the threshold
- improve bloomOptions documentation
2020-02-15 22:19:35 -08:00
Romain Guy
5e6ff5a44f Update to a more recent version of AGP 2020-02-14 15:26:05 -08:00
Philip Rideout
65129d1b52 filament-utils-android: fix recent crash regression. 2020-02-14 14:56:38 -08:00
Philip Rideout
54d9d870ee gltfio size reduction 3/3: compile gltfio directly
This takes libgltfio-jni.so from 882 KB to 850 KB
2020-02-14 14:56:38 -08:00
Philip Rideout
ffff6dd580 gltfio size reduction 2/3: proper shared linking
This takes libgltfio-jni.so from 966 KB to 882 KB
This takes libfilament-jni.so from 810 KB to 802 KB
2020-02-14 14:56:38 -08:00
Philip Rideout
dc4a1ed5e5 gltfio size reduction 1/3: add more opt flags
This takes libgltfio-jni.so from 1.5 MB to 966 KB.
2020-02-14 14:56:38 -08:00
Mathias Agopian
8bbf0ce9ef Bloom can now have a dirt texture applied 2020-02-13 20:51:43 -08:00
Romain Guy
a4e4021950 Update README.md 2020-02-13 20:03:51 -08:00
Mathias Agopian
87fe48225f On mobile, use a more efficient up-sampler
This doesn't affect quality significantly, but saves 30% of gpu time
on the upsampling, overall it's about 0.1 ms. This brings The bloom
effect below 2ms on Pixel4.
2020-02-13 17:40:55 -08:00
Ben Doherty
af47fa9b6d Fix incorrect twoPassesOneSide rendering with Metal (#2133) 2020-02-13 17:32:26 -08:00
Mathias Agopian
3de1e197aa improve SSrefr highlights at low roughness
We untonemap/tonemap the first level of blur to reduce the very high
frequencies due to HDR highlights in the image, this produce a softer
image at higher roughness. This can programmatically be turned off,
but that setting is not exposed.
2020-02-13 12:26:25 -08:00
Mathias Agopian
2a1cbe67c6 Improve bloom performance on mobile
The very first downsample stage costs us a lot because it reads from
a full-res texture. We mitigate this by always doing a blit to
1/4 res. Blits are quite a bit faster, this saves about 1ms on
Pixel4.
2020-02-12 17:19:26 -08:00
Mathias Agopian
f57404a3f0 split downsample and upsample passes 2020-02-12 17:19:26 -08:00
Mathias Agopian
87d815c659 Minor cleanup. Add FTexture::maxLevelCount()
We were computing this is many places. Validate better SSAO depth
buffer size.
2020-02-12 17:19:26 -08:00
Mathias Agopian
651ccb183e New mathfwd.h header
math/mathwfd.h forward declares all {mat|vec}{2|3|4}<> classes,
which allows us to remove their respective #include in a lot of
our public headers.
Our math headers are full of templates, so this should help build times
a bit.

Also we want to keep the public headers as minimalist as possible.
2020-02-12 15:30:13 -08:00
Philip Rideout
67406c42ec Clamp viewport width to prevent floating point exception.
To trigger an exception users could either shrink the window or enlarge
the sidebar. Constraining both of these is somewhat tricky so let's
just clamp the viewport width at a low level.
2020-02-12 12:07:51 -08:00
Philip Rideout
cb953b4203 Remove usage of <regex> from Path.
There was actually no need to give special treatment to leading drive
designators since they effectively form the first path segment anyway.
To help prevent regressions, I added a few unit tests in a previous CL.

The motivation for the CL is to remove a dependency on `locale.cpp`,
which can result in shorter build times and reduced binary sizes.
2020-02-12 10:03:06 -08:00
Philip Rideout
c0e2cfb684 Minor enhancements to test_Path. 2020-02-12 10:03:06 -08:00
Philip Rideout
9358c7313e Remove STL from ResourceLoader API. 2020-02-12 10:03:06 -08:00
Philip Rideout
02b377c244 gltfio: remove locale.cpp dependency
For Android and wasm we do not use the filesystem and therefore do not
need `utils::Path`.

```
libgltfio-jni.so BEFORE 1.9 MB (693 KB gzipped)
libgltfio-jni.so AFTER  1.4 MB (542 KB gzipped)
```
2020-02-12 10:03:06 -08:00
Romain Guy
d2287f584a Fix comment 2020-02-11 17:33:56 -08:00
Mathias Agopian
cc94820cb3 clean-up of dynamic scaling code 2020-02-11 16:31:21 -08:00
Mathias Agopian
b17c51e340 Add a threshold option (enabled by default) for bloom.
Threshold can be either on or off, and only thresholds at 1.0 when 
activated (in pre-exposed mode).

This allows to use very high strengths values for the bloom without
softening the rest of the image, and is useful for artistic considerations.
2020-02-11 16:15:04 -08:00
Romain Guy
34dcc90ac7 Save a couple of mul 2020-02-11 16:12:23 -08:00
Mathias Agopian
8a1dc0ac65 Make sure sun in the skybox blooms enough
This is a temporary (hopefully) hack to make the skybox sun look 
better when bloom is enabled (this doesn't affect how the "sun" lights
objects, only how it looks in the skybox).
This scale factor was adjusted empirically.
2020-02-11 16:12:23 -08:00
Philip Rideout
a61bc51271 Add Java bindings for SurfaceOrientation.
Note that libgeometry is already included in `filament-android`, this
simply exposes more of its existing functionality.

The Java version of SurfaceOrientation is similar to the JavaScript
version because we are bundling it into the main Filament package, even
though it is a separate library in C++. This is much simpler than
creating a brand new Java package.

New Android sample that tests this is forthcoming.

Fixes #1729.
2020-02-11 12:38:06 -08:00
Mathias Agopian
bccb8260e2 Implement a Bloom post-process effect 2020-02-11 12:15:57 -08:00
Philip Rideout
bedc609051 RenderPass: remove overrideMaterial. 2020-02-10 17:05:02 -08:00
Mathias Agopian
f1cab9296a Fix a SSRefr when dynamic-scaling is enabled
because the intermediate buffer could have non-square pixels, blurring
the buffer would result in an anamorphic blur.

We fix this by properly scaling the buffer before blurring.
2020-02-10 16:07:40 -08:00
Philip Rideout
4665f6027f Add dynamic raster states to MaterialInstance.
Fulfills a request from tirichards@.

This is similar in some ways to dynamic backface culling but simpler
because there is no interaction with double-sided lighting.

For reference, dynamic backface culling was implemented with #1936, #1877, #1641.
2020-02-10 14:33:14 -08:00
Philip Rideout
891e85ba2b gltfio: add nominal support for flat shading.
This "fixes" the new animated Fox model in the glTF conformance suite.
As per the glTF spec, we now generate per-face normals for the case
where normals are not specified in the model.

Note that true flat shading (i.e. flat interpolation) is not a
requirement in the glTF spec, since some Khronos members advocate for
WebGL 1.0 compatibility.

Fixes #2088.
2020-02-10 14:29:04 -08:00
Mathias Agopian
6957f54547 improve SSRefr roughness with very strong highlight
Chose a filter width that preserve the "gaussianness" of the 
blur filter.
2020-02-10 11:22:15 -08:00
Ben Doherty
48ba111ccc Fix crash in Metal backend with screen-space refractions (#2104) 2020-02-10 10:34:44 -08:00
Philip Rideout
8f2df79a96 gltfio: clean up finalize(). 2020-02-07 18:54:46 -08:00
Philip Rideout
415aeef95b gltfio JNI: fix broken getName() method. 2020-02-07 17:15:28 -08:00
Philip Rideout
cabd9be5f0 ModelViewer now implements OnTouchListener for convenience. 2020-02-07 15:20:41 -08:00
Philip Rideout
45e6e6eb18 sample-gltf-viewer now supports landscape orientation. 2020-02-07 15:20:41 -08:00
Philip Rideout
b89cac48c5 gltfio: fix regression with un-textured renderables. 2020-02-07 09:44:42 -08:00
Mathias Agopian
00d55cddb5 fix screen-space refraction roughness calculation (#2108)
It turns out that textureLod() only reads the base layer if the sampler
is not set to xxx_MIPMAP_xxx. This prevented the gaussian-blur code
to work properly.
Specifically, the horizontal pass would always use the base layer. Not
only this made the blur unstable, but also hurt performance significantly.

With this change, the untonamap/tonemap is no longer needed and the 
results are much more convincing with objects with highlights.
2020-02-07 08:55:23 -08:00
Romain Guy
88dd32b1a7 Add emissive to material_sandbox 2020-02-06 16:20:22 -08:00
Mathias Agopian
20e7acd24d fix a typo in blit post-process material 2020-02-06 15:32:25 -08:00
Romain Guy
9be871f14b Don't use a LOD bias but a specific LOD in SSAO code 2020-02-06 15:31:33 -08:00
Pixelflinger
0b358081c3 make the gaussian blur pass more generic
the input and output are now separate (don't need to be the same
texture)
2020-02-06 14:37:04 -08:00
Mathias Agopian
d172ae78fd minor improvements to SSRef code 2020-02-06 13:05:25 -08:00
Pixelflinger
5f1c9bc41b More comments and small bug fixes regarding MSAA
- always take the "blit" path (rather than quad path) when MSAA
  and is on. we now rely on the render target to have been resolved
  into its texture (implicitly or explicitly). This means in some cases
  there will be 2 bliss in a row -- but that's still better than a
  blit and a quad. These are unavoidable without using a custom resolve.

- removed creating renderbuffer with the EXT_multisampled_render_to_texture
  extension because we didn't support it fully and didn't support
  the fallback mode (for desktop or if the extension is not there).
  Also this case never happens currently.

- added more assert()

- added a bunch of comments explaining the restrictions of using MSAA
  regarding blitting.
2020-02-06 13:05:02 -08:00
Philip Rideout
317d78d7c6 sample-gltf-viewer: enable gzip compression for bin and ktx. 2020-02-05 18:45:30 -08:00
Romain Guy
46090793a8 Fully document refraction properties 2020-02-05 17:45:03 -08:00
Romain Guy
c3a995dd3d Update README.md 2020-02-05 11:01:26 -08:00
Philip Rideout
8020f7eb78 gltfio: add plural version of popRenderable 2020-02-04 12:47:32 -08:00
Philip Rideout
e8e847a662 gltfio: various cleanup in response to PR review 2020-02-04 12:47:32 -08:00
Philip Rideout
d2c883877d gltfio: hide entities with not-yet-ready textures.
This feature adds one new method to `FilamentAsset` and uses it in our
Kotlin, JavaScript, and C++ helpers:

    utils::Entity popRenderable() noexcept;

This pops a ready renderable off an internal queue, or returns 0 if no
renderables have become ready. It provides a simple way for clients to
gradually add renderables to the scene as they become ready. Previously
clients could only get the entire list of entities, regardless of
whether they had Renderable components or complete textures.

To facilitate this feature, this PR adds a new internal-only class to
gltfio called `DependencyGraph`, which is a temporary object used for
bookkeeping during the asynchronous load.

`DependencyGraph` discovers ready-to-render entities by tracking the
textures that each entity depends on. This is a graph because
renderables connect to a set of material instances, which in turn
connect to a set of parameter names, which in turn connect to a set of
texture objects. These relationships are not easily inspectable using
the Filament API or ECS.
2020-02-04 12:47:32 -08:00
Romain Guy
0f7f6f6004 Update to cgltf v1.5 (#2097) 2020-02-04 12:27:38 -08:00
Philip Rideout
ebadf9d6a3 Fix gradle invocation in build.sh for Vulkan. 2020-02-04 11:06:20 -08:00
Philip Rideout
94fb74d6aa Missing backend now throws Java exception, not segfault.
If a client application selects a backend that is not supported by the
build, Engine::create() now returns null, which allows the Java wrapper
to throw IllegalStateException. Prevously, we would crash in the native
layer by hitting a null pointer in Engine::loop().
2020-02-04 11:06:20 -08:00
Mathias Agopian
60b664d3b9 rework refraction filtering/blurring to improve performance
We now use a fixed-size kernel (right now 17), for each mip-level.
And we workout the mapping from roughness to such mip.

This improves performance by reducing significantly the number of taps
per mip, however, we don't control how much blur is actually applied
at each level. This gives a mip-chain that is proportional to
'roughness'.

It's now easier to tune quality vs. speed by tweaking the kernel's width
as well as how we map 'sigma' to a the kernel width.
2020-02-03 11:45:17 -08:00
Romain Guy
eee9249dfc Fix table 2020-02-03 09:35:30 -08:00
Philip Rideout
7f7625b4a0 gltfio internal rename: URL => URI 2020-01-31 09:31:04 -08:00
Philip Rideout
c681cd243a gltfio: Introduce the asynchronous API and use it.
We were already using jobs for decoding PNG and JPEG files, but we were
doing a join. This add three methods to ResourceLoader that allow
clients to amortize the decoding process across multiple frames, even on
single-threaded platforms like WebGL.

This PR adds async loading to the following demos:
- samples/gltf_viewer (now shows a progress bar in the UI)
- android/sample-gltf-viewer
- web/samples/helmet.html

Fixes #1876.
2020-01-31 09:20:48 -08:00
Romain Guy
503e66790b Docs fixup 2020-01-30 17:52:39 -08:00
Romain Guy
a8dc91c238 Update static version of Materials.md.html 2020-01-30 17:46:46 -08:00
Romain Guy
bc554f77f4 Add documentation for refractive materials 2020-01-30 17:43:21 -08:00
brian.wang
dada7332c6 fixed compile error by vs2019 (#2087) 2020-01-30 16:50:23 -08:00
Philip Rideout
02b1d0a950 Add validation to VertexBuffer::build()
Clients should be prevented from allocating unused buffer slots because
uploading to an unused slot triggers undefined behavior in the backend.

Motivated by #2042
2020-01-30 15:25:18 -08:00
Pixelflinger
bcde742bbc Revert "wip: rework filtering"
This reverts commit 79a83e8c46.
2020-01-30 11:37:41 -08:00
Mathias Agopian
79a83e8c46 wip: rework filtering 2020-01-30 11:33:06 -08:00
Mathias Agopian
3d56ff3547 Process SSR buffer in 11.11.10 format
This will help reducing bandwidth requirements while not affecting
quality significantly.
2020-01-30 11:33:06 -08:00
Mathias Agopian
218c3af11b Fix documentation about Camera's field-of-view. 2020-01-30 11:32:46 -08:00
Philip Rideout
ad20a312d6 gltfio: refactor to prep for async API.
This adds most of the asynchronous functionality but does not expose it.
2020-01-30 08:53:01 -08:00
Benjamin Doherty
ad788d6338 Fix some warnings 2020-01-29 13:33:02 -08:00
Benjamin Doherty
02b2b79060 Fix iOS samples 2020-01-29 13:32:45 -08:00
Mathias Agopian
610dca88a3 Remove everything related to the depth-prepass
depth-preass is no longer supported.
2020-01-29 13:32:45 -08:00
Romain Guy
00a6a68b9c Update Gradle plugin 2020-01-29 11:52:20 -08:00
Ben Doherty
7852fd2ffb Build iOS samples during CI jobs (#2076) 2020-01-29 10:59:19 -08:00
Mathias Agopian
ead4b1d222 Stabilize the blur with an invertible tone-mapping
This helps if some refracted objects have very strong highlights.
2020-01-29 10:17:08 -08:00
Mathias Agopian
f290742f1b Screen-space refraction
With this PR screen-space refraction is functional.

Caveats:

The blur passes for supporting rough refractive materials is quite
heavy and increases with the resolution.

SSR uses a gaussian approximation for the brdf and therefore doesn’t
match perfectly cubemap-based refraction and IBL.

The use of MSAA with screen-space effects, while working, is going
to incur a large cost, especially on tilers.
2020-01-29 10:17:08 -08:00
Mathias Agopian
b31f267467 Get one step closer to have screen-space refraction
In this PR we look for object rendered with refraction
(which currently never happens), and split the command buffer into
two passes in that case.
2020-01-29 10:17:08 -08:00
Mathias Agopian
47db11a205 Added a post-process resolve() and blit() utility pass
- resolve can be used when resolving a multi-sample color
  buffer is needed

- quadBlit() can be used to blit a texture using a quad.
2020-01-29 10:17:08 -08:00
Mathias Agopian
b263a89b07 Use SFINAE for Material::setParameter
This gives us a compile time error instead of link-time error, when
using a parameter type not supported. The code is also a bit more
self-documenting.
2020-01-29 10:17:08 -08:00
Mathias Agopian
dbe01d76a2 Minor shader improvement to the bilateral blur 2020-01-29 10:17:08 -08:00
Romain Guy
aa3b0a4e16 Add --single to only edit the first renderable 2020-01-28 17:12:20 -08:00
Philip Rideout
ff66e980eb Add ResourceLoader::hasResourceData. 2020-01-28 14:51:02 -08:00
Philip Rideout
6fbf8a8be0 Fix event pumping with non-owned platforms.
Tested with WebGL and macOS.
2020-01-28 13:39:58 -08:00
Philip Rideout
1452ce62f4 Remove srcDirs hack, use packagingOptions / exclude. 2020-01-28 12:31:14 -08:00
Philip Rideout
d84d095c97 The Android support libs now use dynamic linking.
In my first attempt I kept the multiple project-level dependencies in
each sample's `build.gradle` but that resulted in a gradle error
concerning multiple copies of the same SO file. To work around this
we now append to "srcDirs" to bring in Java dependencies rather than
using project-level dependencies.

The new APK contents are now much more reasonably sized:

    libfilament-jni.so         981 KB
    libgltfio-jni.so           817 KB
    libfilament-utils-jni.so    96 KB

Previously this was:

    libfilament-utils-jni.so    1.8 MB
    libgltfio-jni.so            1.8 MB (unused)
    libfilament-jni.so          1 MB (unused)

Fixes #2070
2020-01-28 12:31:14 -08:00
Philip Rideout
e1b498f82c Repair iOS error due to STBI_NO_STDIO.
Fixes #2072.
2020-01-28 12:26:31 -08:00
Benjamin Doherty
06726fe361 Regenerate Xcode project for hello-ar iOS sample 2020-01-28 11:09:34 -08:00
Ben Doherty
ba3a274357 Fix headers in iOS samples (#2074) 2020-01-28 10:56:28 -08:00
Romain Guy
30a3d31a3d Update README 2020-01-27 13:46:56 -08:00
Romain Guy
191c89c3b1 Exclude .kt files from javadocs 2020-01-27 13:46:25 -08:00
Romain Guy
42b739154e Update Maven library version 2020-01-27 13:30:34 -08:00
Philip Rideout
721a251b34 Bump package.json to 1.4.5 2020-01-27 13:02:19 -08:00
6557 changed files with 616195 additions and 707899 deletions

View File

@@ -3,7 +3,9 @@ name: Android
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-android:
@@ -11,10 +13,10 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/android && ./build.sh continuous
cd build/android && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-android
@@ -22,7 +24,7 @@ jobs:
- uses: actions/upload-artifact@v1.0.0
with:
name: filamat-android-full
path: out/filamat-android-full-release.aar
path: out/filamat-android-release.aar
- uses: actions/upload-artifact@v1.0.0
with:
name: filamat-android-lite
@@ -31,6 +33,10 @@ jobs:
with:
name: gltfio-android-release
path: out/gltfio-android-release.aar
- uses: actions/upload-artifact@v1.0.0
with:
name: gltfio-android-lite-release
path: out/gltfio-android-lite-release.aar
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-utils-android-release

View File

@@ -3,7 +3,9 @@ name: iOS
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-ios:
@@ -11,11 +13,14 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/ios && ./build.sh continuous
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous

View File

@@ -3,7 +3,9 @@ name: Linux
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-linux:
@@ -11,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/linux && ./build.sh continuous
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-linux

View File

@@ -3,7 +3,9 @@ name: macOS
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-mac:
@@ -11,10 +13,10 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/mac && ./build.sh continuous
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-mac

View File

@@ -12,20 +12,21 @@ jobs:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
cd build/$WORKFLOW_OS && ./build.sh ${TARGET}
env:
TARGET: presubmit
cd build/$WORKFLOW_OS && printf "y" | ./build.sh presubmit
- name: Test material parser
run: |
out/cmake-release/filament/test/test_material_parser
build-windows:
name: build-windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
build\windows\build-github.bat presubmit
@@ -36,33 +37,30 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/android && ./build.sh ${TARGET}
env:
TARGET: presubmit
cd build/android && printf "y" | ./build.sh presubmit
build-ios:
name: build-iOS
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/ios && ./build.sh ${TARGET}
env:
TARGET: presubmit
cd build/ios && printf "y" | ./build.sh presubmit
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh presubmit
build-web:
name: build-web
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/web && ./build.sh ${TARGET}
env:
TARGET: presubmit
cd build/web && printf "y" | ./build.sh presubmit

View File

@@ -30,20 +30,19 @@ jobs:
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
run: |
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
cd build/$WORKFLOW_OS && ./build.sh release
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
DATE=`date +%Y%m%d`
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${DATE}-mac.tgz; fi;
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${DATE}-linux.tgz; fi;
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
TAG: ${{ steps.git_ref.outputs.tag }}
@@ -62,18 +61,17 @@ jobs:
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
run: |
cd build/web && ./build.sh release
cd build/web && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
DATE=`date +%Y%m%d`
mv out/filament-release-web.tgz out/filament-${DATE}-web.tgz
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
TAG: ${{ steps.git_ref.outputs.tag }}
@@ -92,22 +90,23 @@ jobs:
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
run: |
cd build/android && ./build.sh release
cd build/android && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
DATE=`date +%Y%m%d`
mv out/filament-android-release.aar out/filament-${DATE}-android.aar
mv out/filamat-android-full-release.aar out/filamat-${DATE}-full-android.aar
mv out/filamat-android-lite-release.aar out/filamat-${DATE}-lite-android.aar
mv out/gltfio-android-release.aar out/gltfio-${DATE}-android.aar
mv out/filament-utils-android-release.aar out/filament-utils-${DATE}-android.aar
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
python3 build/common/upload-assets.py ${TAG} out/*.aar
env:
TAG: ${{ steps.git_ref.outputs.tag }}
@@ -126,18 +125,17 @@ jobs:
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
run: |
cd build/ios && ./build.sh release
cd build/ios && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
DATE=`date +%Y%m%d`
mv out/filament-release-ios.tgz out/filament-${DATE}-ios.tgz
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
TAG: ${{ steps.git_ref.outputs.tag }}
@@ -157,7 +155,7 @@ jobs:
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
shell: bash
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -167,8 +165,7 @@ jobs:
- name: Upload release assets
run: |
pip3 install PyGithub
DATE=`date +%Y%m%d`
mv out/filament-windows.tgz out/filament-${DATE}-windows.tgz
mv out/filament-windows.tgz out/filament-${TAG}-windows.tgz
python build/common/upload-assets.py ${TAG} out/*.tgz
shell: bash
env:

View File

@@ -3,7 +3,9 @@ name: Web
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-web:
@@ -11,10 +13,10 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
cd build/web && ./build.sh continuous
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v1.0.0
with:
name: filament-web

View File

@@ -3,7 +3,9 @@ name: Windows
on:
push:
branches:
- master
- main
- release
- rc/**
jobs:
build-windows:
@@ -11,7 +13,7 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1.0.0
- uses: actions/checkout@v2.0.0
- name: Run build script
run: |
build\windows\build-github.bat continuous

1
.gitignore vendored
View File

@@ -9,7 +9,6 @@ dist-*
toolchains
filament/docs/html/**
.vscode
gltf_baker.ini
*tmp*.png
civetweb.txt
/TAGS

81
BRANCHING.md Normal file
View File

@@ -0,0 +1,81 @@
![Filament branching strategy](art/diagrams/branching.png)
## Which branch do I open my PR against?
For normal development, open PRs against main. Once they're merged, no further action is necessary.
If you discover a bug with the latest *release candidate*, open a bug fix PR against the release
candidate branch (rc/1.9.0, for example). Once the PR is merged, decide whether it makes sense for
the fix to also go into main. If it was a temporary fix, simply make the _correct_ fix in main as
you would any other change. If the fix is good for main as well, use `git cherry-pick <sha>` to
cherry-pick it into main.
If an immediate hotfix is needed on the *release* branch, open a PR against the release branch. Once
the PR is merged, decide whether the fix is temporary or permanent. If the fix was temporary, make
the _correct_ fix in both the next release candidate branch _and_ main. If the fix is good, use `git
cherry-pick <sha>` to cherry-pick it into the relase candidate branch and main.
## What consitutes a bug?
Only bug fix PRs should be opened against the *release candidate* branch.
Bugs are defined as one of the following _introduced since the prior release_:
- crashes
- rendering issues
- unintentional binary size increases
- unintentional public API changes
For example, a long-standing crash just recently discovered would not necessitate a bug fix PR.
## Creating a GitHub Release
Be sure to choose the *release* branch when drafting a GitHub release.
## Git Commands
These commands assume a release candidate branch called *rc/1.9.0*.
### Creating a Release Candidate Branch
```
$ git checkout main
$ git pull
$ git branch rc/1.9.0
$ git push origin rc/1.9.0
```
### Merging the Release Candidate Branch Into Release
There may be temporary hotfixes in the release branch that should be overriden by the new release
candidate. To accomplish this, we first merge release into rc using the _ours_ strategy. Then we
merge rc into release.
```
$ git checkout rc/1.9.0
$ git pull
$ git fetch origin release:release
$ git merge -s ours release
$ git checkout release
$ git merge --no-ff rc/1.9.0
$ git push origin release
```
### Deleting the Release Candidate Branch
```
$ git branch -d rc/1.9.0
$ git push origin --delete rc/1.9.0
```
### See a History of the Release Branch
```
$ git log --oneline --first-parent
442b061 (HEAD -> release) Merge branch 'rc/1.9.2' into release
ac50d21 Hotfix
94dc2f7 Hotfix
b34ed5b Merge branch 'rc/1.9.1' into release
aeef498 Merge branch 'rc/1.9.0' into release
```

View File

@@ -15,16 +15,11 @@ To build the Java based components of the project you can optionally install (re
Additional dependencies may be required for your operating system. Please refer to the appropriate
section below.
Building the `rays` library (used for light baking) is optional and requires the following packages:
- embree 3.0+
- libtbb-dev
To build Filament for Android you must also install the following:
- Android Studio 3.6
- Android Studio 4.0.1 or more recent
- Android SDK
- Android NDK "side-by-side" 20 or higher
- Android NDK "side-by-side" 21.3 or higher
### Environment variables
@@ -79,20 +74,22 @@ compilation step simply pass the `-j` flag to `build.sh`:
$ ./build.sh -j release
```
If you use CMake directly instead of the build script, pass `-DENABLE_JAVA=OFF` to CMake instead.
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:
- `ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
- `ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
- `GENERATE_JS_DOCS`: Build WebGL documentation and tutorials
- `INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
- `USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
- `FILAMENT_ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
- `FILAMENT_ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
- `FILAMENT_USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
- `FILAMENT_USE_SWIFTSHADER`: Compile Filament against SwiftShader
- `FILAMENT_SKIP_SAMPLES`: Don't build sample apps
To turn an option on or off:
@@ -207,9 +204,12 @@ Install the following components:
The latest Windows SDK can also by installed by opening Visual Studio and selecting _Get Tools and
Features..._ under the _Tools_ menu.
Open the `x64 Native Tools Command Prompt for VS 2019`.
By default, Windows treats the file system as case insensitive. Please do not enable case
sensitivity in your repo, since this does not align with CMake expectations. This can be queried
using `fsutil.exe file queryCaseSensitiveInfo`.
Create a working directory, and run cmake in it:
Next, open `x64 Native Tools Command Prompt for VS 2019`, create a working directory, and run
CMake in it:
```
> mkdir out
@@ -228,6 +228,13 @@ For example, build the `material_sandbox` sample and run it from the `out` direc
> samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
```
You can also use CMake to invoke the build without opening Visual Studio. For example, from the
`out` folder run the following command.
```
> cmake --build . --target gltf_viewer --config Release
```
### Android
Before building Filament for Android, make sure to build Filament for your host. Some of the
@@ -368,7 +375,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/1b1f08f.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/1.39.19.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python ./emsdk.py install latest
python ./emsdk.py activate latest
@@ -447,3 +454,17 @@ $ doxygen docs/doxygen/filament.doxygen
```
Finally simply open `docs/html/index.html` in your web browser.
## SwiftShader
To try out Filament's Vulkan support with SwiftShader, first build SwiftShader and set the
`SWIFTSHADER_LD_LIBRARY_PATH` variable to the folder that contains `libvk_swiftshader.dylib`:
```
git clone https://github.com/google/swiftshader.git
cd swiftshader/build
cmake .. && make -j
export SWIFTSHADER_LD_LIBRARY_PATH=`pwd`
```
Next, go to your Filament repo and use the [easy build](#easy-build) script with `-t`.

View File

@@ -11,14 +11,70 @@ project(TNT)
# ==================================================================================================
# Options
# ==================================================================================================
option(FILAMENT_ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
option(ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env var" ON)
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(FILAMENT_USE_SWIFTSHADER "Compile Filament against SwiftShader" OFF)
option(GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
option(ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
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."
)
set(FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB "1" CACHE STRING
"Size of the high-level draw commands buffer. Rule of thumb, 1 MB less than FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB, default 1."
)
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."
)
# ==================================================================================================
# CMake policies
# ==================================================================================================
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
cmake_policy(SET CMP0074 NEW)
endif()
# ==================================================================================================
# Support for ccache
# ==================================================================================================
find_program(CCACHE_PROGRAM ccache)
if (CCACHE_PROGRAM)
set(C_LAUNCHER "${CCACHE_PROGRAM}")
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
configure_file(build/launch-c.in launch-c)
configure_file(build/launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_BINARY_DIR}/launch-c"
"${CMAKE_BINARY_DIR}/launch-cxx"
)
if (CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
else()
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-c")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cxx")
endif()
endif()
# ==================================================================================================
# Support Vim and Visual Studio Code by generating compile_commands.json
# ==================================================================================================
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ==================================================================================================
# OS specific
@@ -31,6 +87,19 @@ if (ANDROID OR WEBGL OR IOS)
set(IS_MOBILE_TARGET TRUE)
endif()
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
set(IS_HOST_PLATFORM TRUE)
endif()
if (IOS)
# Remove the headerpad_max_install_names linker flag on iOS. It causes warnings when linking
# executables with bitcode.
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS})
endif()
if (WIN32)
# Link statically against c/c++ lib to avoid missing redistriburable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
@@ -63,30 +132,23 @@ if (WIN32)
# 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")
endif()
# ==================================================================================================
# Check if embree is available.
# This is an optional dependency and can be installed with homebrew, apt-get, etc.
# ==================================================================================================
# Special settings when building on CI.
if (${FILAMENT_WINDOWS_CI_BUILD})
set(LinkerFlags
CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG
)
foreach(LinkerFlag ${LinkerFlags})
# The /debug flag outputs .pdb files, which we don't need on CI.
string(REPLACE "/debug" "" ${LinkerFlag} ${${LinkerFlag}})
find_package(embree 3.0 QUIET PATHS /usr/lib64/cmake)
if (embree_FOUND AND NOT ANDROID AND NOT IOS)
message("Found embree in ${embree_DIR}")
set(MKLDNN_THREADING "TBB")
include(third_party/OpenImageDenoise/cmake/resource.cmake)
include(third_party/OpenImageDenoise/mkl-dnn/cmake/Threading.cmake)
include(third_party/OpenImageDenoise/mkl-dnn/cmake/TBB.cmake)
find_package(TBB QUIET)
if (TBB_FOUND AND "${TBB_VERSION_MAJOR}" VERSION_EQUAL 2019)
message("Found TBB ${TBB_VERSION}")
add_definitions(-DFILAMENT_HAS_EMBREE)
set(DENOISE_LIBRARY OpenImageDenoise)
else()
message("TBB 2019 not found.")
# The /INCREMENTAL flag outputs .ilk files for incremental linking. These are huge, and
# we don't need them on CI.
string(REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" ${LinkerFlag} ${${LinkerFlag}})
endforeach()
endif()
else()
message("Embree not found, pipeline features are disabled.")
endif()
# ==================================================================================================
@@ -128,16 +190,14 @@ endif()
# Detect use of the clang-cl.exe frontend, which does not support all of clangs normal options
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
set(CLANG_CL true)
message(FATAL_ERROR "Building with Clang on Windows is no longer supported. Use MSVC 2019 instead.")
endif()
elseif (MSVC)
set(MSVC_NATIVE true)
endif()
# ==================================================================================================
# Link time optimizations (LTO)
# ==================================================================================================
if (ENABLE_LTO)
if (FILAMENT_ENABLE_LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORT)
@@ -151,38 +211,51 @@ endif()
# ==================================================================================================
# General compiler flags
# ==================================================================================================
set(CXX_STANDARD "-std=c++14")
set(CXX_STANDARD "-std=c++17")
if (WIN32)
set(CXX_STANDARD "/std:c++14")
set(CXX_STANDARD "/std:c++17")
endif()
if (MSVC_NATIVE)
if (MSVC)
set(CXX_STANDARD "/std:c++latest")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} /W0 /Zc:__cplusplus")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function")
endif()
if (USE_EXTERNAL_GLES3)
if (FILAMENT_USE_EXTERNAL_GLES3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
endif()
if (FILAMENT_USE_SWIFTSHADER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_SWIFTSHADER")
endif()
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_USE_MATH_DEFINES=1")
endif()
if (LINUX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
option(USE_STATIC_LIBCXX "Link against the static runtime libraries." ON)
if (${USE_STATIC_LIBCXX})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
endif()
# Only linux, clang doesn't want to use a shared library that is not PIC.
# /usr/bin/ld: ../bluegl/libbluegl.a(BlueGL.cpp.o): relocation R_X86_64_32S
# against `.bss' can not be used when making a shared object; recompile with -fPIC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if (CYGWIN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
endif()
if (CLANG_CL OR MSVC)
if (MSVC)
# Since the "secure" replacements that MSVC suggests are not portable, disable
# the deprecation warnings. Also disable warnings about use of POSIX functions (i.e. "unlink").
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE")
@@ -198,8 +271,13 @@ endif()
# ==================================================================================================
# Release compiler flags
# ==================================================================================================
if (NOT CLANG_CL AND NOT MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
if (NOT MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
# These aren't compatible with -fembed-bitcode (and seem to have no effect on Apple platforms anyway)
if (NOT IOS)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
endif()
endif()
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
@@ -222,8 +300,7 @@ endif()
# -fsanitize=undefined causes extremely long link times
# -fsanitize=address causes a crash with assimp, which we can't explain for now
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
# clang-cl.exe on Windows does not support -fstack-protector.
if (NOT CLANG_CL AND NOT MSVC AND NOT WEBGL)
if (NOT MSVC AND NOT WEBGL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
@@ -253,9 +330,6 @@ if (APPLE)
# prevents ar from invoking ranlib, let CMake do it
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc -S <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc -S <TARGET> <LINK_FLAGS> <OBJECTS>")
elseif (CLANG_CL)
set(GC_SECTIONS "")
set(B_SYMBOLIC_FUNCTIONS "")
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
@@ -275,9 +349,8 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebIn
endif()
# By default, build with Vulkan support on desktop platforms, although clients must request to use
# it at run time. On Android, the build does not include Vulkan support unless CMake is invoked
# with -DFILAMENT_SUPPORTS_VULKAN=ON.
if (ANDROID OR WIN32 OR WEBGL OR IOS)
# it at run time.
if (WIN32 OR WEBGL OR IOS)
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" OFF)
else()
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" ON)
@@ -287,8 +360,7 @@ if (FILAMENT_SUPPORTS_VULKAN)
endif()
# Build with Metal support on non-WebGL Apple platforms.
# Apple's simulator does not support Metal.
if (APPLE AND (NOT IOS OR IOS_ARCH STREQUAL "arm64") AND NOT WEBGL)
if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
else()
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" OFF)
@@ -304,6 +376,13 @@ else()
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
endif()
# By default, link in matdbg for Desktop + Debug only since it pulls in filamat and a web server.
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND IS_HOST_PLATFORM)
option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" ON)
else()
option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" OFF)
endif()
# ==================================================================================================
# Material compilation flags
# ==================================================================================================
@@ -404,7 +483,14 @@ endif()
# "bluevk" and "samples" targets.
# ==================================================================================================
if (FILAMENT_SUPPORTS_VULKAN AND APPLE)
if (FILAMENT_USE_SWIFTSHADER)
if (NOT FILAMENT_SUPPORTS_VULKAN)
message(ERROR "SwiftShader is only useful when Vulkan is enabled.")
endif()
find_library(SWIFTSHADER_VK NAMES vk_swiftshader HINTS "$ENV{SWIFTSHADER_LD_LIBRARY_PATH}")
message(STATUS "Found SwiftShader VK library in: ${SWIFTSHADER_VK}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${SWIFTSHADER_VK}\")
elseif (FILAMENT_SUPPORTS_VULKAN AND APPLE)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
if (Vulkan_LIBRARY)
set(Vulkan_FOUND ON)
@@ -439,11 +525,11 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
# the equivalent of .incbin, so on Windows we'll just tell resgen to output a C file.
if (WEBGL OR WIN32 OR ANDROID_ON_WINDOWS)
set(RESGEN_OUTPUTS "${OUTPUTS};${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
set(RESGEN_FLAGS -cx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_FLAGS -qcx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
else()
set(RESGEN_OUTPUTS "${OUTPUTS}" PARENT_SCOPE)
set(RESGEN_FLAGS -x ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_FLAGS -qx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}${ASM_SUFFIX}.S" PARENT_SCOPE)
set(RESGEN_SOURCE_FLAGS "-I${ARCHIVE_DIR} ${ASM_ARCH_FLAG}" PARENT_SCOPE)
endif()
@@ -463,27 +549,34 @@ add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/image)
add_subdirectory(${LIBRARIES}/rays)
add_subdirectory(${LIBRARIES}/math)
add_subdirectory(${LIBRARIES}/mathio)
add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${FILAMENT}/filament)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
add_subdirectory(${EXTERNAL}/smol-v/tnt)
add_subdirectory(${EXTERNAL}/benchmark/tnt)
add_subdirectory(${EXTERNAL}/meshoptimizer)
add_subdirectory(${EXTERNAL}/cgltf/tnt)
add_subdirectory(${EXTERNAL}/xatlas/tnt)
add_subdirectory(${EXTERNAL}/draco/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
if (FILAMENT_BUILD_FILAMAT)
if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
add_subdirectory(${EXTERNAL}/spirv-tools)
add_subdirectory(${EXTERNAL}/glslang/tnt)
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
add_subdirectory(${LIBRARIES}/filamat)
# the material debugger requires filamat
if (FILAMENT_ENABLE_MATDBG OR IS_HOST_PLATFORM)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${LIBRARIES}/matdbg)
endif()
endif()
if (FILAMENT_SUPPORTS_VULKAN)
@@ -495,41 +588,37 @@ if (APPLE)
add_subdirectory(${EXTERNAL}/moltenvk/tnt)
endif()
set (FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
if (WEBGL)
add_subdirectory(web/filament-js)
add_subdirectory(web/samples)
if (GENERATE_JS_DOCS)
add_subdirectory(web/docs)
endif()
add_subdirectory(${EXTERNAL}/imgui/tnt)
endif()
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
if (IS_HOST_PLATFORM)
add_subdirectory(${LIBRARIES}/bluegl)
add_subdirectory(${LIBRARIES}/filamentapp)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${LIBRARIES}/matdbg)
add_subdirectory(${FILAMENT}/java/filamat)
add_subdirectory(${FILAMENT}/java/filament)
add_subdirectory(${FILAMENT}/java/gltfio)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
add_subdirectory(${EXTERNAL}/libz/tnt)
add_subdirectory(${EXTERNAL}/skylight/tnt)
add_subdirectory(${EXTERNAL}/tinyexr/tnt)
add_subdirectory(${TOOLS}/cmgen)
add_subdirectory(${TOOLS}/cso-lut)
add_subdirectory(${TOOLS}/filamesh)
add_subdirectory(${TOOLS}/glslminifier)
add_subdirectory(${TOOLS}/matc)
@@ -538,13 +627,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${TOOLS}/normal-blending)
add_subdirectory(${TOOLS}/resgen)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/skygen)
add_subdirectory(${TOOLS}/specular-color)
if (DENOISE_LIBRARY)
add_subdirectory(${EXTERNAL}/OpenImageDenoise/tnt)
endif()
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)

199
README.md
View File

@@ -1,11 +1,11 @@
# Filament
![Android Build Status](https://github.com/google/filament/workflows/Android/badge.svg)
![iOS Build Status](https://github.com/google/filament/workflows/iOS/badge.svg)
![Linux Build Status](https://github.com/google/filament/workflows/Linux/badge.svg)
![macOS Build Status](https://github.com/google/filament/workflows/macOS/badge.svg)
![Windows Build Status](https://github.com/google/filament/workflows/Windows/badge.svg)
![Web Build Status](https://github.com/google/filament/workflows/Web/badge.svg)
[![Android Build Status](https://github.com/google/filament/workflows/Android/badge.svg)](https://github.com/google/filament/actions?query=workflow%3AAndroid)
[![iOS Build Status](https://github.com/google/filament/workflows/iOS/badge.svg)](https://github.com/google/filament/actions?query=workflow%3AiOS)
[![Linux Build Status](https://github.com/google/filament/workflows/Linux/badge.svg)](https://github.com/google/filament/actions?query=workflow%3ALinux)
[![macOS Build Status](https://github.com/google/filament/workflows/macOS/badge.svg)](https://github.com/google/filament/actions?query=workflow%3AmacOS)
[![Windows Build Status](https://github.com/google/filament/workflows/Windows/badge.svg)](https://github.com/google/filament/actions?query=workflow%3AWindows)
[![Web Build Status](https://github.com/google/filament/workflows/Web/badge.svg)](https://github.com/google/filament/actions?query=workflow%3AWeb)
Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows,
and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
@@ -31,26 +31,47 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.4.4'
implementation 'com.google.android.filament:filament-android:1.9.2'
}
```
Here are all the libraries available in the group `com.google.android.filament`:
- `filament-android`: the Filament rendering engine itself
- `gltfio-android`: a glTF 2.0 loader for Filament, depends on `filament-android`
- `filament-utils-android`: KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`
- `filamat-android-full`: a runtime material builder/compiler. This library is large but contains
a full shader compiler/validator/optimizer
- `filamat-android-lite`: a much smaller alternative to `filamat-android-full` that can only
generate OpenGL shaders. It does not provide validation or optimizations
[![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.
### iOS
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.9.2'
```
### Snapshots
If you prefer to live on the edge, you can download a continuous build by following the following
steps:
1. Find the [commit](https://github.com/google/filament/commits/master) you're interested in.
1. Find the [commit](https://github.com/google/filament/commits/main) you're interested in.
2. Click the green check mark under the commit message.
3. Click on the _Details_ link for the platform you're interested in.
4. On the top right, click on the _Artifacts_ dropdown and choose an artifact.
@@ -69,17 +90,13 @@ steps:
## Examples
### Materials
![Night scene](docs/images/samples/example_bistro1.jpg)
![Night scene](docs/images/samples/example_bistro2.jpg)
![Materials](docs/images/samples/example_materials1.jpg)
![Materials](docs/images/samples/example_materials2.jpg)
![Helmet](docs/images/samples/example_helmet.jpg)
![Screen-space refraction](docs/images/samples/example_ssr.jpg)
Here are a few sample materials rendered with Filament:
![Damaged Helmet](docs/images/samples/model_damaged_helmet.jpg)
![Helmet](docs/images/samples/model_helmet.jpg)
![Brushed copper](docs/images/samples/brushed_copper_2.jpg)
![Material 1](docs/images/samples/material_01.jpg)
![Material 2](docs/images/samples/material_02.jpg)
![Material 6](docs/images/samples/material_06.jpg)
![Material 8](docs/images/samples/material_08.jpg)
### Applications
@@ -124,12 +141,21 @@ Here are a few screenshots of applications that use Filament in production:
- Image-based lighting
- Physically-based camera (shutter speed, sensitivity and aperture)
- Physical light units
- Point light, spot light and directional light
- SSAO
- ACES-like tone-mapping
- Temporal dithering
- FXAA, MSAA and specular anti-aliasing
- Dynamic resolution (on Android and iOS)
- Point lights, spot lights and directional light
- Spot and directional light shadows
- Cascaded shadows
- VSM or PCF shadows
- Contact shadows
- Screen-space ambient occlusion
- Screen-space refraction
- Global fog
- 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
## Rendering with Filament
@@ -147,7 +173,7 @@ Renderer* renderer = engine->createRenderer();
To render a frame you must then create a `View`, a `Scene` and a `Camera`:
```c++
Camera* camera = engine->createCamera();
Camera* camera = engine->createCamera(EntityManager::get().create());
View* view = engine->createView();
Scene* scene = engine->createScene();
@@ -227,11 +253,12 @@ creating the swap chain in the `onNativeWindowChanged()` callback.
### iOS
See `ios/samples` for examples of using Filament on iOS.
Filament is supported on iOS 11.0 and above. See `ios/samples` for examples of using Filament on
iOS.
Filament on iOS is largely the same as native rendering with C++. A `CAEAGLLayer` or `CAMetalLayer`
is passed to the `createSwapChain` method. Filament for iOS supports both OpenGL ES and Vulkan via
MoltenVK.
is passed to the `createSwapChain` method. Filament for iOS supports both Metal (preferred) and
OpenGL ES.
## Assets
@@ -249,56 +276,58 @@ familiar with the [code style](/CODE_STYLE.md).
This repository not only contains the core Filament engine, but also its supporting libraries
and tools.
- `android`: Android libraries and projects
- `filamat-android`: Filament material generation library (AAR) for Android
- `filament-android`: Filament library (AAR) for Android
- `gltfio-android`: Filament glTF loading library (AAR) for Android
- `samples`: Android-specific Filament samples
- `art`: Source for various artworks (logos, PDF manuals, etc.)
- `assets`: 3D assets to use with sample applications
- `build`: CMake build scripts
- `docs`: Documentation
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
- `filament`: Filament rendering engine (minimal dependencies)
- `ide`: Configuration files for IDEs (CLion, etc.)
- `ios`: Sample projects for iOS
- `java`: Java bindings for Filament libraries
- `libs`: Libraries
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
- `filabridge`: Library shared by the Filament engine and host tools
- `filaflat`: Serialization/deserialization library used for materials
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
- `filamat`: Material generation library
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
- `geometry`: Mesh-related utilities
- `gltfio`: Loader and optional pipeline for glTF 2.0
- `ibl`: IBL generation tools
- `image`: Image filtering and simple transforms
- `imageio`: Image file reading / writing, only intended for internal use
- `matdbg`: DebugServer for inspecting shaders at run-time (debug builds only)
- `math`: Math library
- `rays`: Simple path tracer used for baking ambient occlusion, etc.
- `utils`: Utility library (threads, memory, data structures, etc.)
- `samples`: Sample desktop applications
- `shaders`: Shaders used by `filamat` and `matc`
- `third_party`: External libraries and assets
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
- `models`: Models under permissive licenses
- `textures`: Textures under CC0 license
- `tools`: Host tools
- `cmgen`: Image-based lighting asset generator
- `filamesh`: Mesh converter
- `glslminifier`: Minifies GLSL source code
- `matc`: Material compiler
- `matinfo` Displays information about materials compiled with `matc`
- `mipgen` Generates a series of miplevels from a source image
- `normal-blending`: Tool to blend normal maps
- `resgen` Aggregates binary blobs into embeddable resources
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
- `skygen`: Physically-based sky environment texture generator
- `specular-color`: Computes the specular color of conductors based on spectral data
- `web`: JavaScript bindings, documentation, and samples
- `android`: Android libraries and projects
- `filamat-android`: Filament material generation library (AAR) for Android
- `filament-android`: Filament library (AAR) for Android
- `filament-utils-android`: Extra utilities (KTX loader, math types, etc.)
- `gltfio-android`: Filament glTF loading library (AAR) for Android
- `samples`: Android-specific Filament samples
- `art`: Source for various artworks (logos, PDF manuals, etc.)
- `assets`: 3D assets to use with sample applications
- `build`: CMake build scripts
- `docs`: Documentation
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
- `filament`: Filament rendering engine (minimal dependencies)
- `ide`: Configuration files for IDEs (CLion, etc.)
- `ios`: Sample projects for iOS
- `java`: Java bindings for Filament libraries
- `libs`: Libraries
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
- `camutils`: Camera manipulation utilities
- `filabridge`: Library shared by the Filament engine and host tools
- `filaflat`: Serialization/deserialization library used for materials
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
- `filamat`: Material generation library
- `filamentapp`: SDL2 skeleton to build sample apps
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
- `geometry`: Mesh-related utilities
- `gltfio`: Loader for glTF 2.0
- `ibl`: IBL generation tools
- `image`: Image filtering and simple transforms
- `imageio`: Image file reading / writing, only intended for internal use
- `matdbg`: DebugServer for inspecting shaders at run-time (debug builds only)
- `math`: Math library
- `mathio`: Math types support for output streams
- `utils`: Utility library (threads, memory, data structures, etc.)
- `samples`: Sample desktop applications
- `shaders`: Shaders used by `filamat` and `matc`
- `third_party`: External libraries and assets
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
- `models`: Models under permissive licenses
- `textures`: Textures under CC0 license
- `tools`: Host tools
- `cmgen`: Image-based lighting asset generator
- `filamesh`: Mesh converter
- `glslminifier`: Minifies GLSL source code
- `matc`: Material compiler
- `matinfo` Displays information about materials compiled with `matc`
- `mipgen` Generates a series of miplevels from a source image
- `normal-blending`: Tool to blend normal maps
- `resgen` Aggregates binary blobs into embeddable resources
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
- `specular-color`: Computes the specular color of conductors based on spectral data
- `web`: JavaScript bindings, documentation, and samples
## License

View File

@@ -3,7 +3,196 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## Next release
## v1.9.2
- Fixes / improvements for contact shadows, fog, and DOF
- Reduce SSAO creases caused by geometry tessellation
- Fix compilation warnings and issue with Clang 12
- Fix JNI crashes
- Rename .blurScale to .cocScale in DOF options
## v1.9.1
- Improvements to SSAO quality
- Fix unoptimized shader crashes with certain OpenGL drivers
- Add float versions of math constants to libmath
- filament-utils: fix, `CoroutineScope` job should be canceled before destroy
## v1.9.0
- `MASKED` mode now leaves destination alpha intact (useful for transparent targets).
- `MASKED` mode now benefit from smoothing in `unlit` materials.
- Small performance improvement to FXAA.
- Fixed `KHR_materials_transmission` to use the `FADE` blending mode.
- Fixed frame graph crash when more than 32 stages were required.
- Fixed several memory leaks in gltfio and the JavaScript bindings.
- Fixed several platform-specific Vulkan bugs and crashes.
- Temporal Anti-Aliasing (TAA) is now available as a complement to MSAA and FXAA. It can be turned
on and controlled using `View.setTemporalAntiAliasingOptions()`.
- Added texture getters to `Skybox` and `IndirectLight` (C++, Java, JavaScript).
- Added APIs to create 3D textures and 2D texture arrays.
- Internal buffers can now be sized at compile times for applications that render very large
numbers of objects.
- `View.setAmbientOcclusion()` is deprecated in favor of `View.setAmbientOcclusionOptions`
(⚠️ **API change**).
- Switched to C++17.
- Variance Shadow Mapping (VSM) is now available as an alternative to PCF shadows (experimental).
- Reduced compiled material sizes by removing unnecessary variants.
- Many improvement and fixes in the Vulkan backend.
- Many improvement and fixes in the Metal backend.
- Fixed translucent views with custom render targets.
- Improved MSAA implementation compatibility on Android devices.
- Use "reverse-z" for the depth buffer.
- Added a way to create an `Engine` asynchronously.
- Highlights are now more stable under depth of field.
- New option to compress highlights before bloom.
- Improvements and fixes to SSAO and DOF.
## v1.8.1
- New CocoaPods sample for iOS.
- Filament for iOS now supports iOS 11.
- Updated the Emscripten SDK to 1.39.19.
- Fixed skinning issue with Emscripten.
- JavaScript APIs for color grading and the vignette effect.
- Added various missing APIs to Java and JavaScript bindings.
- Fixed camera aspect ratio when loading a camera from a glTF file.
- gltfio now uses specular anti-aliasing by default.
- gltfio now supports the KHR_materials_transmission extension.
- Compiled materials do not perform unnecessary fp32 operations anymore.
- Improved quality and performance of the depth of field effect.
- Fixed transform hierarchy memory corruption when a node is set to be parentless.
- Fixed crashed in some browsers and on some mobile devices caused by
Google-style line directives in shaders.
- Color grading now has a quality option which affects the size and bit depth of the 3D LUT.
- Fixed crash in the Metal backend when more than 16 samplers are bound.
- Added validation in `Texture::setImage()`.
- Fixed refraction/transmission roughness when specular anti-aliasing is enabled.
## v1.8.0
- Improved JavaScript API for SurfaceOrientation and Scene.
- Updated JavaScript API around Camera construction / destruction (⚠️ **API change**)
- Add missing JavaScript API for `View::setVisibleLayers()`.
- Fixed regression in JavaScript IcoSphere that caused tutorial to fail.
- gltf_viewer now supports viewing with glTF cameras.
- gltfio now uses high precision for texture coordinates.
- gltfio now supports importing glTF cameras.
- gltfio now supports simple instancing of entire assets.
- gltfio has improved performance and assumes assets are well-formed.
- gltfio now supports name and prefix lookup for entities.
- ModelViewer now allows resources to be fetched off the UI thread.
- Add support for DOF with Metal backend.
- New Depth-of-Field (Dof) algorithm, which is more plausible and about an order of magnitude faster
(about 4ms on Pixel4).
- SSAO now has an optional high(er) quality upsampler.
- Tone mappping now uses the real ACES tone mapper, applied in the proper color space.
- Tone mapping is now applied via a LUT.
- `View::setToneMapping` is deprecated, use `View::setColorGrading` instead. (⚠️ **API change**)
- Color grading capabilities per View: white balance (temperature/tint), channel mixer,
tonal ranges (shadows/mid-tones/highlights), ASC CDL (slope/offset/power), contrast, vibrance,
saturation, and curves.
- New vignette effect.
- Improved MSAA performance on mobile.
- Improved performance of the post-process pass when bloom is disabled on mobile.
- Added support for 3D textures.
- Fixed private API access on some versions of Android.
- Many improvements and bug fixes in Metal and Vulkan backends.
- Fixed bug in the Metal backend when SSR and MSAA were turned on.
- Fixed Metal issue with `BufferDescriptor` and `PixelBufferDescriptor`s not being called on
the application thread.
## v1.7.0
- MaterialInstances now have optional names.
- Improved Depth of Field effect: bokeh rotates with the aperture diameter, improved CoC calculation, feather blur radius.
- Introduced `getNormalizedViewportCoord` shader API.
- Added basic SwiftShader support.
- Fixed SwapChain resizing issues in Vulkan.
- Added debug option to track `Entities`.
- Fixed `Camera` entity leaks.
- Removed problematic `CreateEliminateDeadMembersPass`, which broke UBO layout.
- Added assert that the engine is not terminated in `flushAndWait()`.
- Added several fixes and improvements around objects lifetime management
- `gltfio`: AssetLoader now loads names for mesh-free nodes
- `gltfio`: Material names are now preserved in ubershader mode
- Fixed JNI objects allocation and memory corruption
- JNI constructors are now "package private" unless they take an Engine.
## v1.6.0
- gltfio: fixed incorrect cone angles with lights.
- Specular ambient occlusion now offers 3 modes: off, simple (default on desktop) and bent normals.
The latter is more accurate but more expensive and requires a bent normal to be specified in the
material. If selected and not bent normal is specified, Filament falls back to the simple mode.
- Specular ambient occlusion from bent normals now smoothly disappears as roughness goes from 0.3
to 0.1. Specular ambient occlusion can completely remove specular light which looks bad on glossy
metals. Use the simple specular occlusion mode for glossy metals instead.
- Refraction can now be set on `MaterialBuilder` from Java.
- Refraction mode and type can now be set by calling `MaterialBuilder::refractionMode()`.
and `MaterialBuilder::refractionType()` instad of `materialRefraction()` and
`materialRefractionType()` (️⚠️ **API change**).
- Fixed documentation confusion about focused spot vs spot lights.
- Fixed a race condition in the job system.
- Fixed support for 565 bitmaps on Android.
- Added support for timer queries in the Metal backend.
- Improved dynamic resolution implementation to be more accurate and target more platforms.
- `beginFrame()` now accepts a v-sync timestamp for accurate frame time measurement (used for
frame skipping and dynamic resolution). You can pass `0` to get the old behavior (⚠️ **API change**).
- Fixed several issues related to multi-view support: removed
`View::setClearColor()`, a similar functionality is now handled by `Renderer::setClearOptions()`
and `Skybox`, the later now can be set to a constant color (⚠️ **API breakage**).
- Fixed spot/point lights rendering bug depending on Viewport position.
- Textures can now be swizzled.
- The emissive property of materials is now expressed in nits and the alpha channel contains the
exposure weight (at 0.0 the exposure is not applied to the emissive component of a surface, at
1.0 the exposure is applied just like with any regular light) (⚠️ **API breakage**).
- Added new `intensityCandela` and `setIntensityCandela` API to `LightManager` for setting a punctual
light's intensity in candela.
- Fixed an issue where some `ShadowOptions` were not being respected when passed to
`LightManager::Builder`.
- Added a Depth of Field post-processing effect
## v1.5.2
- gltfio: fixed null pointer exception seen with some Android clients.
- Engine now exposes its JobSystem to C++ clients.
- Expose setCulling() in public RenderableManager API.
## v1.5.1
- Fixed "no texture bound" warning in WebGL.
- Fixed a clearing bug with imported render targets.
- Fixed the creation potentially invalid entities during shadow map initialization.
- Fixed Maven dependencies for the `filament-utils` library.
## v1.5.0
⚠️ This release breaks compiled materials, use matc to recompile.
- The Android support libraries (gltfio and filament-utils) now use dynamic linking.
- Removed depth-prepass related APIs. (⚠ API Change)
- gltfio: add asynchronous API to ResourceLoader.
- gltfio: generate normals for flat-shaded models that do not have normals.
- Material instances now allow dynamic depth testing and other rasterization state.
- Unlit materials now apply emissive in the same way as lit materials.
- Screen-space refraction is now supported.
- Support for HDR Bloom as a post-process effect.
- Alpha masked objects are now part of the SSAO pass.
- Added Java bindings for geometry::SurfaceOrientation.
- Fixed bug rendering transparent objects with Metal backend.
- Fixed crash on macOS Catalina when rendering with Metal backend.
- Fixed bug in Camera::setLensProjection() and added the aspect ratio parameter. (⚠ API Change)
- WebGL: Improved TypeScript annotations.
- WebGL: Simplified callback API for glTF. (⚠ API Change)
- gltfio: Removed deprecated "Bindings" API. (⚠ API Change)
- gltfio: Added support for Draco.
- gltfio: Reduced the size of the library.
- Improved performance of SSAO.
- Added support for screen-space contact shadows.
- Added support for global fog.
- Added support for bent normal maps and specular occlusion from bent normal maps.
- Added support for shadow-casting spot lights.
## v1.4.5

View File

@@ -2,13 +2,14 @@
## Prerequisites
In addition to the requirements for [building Filament on Windows](../README.md#windows), you'll
In addition to the requirements for [building Filament on Windows](../BUILDING.md#windows), you'll
need the Android SDK and NDK. See [Getting Started with the
NDK](https://developer.android.com/ndk/guides/) for detailed installation instructions.
Ensure the `%ANDROID_HOME%` environment variable is set to your Android SDK installation location.
All of the following commands should be executed in a Visual Studio x64 Native Tools Command Prompt.
On Windows, we require VS2019 for building the host tools. All of the following commands should be
executed in a *Visual Studio x64 Native Tools Command Prompt for VS 2019*.
## Desktop Tools
@@ -21,11 +22,8 @@ mkdir out\cmake-release
cd out\cmake-release
cmake ^
-G Ninja ^
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
-DCMAKE_INSTALL_PREFIX=..\release\filament ^
-DENABLE_JAVA=NO ^
-DFILAMENT_ENABLE_JAVA=NO ^
-DCMAKE_BUILD_TYPE=Release ^
..\..
```
@@ -39,6 +37,12 @@ ninja matc resgen cmgen
The build should succeed and a `ImportExecutables-Release.cmake` file should automatically be
created at Filament's root directory.
If you are going to build Filament samples you should install desktop host tools:
```
ninja install
```
## Build
1. Create the build directories.
@@ -96,28 +100,28 @@ ninja install
## Generate AAR
The Gradle project used to generate the AAR is located at `<filament>\android\filament-android`.
The Gradle project used to generate the AAR is located at `<filament>\android`.
```
cd android\filament-android
gradlew -Pfilament_dist_dir=..\..\out\android-release\filament assembleRelease
copy build\outputs\aar\filament-android-release.aar ..\..\out\
cd android
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease
copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
```
If you're only interested in building for a single ABI, you'll need to add an `abiFilters` override
inside the `build.gradle` file underneath `defaultConfig`:
If you're only interested in building for a single ABI, you'll need to pass a `filament_abis` parameter:
```
ndk {
abiFilters 'arm64-v8a'
}
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_abis=x86
```
If you're only interested in building SDK, you may skip samples build by passing a `filament_skip_samples` flag:
```
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
```
See
[NdkOptions](https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.NdkOptions.html#com.android.build.gradle.internal.dsl.NdkOptions:abiFilters)
for more information.
`filament-android-release.aar` should now be present at `<filament>\out\filament-android-release.aar`.
See [Using Filament's AAR](../README.md#using-filaments-aar) for usage instructions.
See [Using Filament's AAR](../README.md) for usage instructions.

View File

@@ -4,49 +4,106 @@
// Path to the Filament distribution/install directory for Android
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
//
// filament_tools_dir
// Path to the Filament distribution/install directory for desktop.
// This directory must contain bin/matc.
//
// filament_exclude_vulkan
// When set, support for Vulkan will be excluded.
//
// filament_skip_samples
// Exclude samples from the project. Useful to speed up compilation.
//
// filament_abis
// List of supported ABIs to build as a comma separated list. Available options are:
// arm64-v8a, armeabi-v7a, x86_64, x86, all
// Defaults to all.
//
// Example:
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease -Pfilament_abis=x86
buildscript {
def filamentPath = file("../out/android-release/filament").absolutePath
if (project.hasProperty("filament_dist_dir")) {
filamentPath = file("$filament_dist_dir").absolutePath
filamentPath = file(project.property("filament_dist_dir")).absolutePath
}
// Our CMake scripts require a forward-slash path for the FILAMENT_DIST_DIR
// variable, so here we convert the native path to a forward-slash path.
filamentPath = filamentPath.replace(File.separator, '/')
// Warning: changing this property does not work well with incremental builds.
def excludeVulkan = project.hasProperty("filament_exclude_vulkan")
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
if (project.hasProperty("filament_abis")) {
def newAbis = project.property("filament_abis").split(',')
if (!newAbis.contains("all")) {
abis = newAbis
}
}
ext.filamentPath = filamentPath
// Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
// to increase their minSdkVersion unnecessarily. It is however up to them to
// ensure they do not initialize Filament on API levels < 19.
// Our minSdkVersion is 19.
ext.versions = [
'minSdk': 14,
'minSdk': 19,
'targetSdk': 29,
'compileSdk': 29,
'kotlin': '1.3.61',
'buildTools': '29.0.2',
'kotlin': '1.3.72',
'buildTools': '30.0.1',
'ndk': '21.3.6528147'
]
ext.deps = [
'androidx': [
'annotations': "androidx.annotation:annotation:1.1.0",
'core': "androidx.core:core:1.1.0",
'core': "androidx.core:core:1.3.0",
],
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
]
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
ext.cmakeArgs = [
"-DANDROID_PIE=ON",
"-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static",
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString()
]
ext.cppFlags = [
"-std=c++17",
"-Wno-unused-command-line-argument",
// Required to support API levels below 23
"-Wl,--hash-style=both",
"-fno-stack-protector",
"-fno-exceptions",
"-fno-unwind-tables",
"-fno-asynchronous-unwind-tables",
"-fno-rtti",
"-ffast-math",
"-ffp-contract=fast",
"-fvisibility-inlines-hidden",
"-fvisibility=hidden",
"-fomit-frame-pointer",
"-ffunction-sections",
"-fdata-sections",
"-Wl,--gc-sections",
"-Wl,-Bsymbolic-functions",
]
ext.abis = abis
repositories {
mavenCentral()
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.0-rc01'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
}
subprojects { project ->
subprojects {
group = GROUP
version = VERSION_NAME
@@ -55,4 +112,56 @@ subprojects { project ->
google()
jcenter()
}
if (!name.startsWith("sample")) {
apply plugin: 'com.android.library'
android {
buildToolsVersion versions.buildTools
compileSdkVersion versions.compileSdk
ndkVersion versions.ndk
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
externalNativeBuild {
cmake {
arguments.addAll(rootProject.ext.cmakeArgs)
cppFlags.addAll(rootProject.ext.cppFlags)
}
}
ndk {
abiFilters(*rootProject.ext.abis)
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
}
}
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.each {
it.onlyIf {
!it.project.ext.has('isSample') || !project.hasProperty('filament_skip_samples')
}
}
}

View File

@@ -0,0 +1,3 @@
repositories {
mavenCentral()
}

View File

@@ -1,18 +1,35 @@
// This script accepts the following parameters:
// This plugin accepts the following parameters:
//
// filament_tools_dir
// Path to the Filament distribution/install directory for desktop
// (produced by make/ninja install). This directory must contain bin/matc
// Path to the Filament distribution/install directory for desktop.
// This directory must contain bin/matc.
//
// filament_exclude_vulkan
// When set, support for Vulkan will be excluded.
//
// Example:
// ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
import java.nio.file.Paths
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
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.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.InputFileDetails
import org.gradle.internal.os.OperatingSystem
import org.gradle.api.*
import org.gradle.api.logging.*
import org.gradle.api.tasks.*
import org.gradle.api.tasks.incremental.*
import org.gradle.work.ChangeType
import org.gradle.work.Incremental
import org.gradle.work.InputChanges
import java.nio.file.Paths
class TaskWithBinary extends DefaultTask {
private final String binaryName
@@ -65,56 +82,62 @@ class LogOutputStream extends ByteArrayOutputStream {
// Custom task to compile material files using matc
// This task handles incremental builds
class MaterialCompiler extends TaskWithBinary {
@SuppressWarnings("GroovyUnusedDeclaration")
abstract class MaterialCompiler extends TaskWithBinary {
@Incremental
@InputDirectory
File inputDir
final DirectoryProperty inputDir = project.objects.directoryProperty()
@OutputDirectory
File outputDir
final DirectoryProperty outputDir = project.objects.directoryProperty()
MaterialCompiler() {
super("matc")
}
@SuppressWarnings("GroovyUnusedDeclaration")
@TaskAction
void execute(IncrementalTaskInputs inputs) {
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir).matching { include '*.filamat' })
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamat' })
}
inputs.outOfDate { InputFileDetails outOfDate ->
if (outOfDate.file.directory) return
def file = outOfDate.file
inputs.getFileChanges(inputDir).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def file = change.file
def header = ("Compiling material " + file + "\n").getBytes()
out.write(header)
out.flush()
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
def header = ("Compiling material " + file + "\n").getBytes()
out.write(header)
out.flush()
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
}
def matcArgs = []
if (!project.hasProperty("filament_exclude_vulkan")) {
matcArgs += ['-a', 'vulkan']
}
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
project.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
args matcArgs
}
}
project.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
args('-a', 'all', '-p', 'mobile', '-o', getOutputFile(file), file)
}
}
inputs.removed { InputFileDetails removed ->
getOutputFile(removed.file).delete()
}
}
File getOutputFile(final File file) {
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamat')
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamat').get().asFile
}
}
@@ -123,158 +146,170 @@ class MaterialCompiler extends TaskWithBinary {
class IblGenerator extends TaskWithBinary {
String cmgenArgs = null
@SuppressWarnings("GroovyUnusedDeclaration")
@Incremental
@InputFile
File inputFile
final RegularFileProperty inputFile = project.objects.fileProperty()
@OutputDirectory
File outputDir
final DirectoryProperty outputDir = project.objects.directoryProperty()
IblGenerator() {
super("cmgen")
}
@SuppressWarnings("GroovyUnusedDeclaration")
@TaskAction
void execute(IncrementalTaskInputs inputs) {
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir).matching { include '*' })
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*' })
}
inputs.outOfDate { InputFileDetails outOfDate ->
def file = outOfDate.file
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def file = change.file
def header = ("Generating IBL " + file + "\n").getBytes()
out.write(header)
out.flush()
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
}
def header = ("Generating IBL " + file + "\n").getBytes()
out.write(header)
out.flush()
project.exec {
standardOutput out
if (!cmgenArgs) {
cmgenArgs = '-q -x ' + outputDir +
' --format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
}
cmgenArgs = cmgenArgs + " " + file
errorOutput err
executable "${getBinary()}"
args(cmgenArgs.split())
}
}
inputs.removed { InputFileDetails removed ->
getOutputFile(removed.file).delete()
def outputPath = outputDir.get().asFile
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())
}
}
}
}
File getOutputFile(final File file) {
return new File(outputDir, file.name[0..file.name.lastIndexOf('.') - 1])
return outputDir.file(file.name[0..file.name.lastIndexOf('.') - 1]).get().asFile
}
}
// Custom task to compile mesh files using filamesh
// This task handles incremental builds
class MeshCompiler extends TaskWithBinary {
@SuppressWarnings("GroovyUnusedDeclaration")
@Incremental
@InputFile
File inputFile
final RegularFileProperty inputFile = project.objects.fileProperty()
@OutputDirectory
File outputDir
final DirectoryProperty outputDir = project.objects.directoryProperty()
MeshCompiler() {
super("filamesh")
}
@SuppressWarnings("GroovyUnusedDeclaration")
@TaskAction
void execute(IncrementalTaskInputs inputs) {
void execute(InputChanges inputs) {
if (!inputs.incremental) {
project.delete(project.fileTree(outputDir).matching { include '*.filamesh' })
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamesh' })
}
inputs.outOfDate { InputFileDetails outOfDate ->
def file = outOfDate.file
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
if (change.fileType == FileType.DIRECTORY) return
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
def file = change.file
def header = ("Compiling mesh " + file + "\n").getBytes()
out.write(header)
out.flush()
if (change.changeType == ChangeType.REMOVED) {
getOutputFile(file).delete()
} else {
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
def err = new LogOutputStream(logger, LogLevel.ERROR)
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
def header = ("Compiling mesh " + file + "\n").getBytes()
out.write(header)
out.flush()
if (!getBinary().exists()) {
throw new GradleException("Could not find ${getBinary()}." +
" Ensure Filament has been built/installed before building this app.")
}
project.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
args(file, getOutputFile(file))
}
}
project.exec {
standardOutput out
errorOutput err
executable "${getBinary()}"
args(file, getOutputFile(file))
}
}
inputs.removed { InputFileDetails removed ->
getOutputFile(removed.file).delete()
}
}
File getOutputFile(final File file) {
return new File(outputDir, file.name[0..file.name.lastIndexOf('.')] + 'filamesh')
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamesh').get().asFile
}
}
class FilamentToolsPluginExtension {
File materialInputDir
File materialOutputDir
DirectoryProperty materialInputDir
DirectoryProperty materialOutputDir
String cmgenArgs
File iblInputFile
File iblOutputDir
RegularFileProperty iblInputFile
DirectoryProperty iblOutputDir
File meshInputFile
File meshOutputDir
RegularFileProperty meshInputFile
DirectoryProperty meshOutputDir
}
class FilamentToolsPlugin implements Plugin<Project> {
void apply(Project project) {
def extension = project.extensions.create('filamentTools', FilamentToolsPluginExtension)
extension.materialInputDir = project.objects.directoryProperty()
extension.materialOutputDir = project.objects.directoryProperty()
extension.iblInputFile = project.objects.fileProperty()
extension.iblOutputDir = project.objects.directoryProperty()
extension.meshInputFile = project.objects.fileProperty()
extension.meshOutputDir = project.objects.directoryProperty()
project.ext.filamentToolsPath = project.file("../../../out/release/filament")
if (project.hasProperty("filament_tools_dir")) {
project.ext.filamentToolsPath = project.file("$filament_tools_dir")
project.ext.filamentToolsPath = project.file(project.property("filament_tools_dir"))
}
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
enabled = extension.materialInputDir != null && extension.materialOutputDir != null
inputDir = extension.materialInputDir
outputDir = extension.materialOutputDir
enabled =
extension.materialInputDir.isPresent() &&
extension.materialOutputDir.isPresent()
inputDir = extension.materialInputDir.getOrNull()
outputDir = extension.materialOutputDir.getOrNull()
}
project.preBuild.dependsOn "filamentCompileMaterials"
project.tasks.register("filamentGenerateIbl", IblGenerator) {
enabled = extension.iblInputFile != null && extension.iblOutputDir != null
enabled = extension.iblInputFile.isPresent() && extension.iblOutputDir.isPresent()
cmgenArgs = extension.cmgenArgs
inputFile = extension.iblInputFile
outputDir = extension.iblOutputDir
inputFile = extension.iblInputFile.getOrNull()
outputDir = extension.iblOutputDir.getOrNull()
}
project.preBuild.dependsOn "filamentGenerateIbl"
project.tasks.register("filamentCompileMesh", MeshCompiler) {
enabled = extension.meshInputFile != null && extension.meshOutputDir != null
inputFile = extension.meshInputFile
outputDir = extension.meshOutputDir
enabled = extension.meshInputFile.isPresent() && extension.meshOutputDir.isPresent()
inputFile = extension.meshInputFile.getOrNull()
outputDir = extension.meshOutputDir.getOrNull()
}
project.preBuild.dependsOn "filamentCompileMesh"

View File

@@ -14,23 +14,44 @@
* limitations under the License.
*/
#include <functional>
#include "CallbackUtils.h"
struct {
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils) {
#ifdef ANDROID
jclass handlerClass;
jmethodID post;
callbackUtils.handlerClass = env->FindClass("android/os/Handler");
callbackUtils.handlerClass = (jclass) env->NewGlobalRef(callbackUtils.handlerClass);
callbackUtils.post = env->GetMethodID(callbackUtils.handlerClass,
"post", "(Ljava/lang/Runnable;)Z");
#endif
jclass executorClass;
jmethodID execute;
} gCallbackUtils;
callbackUtils.executorClass = env->FindClass("java/util/concurrent/Executor");
callbackUtils.executorClass = (jclass) env->NewGlobalRef(callbackUtils.executorClass);
callbackUtils.execute = env->GetMethodID(callbackUtils.executorClass,
"execute", "(Ljava/lang/Runnable;)V");
}
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback) {
if (handler && callback) {
#ifdef ANDROID
if (env->IsInstanceOf(handler, callbackUtils.handlerClass)) {
env->CallBooleanMethod(handler, callbackUtils.post, callback);
}
#endif
if (env->IsInstanceOf(handler, callbackUtils.executorClass)) {
env->CallVoidMethod(handler, callbackUtils.execute, callback);
}
}
env->DeleteGlobalRef(handler);
env->DeleteGlobalRef(callback);
#ifdef ANDROID
env->DeleteGlobalRef(callbackUtils.handlerClass);
#endif
env->DeleteGlobalRef(callbackUtils.executorClass);
}
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
void* that = engine->streamAlloc(sizeof(JniBufferCallback), alignof(JniBufferCallback));
return new (that) JniBufferCallback(env, handler, callback, std::move(buffer));
return new JniBufferCallback(env, handler, callback, std::move(buffer));
}
JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callback,
@@ -38,71 +59,39 @@ JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callb
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mBuffer(std::move(buffer)){
, mBuffer(std::move(buffer)) {
acquireCallbackJni(env, mCallbackUtils);
}
JniBufferCallback::~JniBufferCallback() {
if (mHandler && mCallback) {
#ifdef ANDROID
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
}
#endif
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
}
}
mEnv->DeleteGlobalRef(mHandler);
mEnv->DeleteGlobalRef(mCallback);
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
void JniBufferCallback::invoke(void*, size_t, void* user) {
JniBufferCallback* data = reinterpret_cast<JniBufferCallback*>(user);
// don't call delete here, because we don't own the storage
data->~JniBufferCallback();
delete data;
}
// -----------------------------------------------------------------------------------------------
JniImageCallback* JniImageCallback::make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, long image) {
void* that = engine->streamAlloc(sizeof(JniImageCallback), alignof(JniImageCallback));
return new (that) JniImageCallback(env, handler, callback, image);
return new JniImageCallback(env, handler, callback, image);
}
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback))
, mImage(image) { }
, mImage(image) {
acquireCallbackJni(env, mCallbackUtils);
}
JniImageCallback::~JniImageCallback() {
if (mHandler && mCallback) {
#ifdef ANDROID
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.handlerClass)) {
mEnv->CallBooleanMethod(mHandler, gCallbackUtils.post, mCallback);
}
#endif
if (mEnv->IsInstanceOf(mHandler, gCallbackUtils.executorClass)) {
mEnv->CallVoidMethod(mHandler, gCallbackUtils.execute, mCallback);
}
}
mEnv->DeleteGlobalRef(mHandler);
mEnv->DeleteGlobalRef(mCallback);
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
void JniImageCallback::invoke(void* image, void* user) {
reinterpret_cast<JniImageCallback*>(user)->~JniImageCallback();
}
void registerCallbackUtils(JNIEnv *env) {
#ifdef ANDROID
gCallbackUtils.handlerClass = env->FindClass("android/os/Handler");
gCallbackUtils.handlerClass = (jclass) env->NewGlobalRef(gCallbackUtils.handlerClass);
gCallbackUtils.post = env->GetMethodID(gCallbackUtils.handlerClass,
"post", "(Ljava/lang/Runnable;)Z");
#endif
gCallbackUtils.executorClass = env->FindClass("java/util/concurrent/Executor");
gCallbackUtils.executorClass = (jclass) env->NewGlobalRef(gCallbackUtils.executorClass);
gCallbackUtils.execute = env->GetMethodID(gCallbackUtils.executorClass,
"execute", "(Ljava/lang/Runnable;)V");
void JniImageCallback::invoke(void*, void* user) {
JniImageCallback* data = reinterpret_cast<JniImageCallback*>(user);
delete data;
}

View File

@@ -23,6 +23,18 @@
#include <filament/Engine.h>
struct CallbackJni {
#ifdef ANDROID
jclass handlerClass = nullptr;
jmethodID post = nullptr;
#endif
jclass executorClass = nullptr;
jmethodID execute = nullptr;
};
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils);
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback);
struct JniBufferCallback {
static JniBufferCallback* make(filament::Engine* engine,
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
@@ -31,12 +43,15 @@ struct JniBufferCallback {
private:
JniBufferCallback(JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
JniBufferCallback(JniBufferCallback const &) = delete;
JniBufferCallback(JniBufferCallback&&) = delete;
~JniBufferCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
AutoBuffer mBuffer;
CallbackJni mCallbackUtils;
};
struct JniImageCallback {
@@ -47,10 +62,13 @@ struct JniImageCallback {
private:
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
JniImageCallback(JniBufferCallback const &) = delete;
JniImageCallback(JniBufferCallback&&) = delete;
~JniImageCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
long mImage;
CallbackJni mCallbackUtils;
};

View File

@@ -18,20 +18,28 @@
#include <algorithm>
struct {
jclass jniClass;
jmethodID getBasePointer;
jmethodID getBaseArray;
jmethodID getBaseArrayOffset;
jmethodID getBufferType;
} gNioUtils;
#include <utils/Log.h>
AutoBuffer::AutoBuffer(JNIEnv *env, jobject buffer, jint size, bool commit) noexcept : mEnv(env),
AutoBuffer::AutoBuffer(JNIEnv *env, jobject buffer, jint size, bool commit) noexcept :
mEnv(env),
mDoCommit(commit) {
mNioUtils.jniClass = env->FindClass("com/google/android/filament/NioUtils");
mNioUtils.jniClass = (jclass) env->NewGlobalRef(mNioUtils.jniClass);
mNioUtils.getBasePointer = env->GetStaticMethodID(mNioUtils.jniClass,
"getBasePointer", "(Ljava/nio/Buffer;JI)J");
mNioUtils.getBaseArray = env->GetStaticMethodID(mNioUtils.jniClass,
"getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
mNioUtils.getBaseArrayOffset = env->GetStaticMethodID(mNioUtils.jniClass,
"getBaseArrayOffset", "(Ljava/nio/Buffer;I)I");
mNioUtils.getBufferType = env->GetStaticMethodID(mNioUtils.jniClass,
"getBufferType", "(Ljava/nio/Buffer;)I");
mBuffer = env->NewGlobalRef(buffer);
mType = (BufferType) env->CallStaticIntMethod(
gNioUtils.jniClass, gNioUtils.getBufferType, mBuffer);
mNioUtils.jniClass, mNioUtils.getBufferType, mBuffer);
switch (mType) {
case BufferType::BYTE:
@@ -56,16 +64,16 @@ AutoBuffer::AutoBuffer(JNIEnv *env, jobject buffer, jint size, bool commit) noex
jlong address = (jlong) env->GetDirectBufferAddress(mBuffer);
if (address) {
// Direct buffer case
mData = reinterpret_cast<void *>(env->CallStaticLongMethod(gNioUtils.jniClass,
gNioUtils.getBasePointer, mBuffer, address, mShift));
mData = reinterpret_cast<void *>(env->CallStaticLongMethod(mNioUtils.jniClass,
mNioUtils.getBasePointer, mBuffer, address, mShift));
mUserData = mData;
} else {
// wrapped array case
jarray array = (jarray) env->CallStaticObjectMethod(gNioUtils.jniClass,
gNioUtils.getBaseArray, mBuffer);
jarray array = (jarray) env->CallStaticObjectMethod(mNioUtils.jniClass,
mNioUtils.getBaseArray, mBuffer);
jint offset = env->CallStaticIntMethod(gNioUtils.jniClass,
gNioUtils.getBaseArrayOffset, mBuffer, mShift);
jint offset = env->CallStaticIntMethod(mNioUtils.jniClass,
mNioUtils.getBaseArrayOffset, mBuffer, mShift);
mBaseArray = (jarray) env->NewGlobalRef(array);
switch (mType) {
@@ -104,6 +112,7 @@ AutoBuffer::AutoBuffer(AutoBuffer &&rhs) noexcept {
std::swap(mShift, rhs.mShift);
std::swap(mBuffer, rhs.mBuffer);
std::swap(mBaseArray, rhs.mBaseArray);
std::swap(mNioUtils, rhs.mNioUtils);
}
AutoBuffer::~AutoBuffer() noexcept {
@@ -138,18 +147,5 @@ AutoBuffer::~AutoBuffer() noexcept {
if (mBuffer) {
env->DeleteGlobalRef(mBuffer);
}
}
void registerNioUtils(JNIEnv *env) {
gNioUtils.jniClass = env->FindClass("com/google/android/filament/NioUtils");
gNioUtils.jniClass = (jclass) env->NewGlobalRef(gNioUtils.jniClass);
gNioUtils.getBasePointer = env->GetStaticMethodID(gNioUtils.jniClass, "getBasePointer",
"(Ljava/nio/Buffer;JI)J");
gNioUtils.getBaseArray = env->GetStaticMethodID(gNioUtils.jniClass, "getBaseArray",
"(Ljava/nio/Buffer;)Ljava/lang/Object;");
gNioUtils.getBaseArrayOffset = env->GetStaticMethodID(gNioUtils.jniClass, "getBaseArrayOffset",
"(Ljava/nio/Buffer;I)I");
gNioUtils.getBufferType = env->GetStaticMethodID(gNioUtils.jniClass, "getBufferType",
"(Ljava/nio/Buffer;)I");
mEnv->DeleteGlobalRef(mNioUtils.jniClass);
}

View File

@@ -65,4 +65,12 @@ private:
jobject mBuffer = nullptr;
jarray mBaseArray = nullptr;
bool mDoCommit = false;
struct {
jclass jniClass;
jmethodID getBasePointer;
jmethodID getBaseArray;
jmethodID getBaseArrayOffset;
jmethodID getBufferType;
} mNioUtils{};
};

View File

@@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 3.6)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(FILAMAT_FLAVOR "filamat")
@@ -7,6 +9,10 @@ if(FILAMAT_LITE)
set(FILAMAT_FLAVOR "filamat_lite")
endif()
if (FILAMENT_SUPPORTS_VULKAN)
message("Library filamat ignores Vulkan settings")
endif()
add_library(${FILAMAT_FLAVOR} STATIC IMPORTED)
set_target_properties(${FILAMAT_FLAVOR} PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/lib${FILAMAT_FLAVOR}.a)
@@ -29,15 +35,6 @@ set_target_properties(shaders PROPERTIES IMPORTED_LOCATION
include_directories(${FILAMENT_DIR}/include)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-protector")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -ffp-contract=fast")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic-functions")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
add_library(filamat-jni SHARED
@@ -52,4 +49,3 @@ target_link_libraries(filamat-jni
log
smol-v
)

View File

@@ -1,26 +1,4 @@
apply plugin: 'com.android.library'
android {
buildToolsVersion versions.buildTools
compileSdkVersion versions.compileSdk
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
}
}
}
}
flavorDimensions "functionality"
productFlavors {
full {
@@ -37,23 +15,6 @@ android {
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {

View File

@@ -1,4 +1,4 @@
POM_NAME=Filament Material Builder
POM_ARTIFACT_ID_FULL=filamat-android-full
POM_ARTIFACT_ID_FULL=filamat-android
POM_ARTIFACT_ID_LITE=filamat-android-lite
POM_PACKAGING=aar

View File

@@ -81,6 +81,14 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderName(JN
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->name(name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterialDomain(JNIEnv* env,
jclass, jlong nativeBuilder, jint domain) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->materialDomain((MaterialBuilder::MaterialDomain) domain);
}
extern "C" JNIEXPORT void JNICALL
@@ -103,6 +111,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniform
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
@@ -111,6 +120,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniform
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
@@ -122,6 +132,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
@@ -130,6 +141,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariabl
const char* name = env->GetStringUTFChars(name_, nullptr);
auto builder = (MaterialBuilder*) nativeBuilder;
builder->variable((MaterialBuilder::Variable) variable, name);
env->ReleaseStringUTFChars(name_, name);
}
extern "C" JNIEXPORT void JNICALL
@@ -145,6 +157,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMateria
auto builder = (MaterialBuilder*) nativeBuilder;
const char* code = env->GetStringUTFChars(code_, nullptr);
builder->material(code);
env->ReleaseStringUTFChars(code_, code);
}
extern "C" JNIEXPORT void JNICALL
@@ -153,6 +166,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMateria
auto builder = (MaterialBuilder*) nativeBuilder;
const char* code = env->GetStringUTFChars(code_, nullptr);
builder->materialVertex(code);
env->ReleaseStringUTFChars(code_, code);
}
extern "C" JNIEXPORT void JNICALL
@@ -246,6 +260,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecula
builder->specularAntiAliasingThreshold(threshold);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderClearCoatIorChange(
JNIEnv*, jclass, jlong nativeBuilder, jboolean clearCoatIorChange) {
@@ -269,9 +284,23 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBo
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecularAmbientOcclusion(
JNIEnv*, jclass, jlong nativeBuilder, jboolean specularAO) {
JNIEnv*, jclass, jlong nativeBuilder, jint specularAO) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->specularAmbientOcclusion(specularAO);
builder->specularAmbientOcclusion((MaterialBuilder::SpecularAmbientOcclusion) specularAO);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionMode(JNIEnv* env,
jclass, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
jclass, jlong nativeBuilder, jint type) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->refractionType((MaterialBuilder::RefractionType) type);
}
extern "C" JNIEXPORT void JNICALL
@@ -304,7 +333,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderOptimiz
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariantFilter(JNIEnv*,
jclass, jlong nativeBuilder, jbyte variantFilter) {
jclass, jlong nativeBuilder, jint variantFilter) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->variantFilter((uint8_t) variantFilter);
}

View File

@@ -66,8 +66,10 @@ public class MaterialBuilder {
public enum SamplerType {
SAMPLER_2D, // 2D texture
SAMPLER_2D_ARRAY, // 2D array texture
SAMPLER_CUBEMAP, // Cube map texture
SAMPLER_EXTERNAL, // External texture
SAMPLER_3D // 3D texture
}
public enum SamplerFormat {
@@ -146,6 +148,28 @@ public class MaterialBuilder {
// mode is ignored. Can be combined with two-sided lighting
}
public enum MaterialDomain {
SURFACE,
POST_PROCESS
}
public enum SpecularAmbientOcclusion {
NONE,
SIMPLE,
BENT_NORMALS
}
public enum RefractionMode {
NONE,
CUBEMAP,
SCREEN_SPACE
}
public enum RefractionType {
SOLID,
THIN
}
public enum Platform {
DESKTOP,
MOBILE,
@@ -191,6 +215,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder materialDomain(MaterialDomain domain) {
nMaterialBuilderMaterialDomain(mNativeObject, domain.ordinal());
return this;
}
@NonNull
public MaterialBuilder shading(@NonNull Shading shading) {
nMaterialBuilderShading(mNativeObject, shading.ordinal());
@@ -325,6 +355,18 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder refractionMode(RefractionMode mode) {
nMaterialBuilderRefractionMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder refractionType(RefractionType type) {
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
return this;
}
@NonNull
public MaterialBuilder clearCoatIorChange(boolean clearCoatIorChange) {
nMaterialBuilderClearCoatIorChange(mNativeObject, clearCoatIorChange);
@@ -344,8 +386,8 @@ public class MaterialBuilder {
}
@NonNull
public MaterialBuilder specularAmbientOcclusion(boolean specularAO) {
nMaterialBuilderSpecularAmbientOcclusion(mNativeObject, specularAO);
public MaterialBuilder specularAmbientOcclusion(SpecularAmbientOcclusion specularAO) {
nMaterialBuilderSpecularAmbientOcclusion(mNativeObject, specularAO.ordinal());
return this;
}
@@ -374,7 +416,7 @@ public class MaterialBuilder {
}
@NonNull
public MaterialBuilder variantFilter(byte variantFilter) {
public MaterialBuilder variantFilter(int variantFilter) {
nMaterialBuilderVariantFilter(mNativeObject, variantFilter);
return this;
}
@@ -419,6 +461,7 @@ public class MaterialBuilder {
private static native void nDestroyPackage(long nativePackage);
private static native void nMaterialBuilderName(long nativeBuilder, String name);
private static native void nMaterialBuilderMaterialDomain(long nativeBuilder, int domain);
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,
@@ -450,17 +493,19 @@ public class MaterialBuilder {
float variance);
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
float threshold);
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
boolean multiBounceAO);
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,
boolean specularAO);
int specularAO);
private static native void nMaterialBuilderTransparencyMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
private static native void nMaterialBuilderTargetApi(long nativeBuilder, int api);
private static native void nMaterialBuilderOptimization(long nativeBuilder, int optimization);
private static native void nMaterialBuilderVariantFilter(long nativeBuilder,
byte variantFilter);
int variantFilter);
}

View File

@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.6)
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
add_library(filament STATIC IMPORTED)
@@ -38,23 +41,19 @@ add_library(smol-v STATIC IMPORTED)
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
if (FILAMENT_ENABLE_MATDBG)
add_library(matdbg STATIC IMPORTED)
set_target_properties(matdbg PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libmatdbg.a)
endif()
include_directories(.. ${FILAMENT_DIR}/include)
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-stack-protector")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffast-math -ffp-contract=fast")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility-inlines-hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
set(CMAKE_SHARED_LINKER_FLAGS" ${CMAKE_SHARED_LINKER_FLAGS} -Wl,-Bsymbolic-functions")
add_library(filament-jni-obj OBJECT
add_library(filament-jni SHARED
src/main/cpp/Camera.cpp
src/main/cpp/Colors.cpp
src/main/cpp/VertexBuffer.cpp
src/main/cpp/ColorGrading.cpp
src/main/cpp/Engine.cpp
src/main/cpp/EntityManager.cpp
src/main/cpp/Fence.cpp
@@ -70,46 +69,45 @@ add_library(filament-jni-obj OBJECT
src/main/cpp/Scene.cpp
src/main/cpp/SkyBox.cpp
src/main/cpp/Stream.cpp
src/main/cpp/SurfaceOrientation.cpp
src/main/cpp/Texture.cpp
src/main/cpp/TextureSampler.cpp
src/main/cpp/TransformManager.cpp
src/main/cpp/VertexBuffer.cpp
src/main/cpp/View.cpp
# Android specific
src/main/cpp/nativewindow/Android.cpp
# Private utils
src/main/cpp/Filament.cpp
# Common utils
../common/CallbackUtils.cpp
../common/NioUtils.cpp
)
if (NOT DISABLE_FILAMENT_JNI)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
target_link_libraries(filament-jni
PRIVATE filament
PRIVATE backend
PRIVATE filaflat
PRIVATE filabridge
PRIVATE geometry
PRIVATE ibl
PRIVATE log
PRIVATE GLESv3
PRIVATE EGL
PRIVATE android
PRIVATE jnigraphics
PRIVATE utils
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
target_include_directories(filament-jni PRIVATE
..
${FILAMENT_DIR}/include
../../third_party/robin-map
../../libs/utils/include)
add_library(filament-jni SHARED
$<TARGET_OBJECTS:filament-jni-obj>
# Private utils
src/main/cpp/Filament.cpp
# Common utils
../common/CallbackUtils.cpp
../common/NioUtils.cpp
)
target_link_libraries(filament-jni
filament
backend
filaflat
filabridge
geometry
ibl
utils
log
GLESv3
EGL
android
jnigraphics
)
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
if (FILAMENT_SUPPORTS_VULKAN)
target_link_libraries(filament-jni bluevk smol-v)
endif()
endif()
# Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})

View File

@@ -1,50 +1,3 @@
apply plugin: 'com.android.library'
android {
buildToolsVersion versions.buildTools
compileSdkVersion versions.compileSdk
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
}
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
// To enable validation layers with the Vulkan backend, uncomment the following lines
// to copy the appropriate files from the NDK to the device. Also be sure to use a debug
// configuration for the native build.
// jniLibs {
// srcDirs = ["${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"]
// }
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation deps.androidx.annotations
}

View File

@@ -1,4 +1,4 @@
LIBFILAMENT {
global: Java_com_google_android_filament_*; JNI*;
global: *filament*; JNI*;
local: *;
};

View File

@@ -18,6 +18,8 @@
#include <filament/Camera.h>
#include <math/mat4.h>
using namespace filament;
extern "C" JNIEXPORT void JNICALL
@@ -38,9 +40,9 @@ Java_com_google_android_filament_Camera_nSetProjectionFov(JNIEnv*, jclass ,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
jlong nativeCamera, jdouble focalLength, jdouble near, jdouble far) {
jlong nativeCamera, jdouble focalLength, jdouble aspect, jdouble near, jdouble far) {
Camera *camera = (Camera *) nativeCamera;
camera->setLensProjection(focalLength, near, far);
camera->setLensProjection(focalLength, aspect, near, far);
}
extern "C" JNIEXPORT void JNICALL
@@ -52,6 +54,15 @@ Java_com_google_android_filament_Camera_nSetCustomProjection(JNIEnv *env, jclass
env->ReleaseDoubleArrayElements(inMatrix_, inMatrix, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
jlong nativeCamera, jdoubleArray inScaling_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *inScaling = env->GetDoubleArrayElements(inScaling_, NULL);
camera->setScaling(*reinterpret_cast<const filament::math::double4*>(inScaling));
env->ReleaseDoubleArrayElements(inScaling_, inScaling, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nLookAt(JNIEnv*, jclass, jlong nativeCamera,
jdouble eye_x, jdouble eye_y, jdouble eye_z, jdouble center_x, jdouble center_y,
@@ -92,6 +103,26 @@ Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetCullingProjectionMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray out_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
const filament::math::mat4& m = camera->getCullingProjectionMatrix();
std::copy_n(&m[0][0], 16, out);
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetScaling(JNIEnv *env, jclass,
jlong nativeCamera, jdoubleArray out_) {
Camera *camera = (Camera *) nativeCamera;
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
const filament::math::double4& s = camera->getScaling();
std::copy_n(&s[0], 4, out);
env->ReleaseDoubleArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Camera_nGetModelMatrix(JNIEnv *env, jclass,
jlong nativeCamera, jfloatArray out_) {

View File

@@ -0,0 +1,172 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <filament/ColorGrading.h>
#include <math/vec3.h>
#include <math/vec4.h>
using namespace filament;
using namespace math;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ColorGrading_nCreateBuilder(JNIEnv*, jclass) {
return (jlong) new ColorGrading::Builder();
}
extern "C" JNIEXPORT void JNICALL
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) {
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_) {
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_nBuilderToneMapping(JNIEnv*, jclass,
jlong nativeBuilder, jint toneMapping_) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
ColorGrading::ToneMapping toneMapping = (ColorGrading::ToneMapping) toneMapping_;
builder->toneMapping(toneMapping);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderWhiteBalance(JNIEnv*, jclass,
jlong nativeBuilder, jfloat temperature, jfloat tint) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->whiteBalance(temperature, tint);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderChannelMixer(JNIEnv* env, jclass,
jlong nativeBuilder, jfloatArray outRed_, jfloatArray outGreen_, jfloatArray outBlue_) {
jfloat* outRed = env->GetFloatArrayElements(outRed_, nullptr);
jfloat* outGreen = env->GetFloatArrayElements(outGreen_, nullptr);
jfloat* outBlue = env->GetFloatArrayElements(outBlue_, nullptr);
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->channelMixer(
*reinterpret_cast<float3*>(outRed),
*reinterpret_cast<float3*>(outGreen),
*reinterpret_cast<float3*>(outBlue));
env->ReleaseFloatArrayElements(outRed_, outRed, JNI_ABORT);
env->ReleaseFloatArrayElements(outGreen_, outGreen, JNI_ABORT);
env->ReleaseFloatArrayElements(outBlue_, outBlue, JNI_ABORT);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderShadowsMidtonesHighlights(JNIEnv* env, jclass, jlong nativeBuilder,
jfloatArray shadows_, jfloatArray midtones_, jfloatArray highlights_, jfloatArray ranges_) {
jfloat* shadows = env->GetFloatArrayElements(shadows_, nullptr);
jfloat* midtones = env->GetFloatArrayElements(midtones_, nullptr);
jfloat* highlights = env->GetFloatArrayElements(highlights_, nullptr);
jfloat* ranges = env->GetFloatArrayElements(ranges_, nullptr);
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->shadowsMidtonesHighlights(
*reinterpret_cast<float4*>(shadows),
*reinterpret_cast<float4*>(midtones),
*reinterpret_cast<float4*>(highlights),
*reinterpret_cast<float4*>(ranges));
env->ReleaseFloatArrayElements(shadows_, shadows, JNI_ABORT);
env->ReleaseFloatArrayElements(midtones_, midtones, JNI_ABORT);
env->ReleaseFloatArrayElements(highlights_, highlights, JNI_ABORT);
env->ReleaseFloatArrayElements(ranges_, ranges, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderSlopeOffsetPower(JNIEnv* env, jclass,
jlong nativeBuilder, jfloatArray slope_, jfloatArray offset_, jfloatArray power_) {
jfloat* slope = env->GetFloatArrayElements(slope_, nullptr);
jfloat* offset = env->GetFloatArrayElements(offset_, nullptr);
jfloat* power = env->GetFloatArrayElements(power_, nullptr);
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->slopeOffsetPower(
*reinterpret_cast<float3*>(slope),
*reinterpret_cast<float3*>(offset),
*reinterpret_cast<float3*>(power));
env->ReleaseFloatArrayElements(slope_, slope, JNI_ABORT);
env->ReleaseFloatArrayElements(offset_, offset, JNI_ABORT);
env->ReleaseFloatArrayElements(power_, power, JNI_ABORT);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderContrast(JNIEnv*, jclass,
jlong nativeBuilder, jfloat contrast) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->contrast(contrast);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderVibrance(JNIEnv*, jclass,
jlong nativeBuilder, jfloat vibrance) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->vibrance(vibrance);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderSaturation(JNIEnv*, jclass,
jlong nativeBuilder, jfloat saturation) {
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->saturation(saturation);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_ColorGrading_nBuilderCurves(JNIEnv* env, jclass,
jlong nativeBuilder, jfloatArray gamma_, jfloatArray midPoint_, jfloatArray scale_) {
jfloat* gamma = env->GetFloatArrayElements(gamma_, nullptr);
jfloat* midPoint = env->GetFloatArrayElements(midPoint_, nullptr);
jfloat* scale = env->GetFloatArrayElements(scale_, nullptr);
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
builder->curves(
*reinterpret_cast<float3*>(gamma),
*reinterpret_cast<float3*>(midPoint),
*reinterpret_cast<float3*>(scale));
env->ReleaseFloatArrayElements(gamma_, gamma, JNI_ABORT);
env->ReleaseFloatArrayElements(midPoint_, midPoint, JNI_ABORT);
env->ReleaseFloatArrayElements(scale_, scale, JNI_ABORT);
}

View File

@@ -76,12 +76,12 @@ Java_com_google_android_filament_Engine_nCreateSwapChainFromRawPointer(JNIEnv*,
return (jlong) engine->createSwapChain((void*)pointer, (uint64_t) flags);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroySwapChain(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSwapChain) {
Engine* engine = (Engine*) nativeEngine;
SwapChain *swapChain = (SwapChain *) nativeSwapChain;
engine->destroy(swapChain);
return engine->destroy(swapChain);
}
// View
@@ -93,12 +93,12 @@ Java_com_google_android_filament_Engine_nCreateView(JNIEnv*, jclass,
return (jlong) engine->createView();
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyView(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeView) {
Engine* engine = (Engine*) nativeEngine;
View *view = (View *) nativeView;
engine->destroy(view);
return engine->destroy(view);
}
// Renderer
@@ -110,17 +110,17 @@ Java_com_google_android_filament_Engine_nCreateRenderer(JNIEnv*, jclass,
return (jlong) engine->createRenderer();
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeRenderer) {
Engine* engine = (Engine*) nativeEngine;
Renderer *renderer = (Renderer *) nativeRenderer;
engine->destroy(renderer);
return engine->destroy(renderer);
}
// Camera
extern "C" JNIEXPORT jlong JNICALL
extern "C" [[deprecated]] JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
@@ -135,7 +135,15 @@ Java_com_google_android_filament_Engine_nCreateCameraWithEntity(JNIEnv*, jclass,
return (jlong) engine->createCamera(entity);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetCameraComponent(JNIEnv*, jclass,
jlong nativeEngine, jint entity_) {
Engine* engine = (Engine*) nativeEngine;
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
return (jlong) engine->getCameraComponent(entity);
}
extern "C" [[deprecated]] JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nDestroyCamera(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeCamera) {
Engine* engine = (Engine*) nativeEngine;
@@ -152,12 +160,12 @@ Java_com_google_android_filament_Engine_nCreateScene(JNIEnv*, jclass,
return (jlong) engine->createScene();
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeScene) {
Engine* engine = (Engine*) nativeEngine;
Scene *scene = (Scene *) nativeScene;
engine->destroy(scene);
return engine->destroy(scene);
}
// Fence
@@ -169,89 +177,96 @@ Java_com_google_android_filament_Engine_nCreateFence(JNIEnv*, jclass,
return (jlong) engine->createFence();
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyFence(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeFence) {
Engine* engine = (Engine*) nativeEngine;
Fence *fence = (Fence *) nativeFence;
engine->destroy(fence);
return engine->destroy(fence);
}
// Stream
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyStream(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeStream) {
Engine* engine = (Engine*) nativeEngine;
Stream *stream = (Stream *) nativeStream;
engine->destroy(stream);
return engine->destroy(stream);
}
// Others...
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndexBuffer) {
Engine* engine = (Engine*) nativeEngine;
IndexBuffer *indexBuffer = (IndexBuffer *) nativeIndexBuffer;
engine->destroy(indexBuffer);
return engine->destroy(indexBuffer);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyVertexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeVertexBuffer) {
Engine* engine = (Engine*) nativeEngine;
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
engine->destroy(vertexBuffer);
return engine->destroy(vertexBuffer);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {
Engine* engine = (Engine*) nativeEngine;
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
engine->destroy(indirectLight);
return engine->destroy(indirectLight);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyMaterial(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterial) {
Engine* engine = (Engine*) nativeEngine;
Material *material = (Material *) nativeMaterial;
engine->destroy(material);
return engine->destroy(material);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyMaterialInstance(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterialInstance) {
Engine* engine = (Engine*) nativeEngine;
MaterialInstance* materialInstance =
(MaterialInstance*) nativeMaterialInstance;
engine->destroy(materialInstance);
MaterialInstance* materialInstance = (MaterialInstance*) nativeMaterialInstance;
return engine->destroy(materialInstance);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroySkybox(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkybox) {
Engine* engine = (Engine*) nativeEngine;
Skybox *skybox = (Skybox *) nativeSkybox;
engine->destroy(skybox);
return engine->destroy(skybox);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyColorGrading(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeColorGrading) {
Engine* engine = (Engine*) nativeEngine;
ColorGrading* colorGrading = (ColorGrading*) nativeColorGrading;
return engine->destroy(colorGrading);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyTexture(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeTexture) {
Engine* engine = (Engine*) nativeEngine;
Texture *texture = (Texture *) nativeTexture;
engine->destroy(texture);
return engine->destroy(texture);
}
extern "C" JNIEXPORT void JNICALL
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyRenderTarget(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeTarget) {
Engine* engine = (Engine*) nativeEngine;
RenderTarget* target = (RenderTarget*) nativeTarget;
engine->destroy(target);
return engine->destroy(target);
}
extern "C" JNIEXPORT void JNICALL

View File

@@ -16,24 +16,16 @@
#include <jni.h>
extern void registerCallbackUtils(JNIEnv*);
extern void registerMaterial(JNIEnv*);
extern void registerNioUtils(JNIEnv*);
namespace filament {
extern jint JNI_OnLoad(JavaVM* vm, void* reserved);
};
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
registerCallbackUtils(env);
registerMaterial(env);
registerNioUtils(env);
#if ANDROID
::filament::JNI_OnLoad(vm, reserved);
#endif

View File

@@ -20,6 +20,7 @@
#include <filament/Texture.h>
#include <common/NioUtils.h>
#include <common/CallbackUtils.h>
#include <math/mat4.h>
using namespace filament;
@@ -124,7 +125,7 @@ Java_com_google_android_filament_IndirectLight_nGetRotation(JNIEnv* env, jclass,
}
extern "C" JNIEXPORT void JNICALL
extern "C" [[deprecated]] JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetDirectionEstimate(JNIEnv* env, jclass,
jlong nativeIndirectLight, jfloatArray outDirection_) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
@@ -133,7 +134,7 @@ Java_com_google_android_filament_IndirectLight_nGetDirectionEstimate(JNIEnv* env
env->ReleaseFloatArrayElements(outDirection_, outDirection, 0);
}
extern "C" JNIEXPORT void JNICALL
extern "C" [[deprecated]] JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetColorEstimate(JNIEnv* env, jclass,
jlong nativeIndirectLight, jfloatArray outColor_, jfloat x, jfloat y, jfloat z) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
@@ -143,6 +144,22 @@ Java_com_google_android_filament_IndirectLight_nGetColorEstimate(JNIEnv* env, jc
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_IndirectLight_nGetReflectionsTexture(JNIEnv* env, jclass,
jlong nativeIndirectLight) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
Texture const *tex = indirectLight->getReflectionsTexture();
return (jlong) tex;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_IndirectLight_nGetIrradianceTexture(JNIEnv* env, jclass,
jlong nativeIndirectLight) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
Texture const *tex = indirectLight->getIrradianceTexture();
return (jlong) tex;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetDirectionEstimateStatic(JNIEnv *env, jclass,
jfloatArray sh_, jfloatArray outDirection_) {
@@ -162,4 +179,4 @@ Java_com_google_android_filament_IndirectLight_nGetColorEstimateStatic(JNIEnv *e
IndirectLight::getColorEstimate((filament::math::float3*)sh, math::float3{x, y, z});
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
env->ReleaseFloatArrayElements(sh_, sh, JNI_ABORT);
}
}

View File

@@ -20,9 +20,18 @@
#include <utils/Entity.h>
#include <algorithm>
using namespace filament;
using namespace utils;
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_LightManager_nGetComponentCount(JNIEnv*, jclass,
jlong nativeLightManager) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getComponentCount();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nHasComponent(JNIEnv*, jclass,
jlong nativeLightManager, jint entity) {
@@ -64,18 +73,32 @@ Java_com_google_android_filament_LightManager_nBuilderCastShadows(JNIEnv*, jclas
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv*, jclass,
jlong nativeBuilder, jint mapSize, jfloat constantBias, jfloat normalBias, jfloat shadowFar,
jfloat shadowNearHint, jfloat shadowFarHint, jboolean stable) {
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env, jclass,
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->shadowOptions(
LightManager::ShadowOptions{.mapSize = (uint32_t)mapSize,
.constantBias = constantBias,
.normalBias = normalBias,
.shadowFar = shadowFar,
.shadowNearHint = shadowNearHint,
.shadowFarHint = shadowFarHint,
.stable = (bool)stable});
LightManager::ShadowOptions shadowOptions {
.mapSize = (uint32_t)mapSize,
.shadowCascades = (uint8_t)cascades,
.constantBias = constantBias,
.normalBias = normalBias,
.shadowFar = shadowFar,
.shadowNearHint = shadowNearHint,
.shadowFarHint = shadowFarHint,
.stable = (bool)stable,
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
.stepCount = uint8_t(stepCount),
.maxShadowDistance = maxShadowDistance
};
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));
for (jsize i = 0; i < splitCount; i++) {
shadowOptions.cascadeSplitPositions[i] = nativeSplits[i];
}
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
builder->shadowOptions(shadowOptions);
}
extern "C" JNIEXPORT void JNICALL
@@ -106,6 +129,13 @@ Java_com_google_android_filament_LightManager_nBuilderColor(JNIEnv*, jclass,
builder->color({linearR, linearG, linearB});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderIntensityCandela(JNIEnv*, jclass,
jlong nativeBuilder, jfloat intensity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->intensityCandela(intensity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderIntensity__JF(JNIEnv*, jclass,
jlong nativeBuilder, jfloat intensity) {
@@ -155,6 +185,30 @@ Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclas
builder->sunHaloFalloff(haloFalloff);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nComputeUniformSplits(JNIEnv* env, jclass,
jfloatArray splitPositions, jint cascades) {
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
LightManager::ShadowCascades::computeUniformSplits(nativeSplits, (uint8_t) cascades);
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nComputeLogSplits(JNIEnv* env, jclass,
jfloatArray splitPositions, jint cascades, jfloat near, jfloat far) {
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
LightManager::ShadowCascades::computeLogSplits(nativeSplits, (uint8_t) cascades, near, far);
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nComputePracticalSplits(JNIEnv* env, jclass,
jfloatArray splitPositions, jint cascades, jfloat near, jfloat far, jfloat lambda) {
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
LightManager::ShadowCascades::computePracticalSplits(nativeSplits, (uint8_t) cascades, near, far, lambda);
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) {
@@ -232,6 +286,13 @@ Java_com_google_android_filament_LightManager_nSetIntensity__JIFF(JNIEnv*, jclas
lm->setIntensity((LightManager::Instance) i, watts, efficiency);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetIntensityCandela(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat intensity) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setIntensityCandela((LightManager::Instance) i, intensity);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetIntensity(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
@@ -282,7 +343,7 @@ Java_com_google_android_filament_LightManager_nSetSunHaloSize(JNIEnv*, jclass,
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetHaloSize(JNIEnv*, jclass,
Java_com_google_android_filament_LightManager_nGetSunHaloSize(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getSunHaloSize((LightManager::Instance) i);
@@ -296,7 +357,7 @@ Java_com_google_android_filament_LightManager_nSetSunHaloFalloff(JNIEnv*, jclass
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetHaloFalloff(JNIEnv*, jclass,
Java_com_google_android_filament_LightManager_nGetSunHaloFalloff(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getSunHaloFalloff((LightManager::Instance) i);
@@ -304,7 +365,7 @@ Java_com_google_android_filament_LightManager_nGetHaloFalloff(JNIEnv*, jclass,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetShadowCaster(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat shadowCaster) {
jlong nativeLightManager, jint i, jboolean shadowCaster) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setShadowCaster((LightManager::Instance) i, shadowCaster);
}
@@ -313,5 +374,5 @@ extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nIsShadowCaster(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->isShadowCaster((LightManager::Instance) i);
return (jboolean)lm->isShadowCaster((LightManager::Instance) i);
}

View File

@@ -22,12 +22,6 @@
using namespace filament;
struct {
jclass parameterClass;
jmethodID parameterAdd;
jfieldID parameterSamplerOffset;
} gMaterial;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size) {
@@ -53,6 +47,16 @@ Java_com_google_android_filament_Material_nCreateInstance(JNIEnv*, jclass,
return (jlong) material->createInstance();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nCreateInstanceWithName(JNIEnv* env, jclass,
jlong nativeMaterial, jstring name_) {
Material* material = (Material*) nativeMaterial;
const char *name = env->GetStringUTFChars(name_, 0);
jlong instance = (jlong) material->createInstance(name);
env->ReleaseStringUTFChars(name_, name);
return instance;
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_android_filament_Material_nGetName(JNIEnv* env, jclass, jlong nativeMaterial) {
@@ -191,16 +195,27 @@ Java_com_google_android_filament_Material_nGetParameters(JNIEnv* env, jclass,
size_t received = material->getParameters(info, (size_t) count);
assert(received == count);
jint offset = env->GetStaticIntField(gMaterial.parameterClass, gMaterial.parameterSamplerOffset);
jclass parameterClass = env->FindClass("com/google/android/filament/Material$Parameter");
parameterClass = (jclass) env->NewLocalRef(parameterClass);
jmethodID parameterAdd = env->GetStaticMethodID(parameterClass, "add",
"(Ljava/util/List;Ljava/lang/String;III)V");
jfieldID parameterSamplerOffset = env->GetStaticFieldID(parameterClass,
"SAMPLER_OFFSET", "I");
jint offset = env->GetStaticIntField(parameterClass, parameterSamplerOffset);
for (size_t i = 0; i < received; i++) {
jint type = info[i].isSampler ? (jint) info[i].samplerType + offset : (jint) info[i].type;
env->CallStaticVoidMethod(
gMaterial.parameterClass, gMaterial.parameterAdd,
parameterClass, parameterAdd,
parameters, env->NewStringUTF(info[i].name), type, (jint) info[i].precision,
(jint) info[i].count);
}
env->DeleteLocalRef(parameterClass);
delete[] info;
}
@@ -221,14 +236,3 @@ Java_com_google_android_filament_Material_nHasParameter(JNIEnv* env, jclass,
env->ReleaseStringUTFChars(name_, name);
return (jboolean) hasParameter;
}
void registerMaterial(JNIEnv *env) {
gMaterial.parameterClass = env->FindClass("com/google/android/filament/Material$Parameter");
gMaterial.parameterClass = (jclass) env->NewGlobalRef(gMaterial.parameterClass);
gMaterial.parameterAdd = env->GetStaticMethodID(gMaterial.parameterClass, "add",
"(Ljava/util/List;Ljava/lang/String;III)V");
gMaterial.parameterSamplerOffset = env->GetStaticFieldID(gMaterial.parameterClass,
"SAMPLER_OFFSET", "I");
}

View File

@@ -324,3 +324,43 @@ Java_com_google_android_filament_MaterialInstance_nSetCullingMode(JNIEnv*,
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setCullingMode((MaterialInstance::CullingMode) cullingMode);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetColorWrite(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setColorWrite(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthWrite(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDepthWrite(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDepthCulling(enable);
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_android_filament_MaterialInstance_nGetName(JNIEnv* env, jclass,
jlong nativeMaterialInstance) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
return env->NewStringUTF(instance->getName());
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_MaterialInstance_nGetMaterial(JNIEnv* env, jclass,
jlong nativeMaterialInstance) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
return (jlong) instance->getMaterial();
}

View File

@@ -39,7 +39,7 @@ Java_com_google_android_filament_RenderTarget_nDestroyBuilder(JNIEnv *env, jclas
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderTarget_nBuilderTexture(JNIEnv *env, jclass type,
jlong nativeBuilder, jlong attachment, jlong nativeTexture) {
jlong nativeBuilder, jint attachment, jlong nativeTexture) {
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
Texture* texture = (Texture*) nativeTexture;
builder->texture(RenderTarget::AttachmentPoint(attachment), texture);
@@ -47,14 +47,14 @@ Java_com_google_android_filament_RenderTarget_nBuilderTexture(JNIEnv *env, jclas
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderTarget_nBuilderMipLevel(JNIEnv *env, jclass type,
jlong nativeBuilder, jlong attachment, jint level) {
jlong nativeBuilder, jint attachment, jint level) {
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
builder->mipLevel(RenderTarget::AttachmentPoint(attachment), level);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderTarget_nBuilderFace(JNIEnv *env, jclass type,
jlong nativeBuilder, jlong attachment, jint face) {
jlong nativeBuilder, jint attachment, jint face) {
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
RenderTarget::CubemapFace cubeface = (RenderTarget::CubemapFace) face;
builder->face(RenderTarget::AttachmentPoint(attachment), cubeface);
@@ -62,7 +62,7 @@ Java_com_google_android_filament_RenderTarget_nBuilderFace(JNIEnv *env, jclass t
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderTarget_nBuilderLayer(JNIEnv *env, jclass type,
jlong nativeBuilder, jlong attachment, jint layer) {
jlong nativeBuilder, jint attachment, jint layer) {
RenderTarget::Builder* builder = (RenderTarget::Builder*) nativeBuilder;
builder->layer(RenderTarget::AttachmentPoint(attachment), layer);
}
@@ -77,7 +77,21 @@ Java_com_google_android_filament_RenderTarget_nBuilderBuild(JNIEnv *env, jclass
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderTarget_nGetMipLevel(JNIEnv *env, jclass type,
jlong nativeTarget, jlong attachment) {
jlong nativeTarget, jint attachment) {
RenderTarget* target = (RenderTarget*) nativeTarget;
return (jint) target->getMipLevel(RenderTarget::AttachmentPoint(attachment));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderTarget_nGetFace(JNIEnv *env, jclass type,
long nativeTarget, int attachment) {
RenderTarget* target = (RenderTarget*) nativeTarget;
return (jint) target->getFace(RenderTarget::AttachmentPoint(attachment));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderTarget_nGetLayer(JNIEnv *env, jclass type,
long nativeTarget, int attachment) {
RenderTarget* target = (RenderTarget*) nativeTarget;
return (jint) target->getLayer(RenderTarget::AttachmentPoint(attachment));
}

View File

@@ -14,7 +14,6 @@
* limitations under the License.
*/
#include <jni.h>
#include <filament/RenderableManager.h>
@@ -164,6 +163,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderReceiveShadows(JNIEnv
builder->receiveShadows(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderScreenSpaceContactShadows(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->screenSpaceContactShadows(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jclass,
jlong nativeBuilder, jint boneCount) {
@@ -261,6 +267,13 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setCulling((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCastShadows(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
@@ -275,6 +288,13 @@ Java_com_google_android_filament_RenderableManager_nSetReceiveShadows(JNIEnv*, j
rm->setReceiveShadows((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetScreenSpaceContactShadows(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setScreenSpaceContactShadows((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nIsShadowCaster(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {

View File

@@ -30,10 +30,10 @@ using namespace backend;
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Renderer_nBeginFrame(JNIEnv *, jclass, jlong nativeRenderer,
jlong nativeSwapChain) {
jlong nativeSwapChain, jlong frameTimeNanos) {
Renderer *renderer = (Renderer *) nativeRenderer;
SwapChain *swapChain = (SwapChain *) nativeSwapChain;
return (jboolean) renderer->beginFrame(swapChain);
return (jboolean) renderer->beginFrame(swapChain, uint64_t(frameTimeNanos));
}
extern "C" JNIEXPORT void JNICALL
@@ -144,3 +144,32 @@ Java_com_google_android_filament_Renderer_nResetUserTime(JNIEnv*, jclass, jlong
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->resetUserTime();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSetDisplayInfo(JNIEnv*, jclass, jlong nativeRenderer,
jfloat refreshRate, jlong presentationDeadlineNanos, jlong vsyncOffsetNanos) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setDisplayInfo({ .refreshRate = refreshRate,
.presentationDeadlineNanos = (uint64_t)presentationDeadlineNanos,
.vsyncOffsetNanos = (uint64_t)vsyncOffsetNanos });
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSetFrameRateOptions(JNIEnv*, jclass,
jlong nativeRenderer, jfloat interval, jfloat headRoomRatio, jfloat scaleRate, jint history) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setFrameRateOptions({ .headRoomRatio = headRoomRatio,
.scaleRate = scaleRate,
.history = (uint8_t)history,
.interval = (uint8_t)interval });
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSetClearOptions(JNIEnv *, jclass ,
jlong nativeRenderer, jfloat r, jfloat g, jfloat b, jfloat a,
jboolean clear, jboolean discard) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setClearOptions({ .clearColor = {r, g, b, a},
.clear = (bool) clear,
.discard = (bool) discard});
}

View File

@@ -62,6 +62,15 @@ Java_com_google_android_filament_Scene_nRemove(JNIEnv *env, jclass type, jlong n
scene->remove((Entity&) entity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Scene_nRemoveEntities(JNIEnv *env, jclass type, jlong nativeScene,
jintArray entities) {
Scene* scene = (Scene*) nativeScene;
Entity* nativeEntities = (Entity*) env->GetIntArrayElements(entities, nullptr);
scene->removeEntities(nativeEntities, env->GetArrayLength(entities));
env->ReleaseIntArrayElements(entities, (jint*) nativeEntities, JNI_ABORT);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Scene_nGetRenderableCount(JNIEnv *env, jclass type,
jlong nativeScene) {

View File

@@ -18,6 +18,8 @@
#include <filament/Skybox.h>
#include <math/vec4.h>
using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
@@ -54,6 +56,13 @@ Java_com_google_android_filament_Skybox_nBuilderIntensity(JNIEnv *env, jclass cl
builder->intensity(intensity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
jlong nativeSkyBoxBuilder, jfloat r, jfloat g, jfloat b, jfloat a) {
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
builder->color({r, g, b, a});
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeSkyBoxBuilder, jlong nativeEngine) {
@@ -82,3 +91,18 @@ Java_com_google_android_filament_Skybox_nGetIntensity(JNIEnv *env, jclass clazz,
Skybox *skybox = (Skybox *) nativeSkybox;
return static_cast<jint>(skybox->getIntensity());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nSetColor(JNIEnv *, jclass,
jlong nativeSkybox, jfloat r, jfloat g, jfloat b, jfloat a) {
Skybox *skybox = (Skybox *) nativeSkybox;
skybox->setColor({r, g, b, a});
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybix_nGetTexture(JNIEnv* env, jclass,
jlong nativeSkybox) {
Skybox *skybox = (Skybox *) nativeSkybox;
Texture const *tex = skybox->getTexture();
return (jlong) tex;
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <geometry/SurfaceOrientation.h>
#include "common/NioUtils.h"
#include <algorithm>
using namespace filament;
using namespace filament::geometry;
using namespace filament::math;
namespace {
struct JniWrapper {
SurfaceOrientation::Builder* builder;
AutoBuffer* normals;
AutoBuffer* tangents;
AutoBuffer* uvs;
AutoBuffer* positions;
AutoBuffer* triangles16;
AutoBuffer* triangles32;
};
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_SurfaceOrientation_nCreateBuilder(JNIEnv* env, jclass) {
JniWrapper* wrapper = new JniWrapper();
wrapper->builder = new SurfaceOrientation::Builder();
return (jlong) wrapper;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nDestroyBuilder(JNIEnv* env, jclass,
jlong nativeBuilder) {
auto wrapper = (JniWrapper*) nativeBuilder;
delete wrapper->builder;
delete wrapper->normals;
delete wrapper->tangents;
delete wrapper->uvs;
delete wrapper->positions;
delete wrapper->triangles16;
delete wrapper->triangles32;
delete wrapper;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderVertexCount(JNIEnv* env, jclass,
jlong nativeBuilder, int vertexCount) {
auto wrapper = (JniWrapper *) nativeBuilder;
wrapper->builder->vertexCount(vertexCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderTriangleCount(JNIEnv* env, jclass,
jlong nativeBuilder, int triangleCount) {
auto wrapper = (JniWrapper *) nativeBuilder;
wrapper->builder->triangleCount(triangleCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderNormals(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, jint remaining, int stride) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->normals = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->normals((const float3 *) buffer->getData(), stride);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderTangents(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, jint remaining, int stride) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->tangents = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->tangents((const float4 *) buffer->getData(), stride);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderUVs(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, int remaining, int stride) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->uvs = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->uvs((const float2 *) buffer->getData(), stride);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderPositions(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, int remaining, int stride) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->positions = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->positions((const float3 *) buffer->getData(), stride);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderTriangles16(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, int remaining) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->triangles16 = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->triangles((const ushort3 *) buffer->getData());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderTriangles32(JNIEnv* env, jclass,
jlong nativeBuilder, jobject javaBuffer, int remaining) {
auto wrapper = (JniWrapper *) nativeBuilder;
AutoBuffer* buffer = wrapper->triangles32 = new AutoBuffer(env, javaBuffer, remaining);
wrapper->builder->triangles((const uint3 *) buffer->getData());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_SurfaceOrientation_nBuilderBuild(JNIEnv* env, jclass,
jlong nativeBuilder) {
auto wrapper = (JniWrapper *) nativeBuilder;
return (jlong) wrapper->builder->build();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_SurfaceOrientation_nGetVertexCount(JNIEnv* env, jclass,
jlong nativeObject) {
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
return helper->getVertexCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsFloat(JNIEnv* env, jclass,
jlong nativeObject, jobject javaBuffer, int remaining) {
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
AutoBuffer buffer(env, javaBuffer, remaining);
size_t requestedCount = std::min(buffer.getSize() / sizeof(float4), helper->getVertexCount());
helper->getQuats((quatf*) buffer.getData(), requestedCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsHalf(JNIEnv* env, jclass,
jlong nativeObject, jobject javaBuffer, int remaining) {
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
AutoBuffer buffer(env, javaBuffer, remaining);
size_t requestedCount = std::min(buffer.getSize() / sizeof(quath), helper->getVertexCount());
helper->getQuats((quath*) buffer.getData(), requestedCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nGetQuatsAsShort(JNIEnv* env, jclass,
jlong nativeObject, jobject javaBuffer, int remaining) {
SurfaceOrientation* helper = (SurfaceOrientation*) nativeObject;
AutoBuffer buffer(env, javaBuffer, remaining);
size_t requestedCount = std::min(buffer.getSize() / sizeof(short4), helper->getVertexCount());
helper->getQuats((short4*) buffer.getData(), requestedCount);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SurfaceOrientation_nDestroy(JNIEnv* env, jclass,
jlong nativeSurfaceOrientation) {
SurfaceOrientation* helper = (SurfaceOrientation*) nativeSurfaceOrientation;
delete helper;
}

View File

@@ -113,6 +113,14 @@ Java_com_google_android_filament_Texture_nBuilderUsage(JNIEnv*, jclass,
builder->usage((Texture::Usage) flags);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
jlong nativeBuilder, jint r, jint g, jint b, jint a) {
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
builder->swizzle(
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine) {
@@ -225,6 +233,76 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong nativeTexture,
jlong nativeEngine, jint level,
jint xoffset, jint yoffset, jint zoffset,
jint width, jint height, jint depth,
jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment,
jint stride, jint format,
jobject handler, jobject runnable) {
Texture* texture = (Texture*) nativeTexture;
Engine* engine = (Engine*) nativeEngine;
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
(Texture::Type) type, (size_t) stride, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
void *buffer = nioBuffer.getData();
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
(uint32_t) stride, &JniBufferCallback::invoke, callback);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
(uint32_t) width, (uint32_t) height, (uint32_t) depth,
std::move(desc));
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage3DCompressed(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level,
jint xoffset, jint yoffset, jint zoffset,
jint width, jint height, jint depth,
jobject storage, jint remaining,
jint, jint, jint, jint, jint compressedSizeInBytes, jint compressedFormat,
jobject handler, jobject runnable) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
size_t sizeInBytes = (size_t) compressedSizeInBytes;
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
void *buffer = nioBuffer.getData();
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
&JniBufferCallback::invoke, callback);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
(uint32_t) width, (uint32_t) height, (uint32_t) depth,
std::move(desc));
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
@@ -396,7 +474,21 @@ public:
}
}
AutoBitmap(JNIEnv* env, jobject bitmap, jobject handler, jobject runnable) noexcept
: mEnv(env)
, mBitmap(env->NewGlobalRef(bitmap))
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(runnable))
{
acquireCallbackJni(env, mCallbackUtils);
if (mBitmap) {
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
}
}
~AutoBitmap() noexcept {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
if (mBitmap) {
AndroidBitmap_unlockPixels(mEnv, mBitmap);
mEnv->DeleteGlobalRef(mBitmap);
@@ -430,6 +522,7 @@ public:
PixelDataType getType(int format) const noexcept {
switch (format) {
case BITMAP_CONFIG_RGB_565: return PixelDataType::USHORT_565;
case BITMAP_CONFIG_RGBA_F16: return PixelDataType::HALF;
default: return PixelDataType::UBYTE;
}
@@ -437,19 +530,26 @@ public:
static void invoke(void* buffer, size_t n, void* user) {
AutoBitmap* data = reinterpret_cast<AutoBitmap*>(user);
data->~AutoBitmap();
delete data;
}
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap) {
void* that = engine->streamAlloc(sizeof(AutoBitmap), alignof(AutoBitmap));
return new (that) AutoBitmap(env, bitmap);
return new AutoBitmap(env, bitmap);
}
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap,
jobject handler, jobject runnable) {
return new AutoBitmap(env, bitmap, handler, runnable);
}
private:
JNIEnv* mEnv;
void* mData = nullptr;
jobject mBitmap = nullptr;
jobject mHandler = nullptr;
jobject mCallback = nullptr;
AndroidBitmapInfo mInfo;
CallbackJni mCallbackUtils;
};
extern "C"
@@ -475,4 +575,27 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmap(JNIEnv* env, j
std::move(desc));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JNIEnv* env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
jint width, jint height, jobject bitmap, jint format, jobject handler, jobject runnable) {
Texture* texture = (Texture*) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap, handler, runnable);
Texture::PixelBufferDescriptor desc(
autoBitmap->getData(),
autoBitmap->getSizeInBytes(),
autoBitmap->getFormat(format),
autoBitmap->getType(format),
&AutoBitmap::invoke, autoBitmap);
texture->setImage(*engine, (size_t) level,
(uint32_t) xoffset, (uint32_t) yoffset,
(uint32_t) width, (uint32_t) height,
std::move(desc));
}
#endif

View File

@@ -17,9 +17,12 @@
#include <jni.h>
#include <utils/Entity.h>
#include <filament/TransformManager.h>
#include <utils/Entity.h>
#include <math/mat4.h>
using namespace utils;
using namespace filament;

View File

@@ -115,7 +115,7 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
return 0;
}
extern "C" JNIEXPORT void JNICALL
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,

View File

@@ -16,14 +16,14 @@
#include <jni.h>
#include <filament/Color.h>
#include <filament/View.h>
#include <filament/Viewport.h>
using namespace filament;
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass,
jlong nativeView, jstring name_) {
Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass, jlong nativeView, jstring name_) {
View* view = (View*) nativeView;
const char* name = env->GetStringUTFChars(name_, 0);
view->setName(name);
@@ -31,8 +31,7 @@ Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetScene(JNIEnv*, jclass,
jlong nativeView, jlong nativeScene) {
Java_com_google_android_filament_View_nSetScene(JNIEnv*, jclass, jlong nativeView, jlong nativeScene) {
View* view = (View*) nativeView;
Scene* scene = (Scene*) nativeScene;
view->setScene(scene);
@@ -46,6 +45,14 @@ Java_com_google_android_filament_View_nSetCamera(JNIEnv*, jclass,
view->setCamera(camera);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetColorGrading(JNIEnv*, jclass,
jlong nativeView, jlong nativeColorGrading) {
View* view = (View*) nativeView;
ColorGrading* colorGrading = (ColorGrading*) nativeColorGrading;
view->setColorGrading(colorGrading);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetViewport(JNIEnv*, jclass,
jlong nativeView, jint left, jint bottom, jint width, jint height) {
@@ -54,43 +61,13 @@ Java_com_google_android_filament_View_nSetViewport(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetClearColor(JNIEnv*, jclass,
jlong nativeView,
jfloat linearR, jfloat linearG, jfloat linearB, jfloat linearA) {
View* view = (View*) nativeView;
view->setClearColor({linearR, linearG, linearB, linearA});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nGetClearColor(JNIEnv* env, jclass,
jlong nativeView, jfloatArray out_) {
View* view = (View*) nativeView;
jfloat* out = env->GetFloatArrayElements(out_, NULL);
auto linearColor = view->getClearColor();
out[0] = linearColor[0];
out[1] = linearColor[1];
out[2] = linearColor[2];
out[3] = linearColor[3];
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetClearTargets(JNIEnv*, jclass,
jlong nativeView, jboolean color, jboolean depth, jboolean stencil) {
View* view = (View*) nativeView;
view->setClearTargets(color, depth, stencil);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass,
jlong nativeView, jint select, jint value) {
Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong nativeView, jint select, jint value) {
View* view = (View*) nativeView;
view->setVisibleLayers((uint8_t) select, (uint8_t) value);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass,
jlong nativeView, jboolean enabled) {
Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setShadowsEnabled(enabled);
}
@@ -103,50 +80,31 @@ Java_com_google_android_filament_View_nSetRenderTarget(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass,
jlong nativeView, jint count) {
Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, jlong nativeView, jint count) {
View* view = (View*) nativeView;
view->setSampleCount((uint8_t) count);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass,
jlong nativeView) {
Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return view->getSampleCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAntiAliasing(JNIEnv*, jclass,
jlong nativeView, jint type) {
Java_com_google_android_filament_View_nSetAntiAliasing(JNIEnv*, jclass, jlong nativeView, jint type) {
View* view = (View*) nativeView;
view->setAntiAliasing(View::AntiAliasing(type));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass,
jlong nativeView) {
Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return (jint) view->getAntiAliasing();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetToneMapping(JNIEnv*, jclass,
jlong nativeView, jint type) {
View* view = (View*) nativeView;
view->setToneMapping(View::ToneMapping(type));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetToneMapping(JNIEnv*, jclass,
jlong nativeView) {
View* view = (View*) nativeView;
return (jint) view->getToneMapping();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDithering(JNIEnv*, jclass,
jlong nativeView, jint dithering) {
Java_com_google_android_filament_View_nSetDithering(JNIEnv*, jclass, jlong nativeView, jint dithering) {
View* view = (View*) nativeView;
view->setDithering((View::Dithering) dithering);
}
@@ -159,20 +117,16 @@ Java_com_google_android_filament_View_nGetDithering(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*,
jclass, jlong nativeView, jboolean enabled, jboolean homogeneousScaling,
jfloat targetFrameTimeMilli, jfloat headRoomRatio, jfloat scaleRate,
jfloat minScale, jfloat maxScale, jint history) {
View* view = (View*) nativeView;
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jclass, jlong nativeView,
jboolean enabled, jboolean homogeneousScaling,
jfloat minScale, jfloat maxScale, jint quality) {
View* view = (View*)nativeView;
View::DynamicResolutionOptions options;
options.enabled = enabled;
options.homogeneousScaling = homogeneousScaling;
options.targetFrameTimeMilli = targetFrameTimeMilli;
options.headRoomRatio = headRoomRatio;
options.scaleRate = scaleRate;
options.minScale = filament::math::float2{minScale};
options.maxScale = filament::math::float2{maxScale};
options.history = (uint8_t) history;
options.minScale = filament::math::float2{ minScale };
options.maxScale = filament::math::float2{ maxScale };
options.quality = (View::QualityLevel)quality;
view->setDynamicResolutionOptions(options);
}
@@ -193,13 +147,6 @@ Java_com_google_android_filament_View_nSetDynamicLightingOptions(JNIEnv*,
view->setDynamicLightingOptions(zLightNear, zLightFar);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDepthPrepass(JNIEnv*,
jclass, jlong nativeView, jint value) {
View* view = (View*) nativeView;
view->setDepthPrepass(View::DepthPrepass(value));
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetPostProcessingEnabled(JNIEnv*,
jclass, jlong nativeView, jboolean enabled) {
@@ -231,25 +178,111 @@ Java_com_google_android_filament_View_nIsFrontFaceWindingInverted(JNIEnv*,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusion(JNIEnv*, jclass, jlong nativeView, jint ordinal) {
View* view = (View*) nativeView;
view->setAmbientOcclusion((View::AmbientOcclusion)ordinal);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
view->setAmbientOcclusion((View::AmbientOcclusion) ordinal);
#pragma clang diagnostic pop
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return (jint)view->getAmbientOcclusion();
#pragma clang diagnostic pop
}
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) {
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
jint quality, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = {
.radius = radius,
.bias = bias,
.power = power,
.bias = bias,
.resolution = resolution,
.intensity = intensity
.intensity = intensity,
.quality = (View::QualityLevel)quality,
.upsampling = (View::QualityLevel)upsampling,
.enabled = (bool)enabled,
.minHorizonAngleRad = minHorizonAngleRad
};
view->setAmbientOcclusionOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
jlong nativeView, jlong nativeTexture,
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight) {
View* view = (View*) nativeView;
Texture* dirt = (Texture*) nativeTexture;
View::BloomOptions options = {
.dirt = dirt,
.dirtStrength = dirtStrength,
.strength = strength,
.resolution = (uint32_t)resolution,
.anamorphism = anamorphism,
.levels = (uint8_t)levels,
.blendMode = (View::BloomOptions::BlendMode)blendMode,
.threshold = (bool)threshold,
.enabled = (bool)enabled,
.highlight = highlight
};
view->setBloomOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong nativeView,
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat r,
jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
jfloat inScatteringSize, jboolean fogColorFromIbl, jboolean enabled) {
View* view = (View*) nativeView;
View::FogOptions options = {
.distance = distance,
.maximumOpacity = maximumOpacity,
.height = height,
.heightFalloff = heightFalloff,
.color = math::float3{r, g, b},
.density = density,
.inScatteringStart = inScatteringStart,
.inScatteringSize = inScatteringSize,
.fogColorFromIbl = (bool)fogColorFromIbl,
.enabled = (bool)enabled
};
view->setFogOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nativeView, jint blendMode) {
View* view = (View*) nativeView;
view->setBlendMode((View::BlendMode)blendMode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass ,
jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled) {
View* view = (View*) nativeView;
view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale,
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVignetteOptions(JNIEnv*, jclass, jlong nativeView, jfloat midPoint, jfloat roundness,
jfloat feather, jfloat r, jfloat g, jfloat b, jfloat a, jboolean enabled) {
View* view = (View*) nativeView;
view->setVignetteOptions({.midPoint = midPoint, .roundness = roundness, .feather = feather,
.color = LinearColorA{r, g, b, a}, .enabled = (bool)enabled});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *, jclass,
jlong nativeView, jfloat feedback, jfloat filterWidth, jboolean enabled) {
View* view = (View*) nativeView;
view->setTemporalAntiAliasingOptions({
.filterWidth = filterWidth, .feedback = feedback, .enabled = (bool) enabled});
}

View File

@@ -78,6 +78,12 @@ final class Asserts {
return out;
}
static void assertFloat3In(@NonNull float[] out) {
if (out.length < 3) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 3");
}
}
@NonNull @Size(min = 4)
static float[] assertFloat4(@Nullable float[] out) {
if (out == null) out = new float[4];
@@ -86,4 +92,24 @@ final class Asserts {
}
return out;
}
static void assertFloat4In(@NonNull float[] out) {
if (out.length < 4) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
}
static double[] assertDouble4(@Nullable double[] out) {
if (out == null) out = new double[4];
else if (out.length < 4) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
return out;
}
static void assertDouble4In(@NonNull double[] in) {
if (in.length < 4) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
}
}

View File

@@ -195,7 +195,7 @@ public class Camera {
/**
* Sets the projection matrix from the field-of-view.
*
* @param fovInDegrees field-of-view in degrees from the camera center axis.
* @param fovInDegrees full field-of-view in degrees.
* 0 < <code>fovInDegrees</code> < 180
*
* @param aspect aspect ratio width/height. <code>aspect</code> > 0
@@ -226,9 +226,11 @@ public class Camera {
}
/**
* Sets the projection matrix from the focal length
* Sets the projection matrix from the focal length.
*
* @param focalLength lense's focal length in millimeters. <code>focalLength</code> > 0
* @param focalLength lens's focal length in millimeters. <code>focalLength</code> > 0
*
* @param aspect aspect ratio width/height. <code>aspect</code> > 0
*
* @param near distance in world units from the camera to the near plane.
* The near plane's position in view space is z = -<code>near</code>.
@@ -245,8 +247,8 @@ public class Camera {
* for {@link Projection#ORTHO}.
*
*/
public void setLensProjection(double focalLength, double near, double far) {
nSetLensProjection(getNativeObject(), focalLength, near, far);
public void setLensProjection(double focalLength, double aspect, double near, double far) {
nSetLensProjection(getNativeObject(), focalLength, aspect, near, far);
}
/**
@@ -274,6 +276,39 @@ public class Camera {
nSetCustomProjection(getNativeObject(), inMatrix, near, far);
}
/**
* Sets an additional matrix that scales the projection matrix.
*
* <p>This is useful to adjust the aspect ratio of the camera independent from its projection.
* First, pass an aspect of 1.0 to setProjection. Then set the scaling with the desired aspect
* ratio:<br>
*
* <code>
* double aspect = width / height;
*
* // with Fov.HORIZONTAL passed to setProjection:
* double[] s = {1.0, aspect, 1.0, 1.0};
* camera.setScaling(s);
*
* // with Fov.VERTICAL passed to setProjection:
* double[] s = {1.0 / aspect, 1.0, 1.0, 1.0};
* camera.setScaling(s);
* </code>
*
* By default, this is an identity matrix.
* </p>
*
* @param scaling diagonal of the scaling matrix to be applied after the projection matrix.
*
* @see Camera#setProjection
* @see Camera#setLensProjection
* @see Camera#setCustomProjection
*/
public void setScaling(@NonNull @Size(min = 4) double[] inScaling) {
Asserts.assertDouble4In(inScaling);
nSetScaling(getNativeObject(), inScaling);
}
/**
* Sets the camera's view matrix.
* <p>
@@ -327,7 +362,9 @@ public class Camera {
}
/**
* Retrieves the camera's projection matrix.
* Retrieves the camera's projection matrix. The projection matrix used for rendering always has
* its far plane set to infinity. This is why it may differ from the matrix set through
* setProjection() or setLensProjection().
*
* @param out A 16-float array where the projection matrix will be stored, or null in which
* case a new array is allocated.
@@ -341,6 +378,36 @@ public class Camera {
return out;
}
/**
* Retrieves the camera's culling matrix. The culling matrix is the same as the projection
* matrix, except the far plane is finite.
*
* @param out A 16-float array where the projection matrix will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-float array containing the camera's projection as a column-major matrix.
*/
@NonNull @Size(min = 16)
public double[] getCullingProjectionMatrix(@Nullable @Size(min = 16) double[] out) {
out = Asserts.assertMat4d(out);
nGetCullingProjectionMatrix(getNativeObject(), out);
return out;
}
/**
* Returns the scaling amount used to scale the projection matrix.
*
* @return the diagonal of the scaling matrix applied after the projection matrix.
*
* @see Camera#setScaling
*/
@NonNull @Size(min = 4)
public double[] getScaling(@Nullable @Size(min = 4) double[] out) {
out = Asserts.assertDouble4(out);
nGetScaling(getNativeObject(), out);
return out;
}
/**
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
* orientation, or pose.
@@ -517,13 +584,16 @@ public class Camera {
private static native void nSetProjection(long nativeCamera, int projection, double left, double right, double bottom, double top, double near, double far);
private static native void nSetProjectionFov(long nativeCamera, double fovInDegrees, double aspect, double near, double far, int fov);
private static native void nSetLensProjection(long nativeCamera, double focalLength, double near, double far);
private static native void nSetLensProjection(long nativeCamera, double focalLength, double aspect, double near, double far);
private static native void nSetCustomProjection(long nativeCamera, double[] inMatrix, double near, double far);
private static native void nSetScaling(long nativeCamera, double[] inScaling);
private static native void nSetModelMatrix(long nativeCamera, float[] in);
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
private static native float nGetNear(long nativeCamera);
private static native float nGetCullingFar(long nativeCamera);
private static native void nGetProjectionMatrix(long nativeCamera, double[] out);
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 nGetViewMatrix(long nativeCamera, float[] out);
private static native void nGetPosition(long nativeCamera, float[] out);

View File

@@ -0,0 +1,477 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament;
import androidx.annotation.NonNull;
import androidx.annotation.Size;
import static com.google.android.filament.Asserts.assertFloat3In;
import static com.google.android.filament.Asserts.assertFloat4In;
/**
* <code>ColorGrading</code> is used to transform (either to modify or correct) the colors of the
* HDR buffer rendered by Filament. Color grading transforms are applied after lighting, and after any
* lens effects (bloom for instance), and include tone mapping.
*
* <h1>Creation, usage and destruction</h1>
*
* A ColorGrading object is created using the ColorGrading::Builder and destroyed by calling
* Engine::destroy(const ColorGrading*). A ColorGrading object is meant to be set on a View.
*
* <pre>
* Engine engine = Engine.create();
*
* ColorGrading colorGrading = ColorGrading.Builder()
* .toneMapping(ColorGrading.ToneMapping.ACES)
* .build(engine);
*
* myView.setColorGrading(colorGrading);
*
* engine.destroy(colorGrading);
* </pre>
*
* <h1>Performance</h1>
*
* Creating a new ColorGrading object may be more expensive than other Filament objects as a
* 3D LUT may need to be generated. The generation of a 3D LUT, if necessary, may happen on
* the CPU.
*
* <h1>Ordering</h1>
*
* The various transforms held by ColorGrading are applied in the following order:
* <ul>
* <li>White balance</li>
* <li>Channel mixer</li>
* <li>Shadows/mid-tones/highlights</li>
* <li>Slope/offset/power (CDL)</li>
* <li>Contrast</li>
* <li>Vibrance</li>
* <li>Saturation</li>
* <li>Curves</li>
* <li>Tone mapping</li>
* </ul>
*
* <h1>Defaults</h1>
*
* Here are the default color grading options:
* <ul>
* <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>,
* highlights <code>{1,1,1,0}</code>, ranges <code>{0,0.333,0.550,1}</code></li>
* <li>Slope/offset/power: slope <code>1.0</code>, offset <code>0.0</code>, and power <code>1.0</code></li>
* <li>Contrast: <code>1.0</code></li>
* <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>
* </ul>
*
* @see View
* @see ToneMapping
*/
public class ColorGrading {
long mNativeObject;
/**
* Color grading quality level.
*/
public enum QualityLevel {
LOW,
MEDIUM,
HIGH,
ULTRA
}
/**
* List of available tone-mapping operators.
*/
public enum ToneMapping {
/** Linear tone mapping (i.e. no tone mapping). */
LINEAR,
/** ACES tone mapping, with a brightness modifier to match Filament's legacy tone mapper. */
ACES_LEGACY,
/** ACES tone mapping. */
ACES,
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
FILMIC,
/** Filmic tone mapping, with more contrast and saturation. */
UCHIMURA,
/** Reinhard luma-based tone mapping. */
REINHARD,
/** Tone mapping used to validate/debug scene exposure. */
DISPLAY_RANGE,
}
ColorGrading(long colorGrading) {
mNativeObject = colorGrading;
}
/**
* Use <code>Builder</code> to construct a <code>ColorGrading</code> object instance.
*/
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
private final BuilderFinalizer mFinalizer;
private final long mNativeBuilder;
/**
* Use <code>Builder</code> to construct a <code>ColorGrading</code> object instance.
*/
public Builder() {
mNativeBuilder = nCreateBuilder();
mFinalizer = new BuilderFinalizer(mNativeBuilder);
}
/**
* Sets the quality level of the color grading. When color grading is implemented using
* a 3D LUT, the quality level may impact the resolution and bit depth of the backing
* 3D texture. For instance, a low quality level will use a 16x16x16 10 bit LUT, a medium
* quality level will use a 32x32x32 10 bit LUT, a high quality will use a 32x32x32 16 bit
* LUT, and a ultra quality will use a 64x64x64 16 bit LUT.
*
* The default quality is {@link QualityLevel#MEDIUM}.
*
* @param qualityLevel The desired quality of the color grading process
*
* @return This Builder, for chaining calls
*/
public Builder quality(QualityLevel qualityLevel) {
nBuilderQuality(mNativeBuilder, qualityLevel.ordinal());
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 ToneMapping#ACES_LEGACY}.
*
* @param toneMapping The tone mapping operator to apply to the HDR color buffer
*
* @return This Builder, for chaining calls
*/
public Builder toneMapping(ToneMapping toneMapping) {
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
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
* overall chromaticity of the image for artistic reasons (to make the image appear
* cooler or warmer for instance).
*
* The while balance adjustment is defined with two values:
* <ul>
* <li>Temperature, to modify the color temperature. This value will modify the colors
* on a blue/yellow axis. Lower values apply a cool color temperature, and higher
* values apply a warm color temperature. The lowest value, -1.0f, is equivalent to
* a temperature of 50,000K. The highest value, 1.0f, is equivalent to a temperature
* of 2,000K.</li>
* <li>Tint, to modify the colors on a green/magenta axis. The lowest value, -1.0f, will
* apply a strong green cast, and the highest value, 1.0f, will apply a strong magenta
* cast.</li>
* </ul>
*
* Both values are expected to be in the range <code>[-1.0..+1.0]</code>. Values outside
* of that range will be clipped to that range.
*
* @param temperature Modification on the blue/yellow axis, as a value between -1.0 and +1.0.
* @param tint Modification on the green/magenta axis, as a value between -1.0 and +1.0.
*
* @return This Builder, for chaining calls
*/
public Builder whiteBalance(float temperature, float tint) {
nBuilderWhiteBalance(mNativeBuilder, temperature, tint);
return this;
}
/**
* The channel mixer adjustment modifies each output color channel using the specified
* mix of the source color channels.
*
* By default each output color channel is set to use 100% of the corresponding source
* channel and 0% of the other channels. For instance, the output red channel is set to
* <code>{1.0, 0.0, 1.0}</code> or 100% red, 0% green and 0% blue.
*
* Each output channel can add or subtract data from the source channel by using values
* in the range <code>[-2.0..+2.0]</code>. Values outside of that range will be clipped
* to that range.
*
* Using the channel mixer adjustment you can for instance create a monochrome output
* by setting all 3 output channels to the same mix. For instance:
* </code>{0.4, 0.4, 0.2}</code> for all 3 output channels(40% red, 40% green and 20% blue).
*
* More complex mixes can be used to create more complex effects. For instance, here is
* a mix that creates a sepia tone effect:
* <ul>
* <li><code>outRed = {0.255, 0.858, 0.087}</code></li>
* <li><code>outGreen = {0.213, 0.715, 0.072}</code></li>
* <li><code>outBlue = {0.170, 0.572, 0.058}</code></li>
* </ul>
*
* @param outRed The mix of source RGB for the output red channel, between -2.0 and +2.0
* @param outGreen The mix of source RGB for the output green channel, between -2.0 and +2.0
* @param outBlue The mix of source RGB for the output blue channel, between -2.0 and +2.0
*
* @return This Builder, for chaining calls
*/
public Builder channelMixer(
@NonNull @Size(min = 3) float[] outRed,
@NonNull @Size(min = 3) float[] outGreen,
@NonNull @Size(min = 3) float[] outBlue) {
assertFloat3In(outRed);
assertFloat3In(outGreen);
assertFloat3In(outBlue);
nBuilderChannelMixer(mNativeBuilder, outRed, outGreen, outBlue);
return this;
}
/**
* Adjusts the colors separately in 3 distinct tonal ranges or zones: shadows, mid-tones,
* and highlights.
*
* The tonal zones are by the ranges parameter: the x and y components define the beginning
* and end of the transition from shadows to mid-tones, and the z and w components define
* the beginning and end of the transition from mid-tones to highlights.
*
* A smooth transition is applied between the zones which means for instance that the
* correction color of the shadows range will partially apply to the mid-tones, and the
* other way around. This ensure smooth visual transitions in the final image.
*
* Each correction color is defined as a linear RGB color and a weight. The weight is a
* value (which may be positive or negative) that is added to the linear RGB color before
* mixing. This can be used to darken or brighten the selected tonal range.
*
* Shadows/mid-tones/highlights adjustment are performed linear space.
*
* @param shadows Linear RGB color (.rgb) and weight (.w) to apply to the shadows
* @param midtones Linear RGB color (.rgb) and weight (.w) to apply to the mid-tones
* @param highlights Linear RGB color (.rgb) and weight (.w) to apply to the highlights
* @param ranges Range of the shadows (x and y), and range of the highlights (z and w)
*
* @return This Builder, for chaining calls
*/
Builder shadowsMidtonesHighlights(
@NonNull @Size(min = 4) float[] shadows,
@NonNull @Size(min = 4) float[] midtones,
@NonNull @Size(min = 4) float[] highlights,
@NonNull @Size(min = 4) float[] ranges) {
assertFloat4In(shadows);
assertFloat4In(midtones);
assertFloat4In(highlights);
assertFloat4In(ranges);
nBuilderShadowsMidtonesHighlights(mNativeBuilder, shadows, midtones, highlights, ranges);
return this;
}
/**
* Applies a slope, offset, and power, as defined by the ASC CDL (American Society of
* Cinematographers Color Decision List) to the image. The CDL can be used to adjust the
* colors of different tonal ranges in the image.
*
* The ASC CDL is similar to the lift/gamma/gain controls found in many color grading tools.
* Lift is equivalent to a combination of offset and slope, gain is equivalent to slope,
* and gamma is equivalent to power.
*
* The slope and power values must be strictly positive. Values less than or equal to 0 will
* be clamped to a small positive value, offset can be any positive or negative value.
*
* Version 1.2 of the ASC CDL adds saturation control, which is here provided as a separate
* API. See the saturation() method for more information.
*
* Slope/offset/power adjustments are performed in log space.
*
* @param slope Multiplier of the input color, must be a strictly positive number
* @param offset Added to the input color, can be a negative or positive number, including 0
* @param power Power exponent of the input color, must be a strictly positive number
*
* @return This Builder, for chaining calls
*/
Builder slopeOffsetPower(
@NonNull @Size(min = 3) float[] slope,
@NonNull @Size(min = 3) float[] offset,
@NonNull @Size(min = 3) float[] power) {
assertFloat3In(slope);
assertFloat3In(offset);
assertFloat3In(power);
nBuilderSlopeOffsetPower(mNativeBuilder, slope, offset, power);
return this;
}
/**
* Adjusts the contrast of the image. Lower values decrease the contrast of the image
* (the tonal range is narrowed), and higher values increase the contrast of the image
* (the tonal range is widened). A value of 1.0 has no effect.
*
* The contrast is defined as a value in the range <code>[0.0...2.0]</code>. Values
* outside of that range will be clipped to that range.
*
* Contrast adjustment is performed in log space.
*
* @param contrast Contrast expansion, between 0.0 and 2.0. 1.0 leaves contrast unaffected
*
* @return This Builder, for chaining calls
*/
public Builder contrast(float contrast) {
nBuilderContrast(mNativeBuilder, contrast);
return this;
}
/**
* Adjusts the saturation of the image based on the input color's saturation level.
* Colors with a high level of saturation are less affected than colors with low saturation
* levels.
*
* Lower vibrance values decrease intensity of the colors present in the image, and
* higher values increase the intensity of the colors in the image. A value of 1.0 has
* no effect.
*
* The vibrance is defined as a value in the range <code>[0.0...2.0]</code>. Values outside
* of that range will be clipped to that range.
*
* Vibrance adjustment is performed in linear space.
*
* @param vibrance Vibrance, between 0.0 and 2.0. 1.0 leaves vibrance unaffected
*
* @return This Builder, for chaining calls
*/
Builder vibrance(float vibrance) {
nBuilderVibrance(mNativeBuilder, vibrance);
return this;
}
/**
* Adjusts the saturation of the image. Lower values decrease intensity of the colors
* present in the image, and higher values increase the intensity of the colors in the
* image. A value of 1.0 has no effect.
*
* The saturation is defined as a value in the range <code>[0.0...2.0]</code>.
* Values outside of that range will be clipped to that range.
*
* Saturation adjustment is performed in linear space.
*
* @param saturation Saturation, between 0.0 and 2.0. 1.0 leaves saturation unaffected
*
* @return This Builder, for chaining calls
*/
public Builder saturation(float saturation) {
nBuilderSaturation(mNativeBuilder, saturation);
return this;
}
/**
* Applies a curve to each RGB channel of the image. Each curve is defined by 3 values:
* a gamma value applied to the shadows only, a mid-point indicating where shadows stop
* and highlights start, and a scale factor for the highlights.
*
* The gamma and mid-point must be strictly positive values. If they are not, they will be
* clamped to a small positive value. The scale can be any negative of positive value.
*
* Curves are applied in linear space.
*
* @param shadowGamma Power value to apply to the shadows, must be strictly positive
* @param midPoint Mid-point defining where shadows stop and highlights start, must be strictly positive
* @param highlightScale Scale factor for the highlights, can be any negative or positive value
*
* @return This Builder, for chaining calls
*/
public Builder curves(
@NonNull @Size(min = 3) float[] shadowGamma,
@NonNull @Size(min = 3) float[] midPoint,
@NonNull @Size(min = 3) float[] highlightScale) {
assertFloat3In(shadowGamma);
assertFloat3In(midPoint);
assertFloat3In(highlightScale);
nBuilderCurves(mNativeBuilder, shadowGamma, midPoint, highlightScale);
return this;
}
/**
* Creates the IndirectLight object and returns a pointer to it.
*
* @param engine The {@link Engine} to associate this <code>IndirectLight</code> with.
*
* @return A newly created <code>IndirectLight</code>
*
* @exception IllegalStateException if a parameter to a builder function was invalid.
*/
@NonNull
public ColorGrading build(@NonNull Engine engine) {
long nativeColorGrading = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
if (nativeColorGrading == 0) throw new IllegalStateException("Couldn't create ColorGrading");
return new ColorGrading(nativeColorGrading);
}
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);
}
}
}
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed ColorGrading");
}
return mNativeObject;
}
void clearNativeObject() {
mNativeObject = 0;
}
private static native long nCreateBuilder();
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 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);
private static native void nBuilderSlopeOffsetPower(long nativeBuilder, float[] slope, float[] offset, float[] power);
private static native void nBuilderContrast(long nativeBuilder, float contrast);
private static native void nBuilderVibrance(long nativeBuilder, float vibrance);
private static native void nBuilderSaturation(long nativeBuilder, float saturation);
private static native void nBuilderCurves(long nativeBuilder, float[] gamma, float[] midPoint, float[] scale);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
}

View File

@@ -17,6 +17,7 @@
package com.google.android.filament;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.filament.proguard.UsedByReflection;
@@ -344,7 +345,7 @@ public class Engine {
* @param swapChain the {@link SwapChain} to destroy
*/
public void destroySwapChain(@NonNull SwapChain swapChain) {
nDestroySwapChain(getNativeObject(), swapChain.getNativeObject());
assertDestroy(nDestroySwapChain(getNativeObject(), swapChain.getNativeObject()));
swapChain.clearNativeObject();
}
@@ -367,7 +368,7 @@ public class Engine {
* @param view the {@link View} to destroy
*/
public void destroyView(@NonNull View view) {
nDestroyView(getNativeObject(), view.getNativeObject());
assertDestroy(nDestroyView(getNativeObject(), view.getNativeObject()));
view.clearNativeObject();
}
@@ -390,7 +391,7 @@ public class Engine {
* @param renderer the {@link Renderer} to destroy
*/
public void destroyRenderer(@NonNull Renderer renderer) {
nDestroyRenderer(getNativeObject(), renderer.getNativeObject());
assertDestroy(nDestroyRenderer(getNativeObject(), renderer.getNativeObject()));
renderer.clearNativeObject();
}
@@ -423,6 +424,20 @@ public class Engine {
return new Camera(nativeCamera);
}
/**
* Returns the Camera component of the given <code>entity</code>.
*
* @param entity An <code>entity</code>.
* @return the Camera component for this entity or null if the entity doesn't have a Camera
* component
*/
@Nullable
public Camera getCameraComponent(@Entity int entity) {
long nativeCamera = nGetCameraComponent(getNativeObject(), entity);
if (nativeCamera == 0) return null;
return new Camera(nativeCamera);
}
/**
* Destroys a {@link Camera} component and frees all its associated resources.
* @param camera the {@link Camera} to destroy
@@ -451,7 +466,7 @@ public class Engine {
* @param scene the {@link Scene} to destroy
*/
public void destroyScene(@NonNull Scene scene) {
nDestroyScene(getNativeObject(), scene.getNativeObject());
assertDestroy(nDestroyScene(getNativeObject(), scene.getNativeObject()));
scene.clearNativeObject();
}
@@ -462,7 +477,7 @@ public class Engine {
* @param stream the {@link Stream} to destroy
*/
public void destroyStream(@NonNull Stream stream) {
nDestroyStream(getNativeObject(), stream.getNativeObject());
assertDestroy(nDestroyStream(getNativeObject(), stream.getNativeObject()));
stream.clearNativeObject();
}
@@ -485,7 +500,7 @@ public class Engine {
* @param fence the {@link Fence} to destroy
*/
public void destroyFence(@NonNull Fence fence) {
nDestroyFence(getNativeObject(), fence.getNativeObject());
assertDestroy(nDestroyFence(getNativeObject(), fence.getNativeObject()));
fence.clearNativeObject();
}
@@ -496,7 +511,7 @@ public class Engine {
* @param indexBuffer the {@link IndexBuffer} to destroy
*/
public void destroyIndexBuffer(@NonNull IndexBuffer indexBuffer) {
nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject());
assertDestroy(nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject()));
indexBuffer.clearNativeObject();
}
@@ -505,7 +520,7 @@ public class Engine {
* @param vertexBuffer the {@link VertexBuffer} to destroy
*/
public void destroyVertexBuffer(@NonNull VertexBuffer vertexBuffer) {
nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject());
assertDestroy(nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject()));
vertexBuffer.clearNativeObject();
}
@@ -514,7 +529,7 @@ public class Engine {
* @param ibl the {@link IndirectLight} to destroy
*/
public void destroyIndirectLight(@NonNull IndirectLight ibl) {
nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject());
assertDestroy(nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject()));
ibl.clearNativeObject();
}
@@ -527,7 +542,7 @@ public class Engine {
* @param material the {@link Material} to destroy
*/
public void destroyMaterial(@NonNull Material material) {
nDestroyMaterial(getNativeObject(), material.getNativeObject());
assertDestroy(nDestroyMaterial(getNativeObject(), material.getNativeObject()));
material.clearNativeObject();
}
@@ -536,7 +551,7 @@ public class Engine {
* @param materialInstance the {@link MaterialInstance} to destroy
*/
public void destroyMaterialInstance(@NonNull MaterialInstance materialInstance) {
nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject());
assertDestroy(nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject()));
materialInstance.clearNativeObject();
}
@@ -545,16 +560,25 @@ public class Engine {
* @param skybox the {@link Skybox} to destroy
*/
public void destroySkybox(@NonNull Skybox skybox) {
nDestroySkybox(getNativeObject(), skybox.getNativeObject());
assertDestroy(nDestroySkybox(getNativeObject(), skybox.getNativeObject()));
skybox.clearNativeObject();
}
/**
* Destroys a {@link ColorGrading} and frees all its associated resources.
* @param colorGrading the {@link ColorGrading} to destroy
*/
public void destroySkybox(@NonNull ColorGrading colorGrading) {
assertDestroy(nDestroyColorGrading(getNativeObject(), colorGrading.getNativeObject()));
colorGrading.clearNativeObject();
}
/**
* Destroys a {@link Texture} and frees all its associated resources.
* @param texture the {@link Texture} to destroy
*/
public void destroyTexture(@NonNull Texture texture) {
nDestroyTexture(getNativeObject(), texture.getNativeObject());
assertDestroy(nDestroyTexture(getNativeObject(), texture.getNativeObject()));
texture.clearNativeObject();
}
@@ -634,33 +658,41 @@ public class Engine {
mNativeObject = 0;
}
private static void assertDestroy(boolean success) {
if (!success) {
throw new IllegalStateException("Object couldn't be destoyed (double destroy()?)");
}
}
private static native long nCreateEngine(long backend, long sharedContext);
private static native void nDestroyEngine(long nativeEngine);
private static native long nGetBackend(long nativeEngine);
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags);
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
private static native void nDestroySwapChain(long nativeEngine, long nativeSwapChain);
private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain);
private static native long nCreateView(long nativeEngine);
private static native void nDestroyView(long nativeEngine, long nativeView);
private static native boolean nDestroyView(long nativeEngine, long nativeView);
private static native long nCreateRenderer(long nativeEngine);
private static native void nDestroyRenderer(long nativeEngine, long nativeRenderer);
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 nGetCameraComponent(long nativeEngine, int entity);
private static native void nDestroyCamera(long nativeEngine, long nativeCamera);
private static native long nCreateScene(long nativeEngine);
private static native void nDestroyScene(long nativeEngine, long nativeScene);
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
private static native long nCreateFence(long nativeEngine);
private static native void nDestroyFence(long nativeEngine, long nativeFence);
private static native void nDestroyStream(long nativeEngine, long nativeStream);
private static native void nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native void nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native void nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native void nDestroyMaterial(long nativeEngine, long nativeMaterial);
private static native void nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
private static native void nDestroySkybox(long nativeEngine, long nativeSkybox);
private static native void nDestroyTexture(long nativeEngine, long nativeTexture);
private static native void nDestroyRenderTarget(long nativeEngine, long nativeTarget);
private static native boolean nDestroyFence(long nativeEngine, long nativeFence);
private static native boolean nDestroyStream(long nativeEngine, long nativeStream);
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
private static native boolean nDestroySkybox(long nativeEngine, long nativeSkybox);
private static native boolean nDestroyColorGrading(long nativeEngine, long nativeColorGrading);
private static native boolean nDestroyTexture(long nativeEngine, long nativeTexture);
private static native boolean nDestroyRenderTarget(long nativeEngine, long nativeTarget);
private static native void nDestroyEntity(long nativeEngine, int entity);
private static native void nFlushAndWait(long nativeEngine);
private static native long nGetTransformManager(long nativeEngine);

View File

@@ -86,7 +86,11 @@ import com.google.android.filament.proguard.UsedByReflection;
public class IndirectLight {
long mNativeObject;
public IndirectLight(long indirectLight) {
public IndirectLight(Engine engine, long indirectLight) {
mNativeObject = indirectLight;
}
IndirectLight(long indirectLight) {
mNativeObject = indirectLight;
}
@@ -475,6 +479,18 @@ public class IndirectLight {
return colorIntensity;
}
@Nullable
public Texture getReflectionsTexture() {
long nativeTexture = nGetReflectionsTexture(getNativeObject());
return nativeTexture == 0 ? null : new Texture(nativeTexture);
}
@Nullable
public Texture getIrradianceTexture() {
long nativeTexture = nGetIrradianceTexture(getNativeObject());
return nativeTexture == 0 ? null : new Texture(nativeTexture);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IndirectLight");
@@ -504,6 +520,9 @@ public class IndirectLight {
private static native void nGetDirectionEstimate(long nativeIndirectLight, float[] outDirection);
private static native void nGetColorEstimate(long nativeIndirectLight, float[] outColor, float x, float y, float z);
private static native long nGetReflectionsTexture(long nativeIndirectLight);
private static native long nGetIrradianceTexture(long nativeIndirectLight);
private static native void nGetDirectionEstimateStatic(float[] sh, float[] direction);
private static native void nGetColorEstimateStatic(float[] colorIntensity, float[] sh, float x, float y, float z);
}

View File

@@ -230,8 +230,10 @@ public class Material {
MAT3,
MAT4,
SAMPLER_2D,
SAMPLER_2D_ARRAY,
SAMPLER_CUBEMAP,
SAMPLER_EXTERNAL
SAMPLER_EXTERNAL,
SAMPLER_3D
}
public enum Precision {
@@ -326,6 +328,21 @@ public class Material {
return new MaterialInstance(this, nativeInstance);
}
/**
* Creates a new instance of this material with a specified name. Material instances should be
* freed using {@link Engine#destroyMaterialInstance(MaterialInstance)}.
*
* @param name arbitrary label to associate with the given material instance
*
* @return the new instance
*/
@NonNull
public MaterialInstance createInstance(@NonNull String name) {
long nativeInstance = nCreateInstanceWithName(getNativeObject(), name);
if (nativeInstance == 0) throw new IllegalStateException("Couldn't create MaterialInstance");
return new MaterialInstance(this, nativeInstance);
}
/** Returns the material's default instance. */
@NonNull
public MaterialInstance getDefaultInstance() {
@@ -422,7 +439,7 @@ public class Material {
}
/**
* Indicates whether this material will write to the color buffer.
* Indicates whether instances of this material will, by default, write to the color buffer.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorwrite">
@@ -433,7 +450,7 @@ public class Material {
}
/**
* Indicates whether this material will write to the depth buffer.
* Indicates whether instances of this material will, by default, write to the depth buffer.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthwrite">
@@ -444,7 +461,7 @@ public class Material {
}
/**
* Indicates whether this material will use depth testing.
* Indicates whether instances of this material will, by default, use depth testing.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthculling">
@@ -879,6 +896,7 @@ public class Material {
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);
private static native String nGetName(long nativeMaterial);

View File

@@ -22,6 +22,7 @@ import androidx.annotation.Size;
public class MaterialInstance {
private Material mMaterial;
private String mName;
private long mNativeObject;
private long mNativeMaterial;
@@ -48,14 +49,19 @@ public class MaterialInstance {
MAT4
}
public MaterialInstance(Engine engine, long nativeMaterialInstance) {
mNativeObject = nativeMaterialInstance;
mNativeMaterial = nGetMaterial(mNativeObject);
}
MaterialInstance(@NonNull Material material, long nativeMaterialInstance) {
mMaterial = material;
mNativeObject = nativeMaterialInstance;
}
MaterialInstance(long nativeMaterial, long nativeMaterialInstance) {
mNativeMaterial = nativeMaterial;
MaterialInstance(long nativeMaterialInstance) {
mNativeObject = nativeMaterialInstance;
mNativeMaterial = nGetMaterial(mNativeObject);
}
/** @return the {@link Material} associated with this instance */
@@ -67,6 +73,15 @@ public class MaterialInstance {
return mMaterial;
}
/** @return the name associated with this instance */
@NonNull
public String getName() {
if (mName == null) {
mName = nGetName(getNativeObject());
}
return mName;
}
/**
* Sets the value of a bool parameter.
*
@@ -430,6 +445,39 @@ public class MaterialInstance {
nSetCullingMode(getNativeObject(), mode.ordinal());
}
/**
* Overrides the default color-buffer write state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorWrite">
* Rasterization: colorWrite</a>
*/
void setColorWrite(boolean enable) {
nSetColorWrite(getNativeObject(), enable);
}
/**
* Overrides the default depth-buffer write state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthWrite">
* Rasterization: depthWrite</a>
*/
void setDepthWrite(boolean enable) {
nSetDepthWrite(getNativeObject(), enable);
}
/**
* Overrides the default depth testing state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthCulling">
* Rasterization: depthCulling</a>
*/
void setDepthCulling(boolean enable) {
nSetDepthCulling(getNativeObject(), enable);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
@@ -499,6 +547,11 @@ public class MaterialInstance {
float threshold);
private static native void nSetDoubleSided(long nativeMaterialInstance, boolean doubleSided);
private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
private static native void nSetColorWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable);
private static native String nGetName(long nativeMaterialInstance);
private static native long nGetMaterial(long nativeMaterialInstance);
}

View File

@@ -206,11 +206,11 @@ public class RenderTarget {
}
private static native long nCreateBuilder();
private static native long nDestroyBuilder(long nativeBuilder);
private static native long nBuilderTexture(long nativeBuilder, int attachment, long nativeTexture);
private static native long nBuilderMipLevel(long nativeBuilder, int attachment, int level);
private static native long nBuilderFace(long nativeBuilder, int attachment, int face);
private static native long nBuilderLayer(long nativeBuilder, int attachment, int layer);
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderTexture(long nativeBuilder, int attachment, long nativeTexture);
private static native void nBuilderMipLevel(long nativeBuilder, int attachment, int level);
private static native void nBuilderFace(long nativeBuilder, int attachment, int face);
private static native void nBuilderLayer(long nativeBuilder, int attachment, int layer);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetMipLevel(long nativeRenderTarget, int attachment);

View File

@@ -284,6 +284,17 @@ public class RenderableManager {
return this;
}
/**
* Controls if this renderable uses screen-space contact shadows. This is more
* expensive but can improve the quality of shadows, especially in large scenes.
* (off by default).
*/
@NonNull
public Builder screenSpaceContactShadows(boolean enabled) {
nBuilderScreenSpaceContactShadows(mNativeBuilder, enabled);
return this;
}
@NonNull
public Builder skinning(@IntRange(from = 0, to = 255) int boneCount) {
nBuilderSkinning(mNativeBuilder, boneCount);
@@ -442,6 +453,15 @@ public class RenderableManager {
nSetPriority(mNativeObject, i, priority);
}
/**
* Changes whether or not frustum culling is on.
*
* @see Builder#culling
*/
public void setCulling(@EntityInstance int i, boolean enabled) {
nSetCulling(mNativeObject, i, enabled);
}
/**
* Changes whether or not the renderable casts shadows.
*
@@ -460,6 +480,16 @@ public class RenderableManager {
nSetReceiveShadows(mNativeObject, i, enabled);
}
/**
* Changes whether or not the renderable can use screen-space contact shadows.
*
* @see Builder#screenSpaceContactShadows
*/
public void setScreenSpaceContactShadows(@EntityInstance int i, boolean enabled) {
nSetScreenSpaceContactShadows(mNativeObject, i, enabled);
}
/**
* Checks if the renderable can cast shadows.
*
@@ -523,8 +553,7 @@ public class RenderableManager {
public @NonNull MaterialInstance getMaterialInstanceAt(@EntityInstance int i,
@IntRange(from = 0) int primitiveIndex) {
long nativeMatInstance = nGetMaterialInstanceAt(mNativeObject, i, primitiveIndex);
long nativeMaterial = nGetMaterialAt(mNativeObject, i, primitiveIndex);
return new MaterialInstance(nativeMaterial, nativeMatInstance);
return new MaterialInstance(nativeMatInstance);
}
/**
@@ -614,6 +643,7 @@ public class RenderableManager {
private static native void nBuilderCulling(long nativeBuilder, boolean enabled);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enabled);
private static native void nBuilderReceiveShadows(long nativeBuilder, boolean enabled);
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 nBuilderMorphing(long nativeBuilder, boolean enabled);
@@ -624,8 +654,10 @@ public class RenderableManager {
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
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);
private static native boolean nIsShadowCaster(long nativeRenderableManager, int i);
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);

View File

@@ -44,6 +44,100 @@ import java.nio.ReadOnlyBufferException;
public class Renderer {
private final Engine mEngine;
private long mNativeObject;
private DisplayInfo mDisplayInfo;
private FrameRateOptions mFrameRateOptions;
private ClearOptions mClearOptions;
/**
* Information about the display this renderer is associated to
*/
public static class DisplayInfo {
/**
* Refresh rate of the display in Hz. Set to 0 for offscreen or turn off frame-pacing.
* On Android you can use {@link android.view.Display#getRefreshRate()}.
*/
public float refreshRate = 60.0f;
/**
* How far in advance a buffer must be queued for presentation at a given time in ns
* On Android you can use {@link android.view.Display#getPresentationDeadlineNanos()}.
*/
public long presentationDeadlineNanos = 0;
/**
* Offset by which vsyncSteadyClockTimeNano provided in beginFrame() is offset in ns
* On Android you can use {@link android.view.Display#getAppVsyncOffsetNanos()}.
*/
public long vsyncOffsetNanos = 0;
};
/**
* Use FrameRateOptions to set the desired frame rate and control how quickly the system
* reacts to GPU load changes.
*
* interval: desired frame interval in multiple of the refresh period, set in DisplayInfo
* (as 1 / DisplayInfo.refreshRate)
*
* The parameters below are relevant when some Views are using dynamic resolution scaling:
*
* headRoomRatio: additional headroom for the GPU as a ratio of the targetFrameTime.
* Useful for taking into account constant costs like post-processing or
* GPU drivers on different platforms.
* history: History size. higher values, tend to filter more (clamped to 30)
* scaleRate: rate at which the gpu load is adjusted to reach the target frame rate
* This value can be computed as 1 / N, where N is the number of frames
* needed to reach 64% of the target scale factor.
* Higher values make the dynamic resolution react faster.
*
* @see View.DynamicResolutionOptions
* @see Renderer.DisplayInfo
*
*/
public static class FrameRateOptions {
/**
* Desired frame interval in unit of 1 / DisplayInfo.refreshRate.
*/
public float interval = 1.0f / 60.0f;
/**
* Additional headroom for the GPU as a ratio of the targetFrameTime.
*/
public float headRoomRatio = 0.0f;
/**
* Rate at which the scale will change to reach the target frame rate.
*/
public float scaleRate = 0.125f;
/**
* History size. higher values, tend to filter more (clamped to 30).
*/
public int history = 9;
}
/**
* ClearOptions are used at the beginning of a frame to clear or retain the SwapChain content.
*/
public static class ClearOptions {
/**
* Color to use to clear the SwapChain
*/
@NonNull
public float[] clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
/**
* Whether the SwapChain should be cleared using the clearColor. Use this if translucent
* View will be drawn, for instance.
*/
public boolean clear = false;
/**
* Whether the SwapChain content should be discarded. clear implies discard. Set this
* to false (along with clear to false as well) if the SwapChain already has content that
* needs to be preserved
*/
public boolean discard = true;
};
/**
* Indicates that the <code>dstSwapChain</code> passed into {@link #copyFrame} should be
@@ -75,6 +169,74 @@ public class Renderer {
mNativeObject = nativeRenderer;
}
/**
* Information about the display this Renderer is associated to. This information is needed
* to accurately compute dynamic-resolution scaling and for frame-pacing.
*/
public void setDisplayInfo(@NonNull DisplayInfo info) {
mDisplayInfo = info;
nSetDisplayInfo(getNativeObject(),
info.refreshRate, info.presentationDeadlineNanos, info.vsyncOffsetNanos);
}
/**
* Returns the DisplayInfo object set in {@link #setDisplayInfo} or a new instance otherwise.
* @return a DisplayInfo instance
*/
@NonNull
public DisplayInfo getDisplayInfo() {
if (mDisplayInfo == null) {
mDisplayInfo = new DisplayInfo();
}
return mDisplayInfo;
}
/**
* Set options controlling the desired frame-rate.
*/
public void setFrameRateOptions(@NonNull FrameRateOptions options) {
mFrameRateOptions = options;
nSetFrameRateOptions(getNativeObject(),
options.interval, options.headRoomRatio, options.scaleRate, options.history);
}
/**
* Returns the FrameRateOptions object set in {@link #setFrameRateOptions} or a new instance
* otherwise.
* @return a FrameRateOptions instance
*/
@NonNull
public FrameRateOptions getFrameRateOptions() {
if (mFrameRateOptions == null) {
mFrameRateOptions = new FrameRateOptions();
}
return mFrameRateOptions;
}
/**
* Set ClearOptions which are used at the beginning of a frame to clear or retain the
* SwapChain content.
*/
public void setClearOptions(@NonNull ClearOptions options) {
mClearOptions = options;
nSetClearOptions(getNativeObject(),
options.clearColor[0], options.clearColor[1], options.clearColor[2], options.clearColor[3],
options.clear, options.discard);
}
/**
* Returns the ClearOptions object set in {@link #setClearOptions} or a new instance
* otherwise.
* @return a ClearOptions instance
*/
@NonNull
public ClearOptions getClearOptions() {
if (mClearOptions == null) {
mClearOptions = new ClearOptions();
}
return mClearOptions;
}
/**
* Gets the {@link Engine} that created this <code>Renderer</code>.
*
@@ -100,16 +262,24 @@ public class Renderer {
* <p>All calls to render() must happen <b>after</b> beginFrame().</p>
*
* @param swapChain the {@link SwapChain} instance to use
* @param frameTimeNanos The time in nanoseconds when the frame started being rendered,
* in the {@link System#nanoTime()} timebase. Divide this value by 1000000 to
* convert it to the {@link android.os.SystemClock#uptimeMillis()}
* time base. This typically comes from
* {@link android.view.Choreographer.FrameCallback}.
*
* @return <code>false</code> if the current frame must be skipped<br>
* When skipping a frame, the whole frame is canceled, and {@link #endFrame} must not
* be called.
* @return <code>true</code>: the current frame must be drawn, and {@link #endFrame} must be called<br>
* <code>false</code>: the current frame should be skipped, when skipping a frame,
* the whole frame is canceled, and {@link #endFrame} must not
* be called. However, the user can choose to proceed as though <code>true</code> was
* returned and produce a frame anyways, by making calls to {@link #render(View)},
* in which case {@link #endFrame} must be called.
*
* @see #endFrame
* @see #render
*/
public boolean beginFrame(@NonNull SwapChain swapChain) {
return nBeginFrame(getNativeObject(), swapChain.getNativeObject());
public boolean beginFrame(@NonNull SwapChain swapChain, long frameTimeNanos) {
return nBeginFrame(getNativeObject(), swapChain.getNativeObject(), frameTimeNanos);
}
/**
@@ -462,7 +632,7 @@ public class Renderer {
mNativeObject = 0;
}
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain);
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
private static native void nEndFrame(long nativeRenderer);
private static native void nRender(long nativeRenderer, long nativeView);
private static native void nCopyFrame(long nativeRenderer, long nativeDstSwapChain,
@@ -482,4 +652,10 @@ public class Renderer {
Object handler, Runnable callback);
private static native double nGetUserTime(long nativeRenderer);
private static native void nResetUserTime(long nativeRenderer);
private static native void nSetDisplayInfo(long nativeRenderer,
float refreshRate, long presentationDeadlineNanos, long vsyncOffsetNanos);
private static native void nSetFrameRateOptions(long nativeRenderer,
float interval, float headRoomRatio, float scaleRate, int history);
private static native void nSetClearOptions(long nativeRenderer,
float r, float g, float b, float a, boolean clear, boolean discard);
}

View File

@@ -132,6 +132,18 @@ public class Scene {
removeEntity(entity);
}
/**
* Removes a list of entities from the <code>Scene</code>.
*
* This is equivalent to calling remove in a loop.
* If any of the specified entities do not exist in the scene, they are skipped.
*
* @param entities array containing entities to remove from the <code>Scene</code>.
*/
public void removeEntities(@Entity int[] entities) {
nRemoveEntities(getNativeObject(), entities);
}
/**
* Returns the number of {@link RenderableManager} components in the <code>Scene</code>.
*
@@ -166,6 +178,7 @@ public class Scene {
private static native void nAddEntity(long nativeScene, int entity);
private static native void nAddEntities(long nativeScene, int[] entities);
private static native void nRemove(long nativeScene, int entity);
private static native void nRemoveEntities(long nativeScene, int[] entities);
private static native int nGetRenderableCount(long nativeScene);
private static native int nGetLightCount(long nativeScene);
}

View File

@@ -18,6 +18,10 @@ package com.google.android.filament;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import static com.google.android.filament.Colors.LinearColor;
import com.google.android.filament.proguard.UsedByReflection;
@@ -49,10 +53,13 @@ import com.google.android.filament.proguard.UsedByReflection;
public class Skybox {
private long mNativeObject;
public Skybox(long nativeSkybox) {
public Skybox(Engine engine, long nativeSkybox) {
mNativeObject = nativeSkybox;
}
Skybox(long nativeSkybox) {
mNativeObject = nativeSkybox;
}
/**
* Use <code>Builder</code> to construct a <code>Skybox</code> object instance.
@@ -126,6 +133,33 @@ public class Skybox {
return this;
}
/**
* Sets the <code>Skybox</code> to a constant color. Default is opaque black.
*
* Ignored if an environment is set.
*
* @return This Builder, for chaining calls.
*/
@NonNull
public Builder color(@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) {
nBuilderColor(mNativeBuilder, r, g, b, a);
return this;
}
/**
* Sets the <code>Skybox</code> to a constant color. Default is opaque black.
*
* Ignored if an environment is set.
*
* @param color an array of 4 floats
* @return This Builder, for chaining calls.
*/
@NonNull
public Builder color(@NonNull @Size(min = 4) float[] color) {
nBuilderColor(mNativeBuilder, color[0], color[1], color[2], color[3]);
return this;
}
/**
* Creates a <code>Skybox</code> object
*
@@ -159,6 +193,25 @@ public class Skybox {
}
}
/**
* Mutates the <code>Skybox</code>'s constant color.
*
* Ignored if an environment is set.
*/
public void setColor(@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) {
nSetColor(getNativeObject(), r, g, b, a);
}
/**
* Mutates the <code>Skybox</code>'s constant color.
* Ignored if an environment is set.
*
* @param color an array of 4 floats
*/
public void setColor(@NonNull @Size(min = 4) float[] color) {
nSetColor(getNativeObject(), color[0], color[1], color[2], color[3]);
}
/**
* Sets bits in a visibility mask. By default, this is <code>0x1</code>.
* <p>This provides a simple mechanism for hiding or showing this <code>Skybox</code> in a
@@ -188,6 +241,15 @@ public class Skybox {
*/
public float getIntensity() { return nGetIntensity(getNativeObject()); }
/**
* @return the associated texture, or null if it does not exist
*/
@Nullable
public Texture getTexture() {
long nativeTexture = nGetTexture(getNativeObject());
return nativeTexture == 0 ? null : new Texture(nativeTexture);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Skybox");
@@ -204,8 +266,11 @@ public class Skybox {
private static native void nBuilderEnvironment(long nativeSkyboxBuilder, long nativeTexture);
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a);
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
private static native int nGetLayerMask(long nativeSkybox);
private static native float nGetIntensity(long nativeSkybox);
private static native void nSetColor(long nativeSkybox, float r, float g, float b, float a);
private static native long nGetTexture(long nativeSkybox);
}

View File

@@ -0,0 +1,225 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import java.nio.Buffer;
/**
* Helper used to populate <code>TANGENTS</code> buffers.
*/
public class SurfaceOrientation {
private long mNativeObject;
private SurfaceOrientation(long nativeSurfaceOrientation) {
mNativeObject = nativeSurfaceOrientation;
}
/**
* Constructs an immutable surface orientation helper.
*
* At a minimum, clients must supply a vertex count.
* They can supply data in any of the following combinations:
*
* <ol>
* <li>normals only (not recommended)</li>
* <li>normals + tangents (sign of W determines bitangent orientation)</li>
* <li>normals + uvs + positions + indices</li>
* <li>positions + indices</li>
* </ol>
*
* Additionally, the client-side data has the following type constraints:
*
* <ol>
* <li>Normals must be float3</li>
* <li>Tangents must be float4</li>
* <li>UVs must be float2</li>
* <li>Positions must be float3</li>
* <li>Triangles must be uint3 or ushort3</li>
* </ol>
*/
public static class Builder {
private int mVertexCount;
private int mTriangleCount;
private Buffer mNormals;
private int mNormalsStride;
private Buffer mTangents;
private int mTangentsStride;
private Buffer mTexCoords;
private int mTexCoordsStride;
private Buffer mPositions;
private int mPositionsStride;
private Buffer mTrianglesUint16;
private Buffer mTrianglesUint32;
@NonNull
public Builder vertexCount(@IntRange(from = 1) int vertexCount) {
mVertexCount = vertexCount;
return this;
}
@NonNull
public Builder normals(@NonNull Buffer buffer) {
mNormals = buffer;
mNormalsStride = 0;
return this;
}
@NonNull
public Builder tangents(@NonNull Buffer buffer) {
mTangents = buffer;
mTangentsStride = 0;
return this;
}
@NonNull
public Builder uvs(@NonNull Buffer buffer) {
mTexCoords = buffer;
mTexCoordsStride = 0;
return this;
}
@NonNull
public Builder positions(@NonNull Buffer buffer) {
mPositions = buffer;
mPositionsStride = 0;
return this;
}
@NonNull
public Builder triangleCount(int triangleCount) {
mTriangleCount = triangleCount;
return this;
}
@NonNull
public Builder triangles_uint16(@NonNull Buffer buffer) {
mTrianglesUint16 = buffer;
return this;
}
@NonNull
public Builder triangles_uint32(@NonNull Buffer buffer) {
mTrianglesUint32 = buffer;
return this;
}
/**
* Consumes the input data, produces quaternions, and destroys the native builder.
*/
@NonNull
public SurfaceOrientation build() {
// The C++ Builder API specifies that the pointers are consumed during build(), not
// during the individual daisy-chain methods. Therefore we need to retain the Java
// buffers until this point in the code.
long builder = nCreateBuilder();
nBuilderVertexCount(builder, mVertexCount);
nBuilderTriangleCount(builder, mTriangleCount);
if (mNormals != null) {
nBuilderNormals(builder, mNormals, mNormals.remaining(), mNormalsStride);
}
if (mTangents != null) {
nBuilderTangents(builder, mTangents, mTangents.remaining(), mTangentsStride);
}
if (mTexCoords != null) {
nBuilderUVs(builder, mTexCoords, mTexCoords.remaining(), mTexCoordsStride);
}
if (mPositions != null) {
nBuilderPositions(builder, mPositions, mPositions.remaining(), mPositionsStride);
}
if (mTrianglesUint16 != null) {
nBuilderTriangles16(builder, mTrianglesUint16, mTrianglesUint16.remaining());
}
if (mTrianglesUint32 != null) {
nBuilderTriangles32(builder, mTrianglesUint32, mTrianglesUint32.remaining());
}
long nativeSurfaceOrientation = nBuilderBuild(builder);
nDestroyBuilder(builder);
if (nativeSurfaceOrientation == 0) {
throw new IllegalStateException("Could not create SurfaceOrientation");
}
return new SurfaceOrientation(nativeSurfaceOrientation);
}
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SurfaceOrientation");
}
return mNativeObject;
}
@IntRange(from = 0)
public int getVertexCount() {
return nGetVertexCount(mNativeObject);
}
@NonNull
public void getQuatsAsFloat(@NonNull Buffer buffer) {
nGetQuatsAsFloat(mNativeObject, buffer, buffer.remaining());
}
@NonNull
public void getQuatsAsHalf(@NonNull Buffer buffer) {
nGetQuatsAsHalf(mNativeObject, buffer, buffer.remaining());
}
@NonNull
public void getQuatsAsShort(@NonNull Buffer buffer) {
nGetQuatsAsShort(mNativeObject, buffer, buffer.remaining());
}
public void destroy() {
nDestroy(mNativeObject);
mNativeObject = 0;
}
private static native long nCreateBuilder();
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
private static native void nBuilderNormals(long nativeBuilder, Buffer buffer, int remaining, int stride);
private static native void nBuilderTangents(long nativeBuilder, Buffer buffer, int remaining, int stride);
private static native void nBuilderUVs(long nativeBuilder, Buffer buffer, int remaining, int stride);
private static native void nBuilderPositions(long nativeBuilder, Buffer buffer, int remaining, int stride);
private static native void nBuilderTriangleCount(long nativeBuilder, int triangleCount);
private static native void nBuilderTriangles16(long nativeBuilder, Buffer buffer, int remaining);
private static native void nBuilderTriangles32(long nativeBuilder, Buffer buffer, int remaining);
private static native long nBuilderBuild(long nativeBuilder);
private static native int nGetVertexCount(long nativeSurfaceOrientation);
private static native void nGetQuatsAsFloat(long nativeSurfaceOrientation, Buffer buffer, int remaining);
private static native void nGetQuatsAsHalf(long nativeSurfaceOrientation, Buffer buffer, int remaining);
private static native void nGetQuatsAsShort(long nativeSurfaceOrientation, Buffer buffer, int remaining);
private static native void nDestroy(long nativeSurfaceOrientation);
}

View File

@@ -73,7 +73,11 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
public class Texture {
private long mNativeObject;
public Texture(long nativeTexture) {
Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
public Texture(Engine engine, long nativeTexture) {
mNativeObject = nativeTexture;
}
@@ -83,10 +87,14 @@ public class Texture {
public enum Sampler {
/** 2D sampler */
SAMPLER_2D,
/** 2D array sampler */
SAMPLER_2D_ARRAY,
/** Cubemap sampler */
SAMPLER_CUBEMAP,
/** External texture sampler */
SAMPLER_EXTERNAL
SAMPLER_EXTERNAL,
/** 3D sampler */
SAMPLER_3D,
}
/**
@@ -271,26 +279,40 @@ public class Texture {
* Pixel data type
*/
public enum Type {
/** unsigned byte, 8-bits */
/** unsigned byte, 8-bit */
UBYTE,
/** signed byte, 8-bits */
/** signed byte, 8-bit */
BYTE,
/** unsigned short, 16-bits */
/** unsigned short, 16-bits*/
USHORT,
/** signed short, 16-bits */
/** signed short, 16-bit */
SHORT,
/** unsigned int, 32-bits */
/** unsigned int, 32-bit */
UINT,
/** signed int, 32-bits */
/** signed int, 32-bit */
INT,
/** half-float, 16-bits float with 10 bits mantissa */
/** half-float, 16-bit float with 10 bits mantissa */
HALF,
/** float, 32-bits float, with 24 bits mantissa */
/** float, 32-bit float, with 24 bits mantissa */
FLOAT,
/** a compessed type */
/** a compressed type */
COMPRESSED,
/** unsigned 5.6 (5.5 for blue) float packed in 32-bits */
UINT_10F_11F_11F_REV
/** unsigned 5.6 (5.5 for blue) float packed in a 32-bit integer. */
UINT_10F_11F_11F_REV,
/** unsigned 5/6 bit integers packed in a 16-bit short. */
USHORT_565,
}
/**
* Texture swizzling channels
*/
public enum Swizzle {
SUBSTITUTE_ZERO, //!< specified component is substituted with 0
SUBSTITUTE_ONE, //!< specified component is substituted with 1
CHANNEL_0, //!< specified component taken from channel 0
CHANNEL_1, //!< specified component taken from channel 1
CHANNEL_2, //!< specified component taken from channel 2
CHANNEL_3 //!< specified component taken from channel 3
}
/**
@@ -341,7 +363,6 @@ public class Texture {
*/
@Nullable public Runnable callback;
/**
* Creates a <code>PixelBufferDescriptor</code>
*
@@ -581,8 +602,12 @@ public class Texture {
}
/**
* Specifies the texture's number of layers. This creates a 3D texture.
* @param depth texture number of layer, must be at least 1. Default is 1.
* Specifies the texture's number of layers. Values greater than 1 create a 3D texture.
*
* <p>This <code>Texture</code> instance must use
* {@link Sampler#SAMPLER_2D_ARRAY SAMPLER_2D_ARRAY} or it has no effect.</p>
*
* @param depth texture number of layers. Default is 1.
* @return This Builder, for chaining calls.
*/
@NonNull
@@ -638,6 +663,21 @@ public class Texture {
return this;
}
/**
* Specifies how a texture's channels map to color components
*
* @param r texture channel for red component
* @param g texture channel for green component
* @param b texture channel for blue component
* @param a texture channel for alpha component
* @return This Builder, for chaining calls.
*/
@NonNull
public Builder swizzle(@NonNull Swizzle r, @NonNull Swizzle g, @NonNull Swizzle b, @NonNull Swizzle a) {
nBuilderSwizzle(mNativeBuilder, r.ordinal(), g.ordinal(), b.ordinal(), a.ordinal());
return this;
}
/**
* Creates a new <code>Texture</code> instance.
* @param engine The {@link Engine} to associate this <code>Texture</code> with.
@@ -685,6 +725,8 @@ public class Texture {
public static final int UPLOADABLE = 0x8;
/** The texture can be read from a shader or blitted from */
public static final int SAMPLEABLE = 0x10;
/** Texture can be used as a subpass input */
public static final int SUBPASS_INPUT = 0x20;
/** by default textures are <code>UPLOADABLE</code> and <code>SAMPLEABLE</code>*/
public static final int DEFAULT = UPLOADABLE | SAMPLEABLE;
}
@@ -777,7 +819,7 @@ public class Texture {
/**
* <code>setImage</code> is used to modify a sub-region of the texure from a CPU-buffer.
* <code>setImage</code> is used to modify a sub-region of the texture from a CPU-buffer.
*
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D SAMPLER_2D} or
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}. If the later is specified
@@ -828,6 +870,58 @@ public class Texture {
}
}
/**
* <code>setImage</code> is used to modify a sub-region of the 3D texture or 2D texture array
* from a CPU-buffer.
*
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D_ARRAY SAMPLER_2D_ARRAY} or
* {@link Sampler#SAMPLER_3D SAMPLER_3D}.</p>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
* @param xoffset x-offset in texel of the region to modify
* @param yoffset y-offset in texel of the region to modify
* @param yoffset z-offset in texel of the region to modify
* @param width width in texel of the region to modify
* @param height height in texel of the region to modify
* @param depth depth in texel or index of the region to modify
* @param buffer Client-side buffer containing the image to set.
* <code>buffer</code>'s {@link Format format} must match that
* of {@link #getFormat()}
*
* @exception BufferOverflowException if the specified parameters would result in reading
* outside of <code>buffer</code>.
*
* @see Builder#sampler
* @see PixelBufferDescriptor
*/
public void setImage(@NonNull Engine engine,
@IntRange(from = 0) int level,
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset, @IntRange(from = 0) int zoffset,
@IntRange(from = 0) int width, @IntRange(from = 0) int height, @IntRange(from = 0) int depth,
@NonNull PixelBufferDescriptor buffer) {
int result;
if (buffer.type == COMPRESSED) {
result = nSetImage3DCompressed(getNativeObject(), engine.getNativeObject(), level,
xoffset, yoffset, zoffset, width, height, depth,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.compressedSizeInBytes, buffer.compressedFormat.ordinal(),
buffer.handler, buffer.callback);
} else {
result = nSetImage3D(getNativeObject(), engine.getNativeObject(), level,
xoffset, yoffset, zoffset, width, height, depth,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.stride, buffer.format.ordinal(),
buffer.handler, buffer.callback);
}
if (result < 0) {
throw new BufferOverflowException();
}
}
/**
* <code>setImage</code> is used to specify all six images of a cubemap level and
* follows exactly the OpenGL conventions
@@ -1054,6 +1148,7 @@ public class Texture {
private static native void nBuilderSampler(long nativeBuilder, int sampler);
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 long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetWidth(long nativeTexture, int level);
@@ -1075,6 +1170,18 @@ public class Texture {
int compressedSizeInBytes, int compressedFormat,
Object handler, Runnable callback);
private static native int nSetImage3D(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
int stride, int format,
Object handler, Runnable callback);
private static native int nSetImage3DCompressed(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
int compressedSizeInBytes, int compressedFormat,
Object handler, Runnable callback);
private static native int nSetImageCubemap(long nativeTexture, long nativeEngine,
int level, Buffer storage, int remaining, int left, int bottom, int type,
int alignment, int stride, int format,

View File

@@ -416,6 +416,9 @@ public class VertexBuffer {
* 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) {

View File

@@ -21,6 +21,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import java.util.EnumSet;
import static com.google.android.filament.Asserts.assertFloat3In;
import static com.google.android.filament.Asserts.assertFloat4In;
import static com.google.android.filament.Colors.LinearColor;
/**
@@ -62,9 +66,30 @@ public class View {
private Viewport mViewport = new Viewport(0, 0, 0, 0);
private DynamicResolutionOptions mDynamicResolution;
private RenderQuality mRenderQuality;
private DepthPrepass mDepthPrepass = DepthPrepass.DEFAULT;
private AmbientOcclusionOptions mAmbientOcclusionOptions;
private BloomOptions mBloomOptions;
private FogOptions mFogOptions;
private RenderTarget mRenderTarget;
private BlendMode mBlendMode;
private DepthOfFieldOptions mDepthOfFieldOptions;
private VignetteOptions mVignetteOptions;
private ColorGrading mColorGrading;
private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions;
/**
* Generic quality level.
*/
public enum QualityLevel {
LOW,
MEDIUM,
HIGH,
ULTRA
}
public enum BlendMode {
OPAQUE,
TRANSLUCENT
}
/**
* Dynamic resolution can be used to either reach a desired target frame rate by lowering the
@@ -94,21 +119,6 @@ public class View {
*/
public boolean homogeneousScaling = false;
/**
* Desired frame time in milliseconds.
*/
public float targetFrameTimeMilli = 1000.0f / 60.0f;
/**
* Additional headroom for the GPU as a ratio of the targetFrameTime.
*/
public float headRoomRatio = 0.0f;
/**
* Rate at which the scale will change to reach the target frame rate.
*/
public float scaleRate = 0.125f;
/**
* The minimum scale in X and Y this View should use.
*/
@@ -120,14 +130,16 @@ public class View {
public float maxScale = 1.0f;
/**
* History size. higher values, tend to filter more (clamped to 30).
* Upscaling quality. LOW: 1 bilinear tap, MEDIUM: 4 bilinear taps, HIGH: 9 bilinear taps.
* If minScale needs to be very low, it might help to use MEDIUM or HIGH here.
* The default upscaling quality is set to LOW.
*/
public int history = 9;
@NonNull
public QualityLevel quality = QualityLevel.LOW;
}
/**
* Options for Ambient Occlusion
* @see #setAmbientOcclusion
* Options for screen space Ambient Occlusion
*/
public static class AmbientOcclusionOptions {
/**
@@ -138,15 +150,16 @@ public class View {
/**
* Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
*/
public float bias = 0.005f;
public float bias = 0.0005f;
/**
* Controls ambient occlusion's contrast. Between 0 (linear) and 1 (squared)
* Controls ambient occlusion's contrast. Must be positive. Default is 1.
* Good values are between 0.5 and 3.
*/
public float power = 0.0f;
public float power = 1.0f;
/**
* How each dimension of the AO buffer is scaled. Must be positive and <= 1.
* How each dimension of the AO buffer is scaled. Must be either 0.5 or 1.0.
*/
public float resolution = 0.5f;
@@ -154,24 +167,257 @@ public class View {
* Strength of the Ambient Occlusion effect. Must be positive.
*/
public float intensity = 1.0f;
/**
* The quality setting controls the number of samples used for evaluating Ambient
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
* applications.
*/
@NonNull
public QualityLevel quality = QualityLevel.LOW;
/**
* The upsampling setting controls the quality of the ambient occlusion buffer upsampling.
* The default is QualityLevel.LOW and uses bilinear filtering, a value of
* QualityLevel.HIGH or more enables a better bilateral filter.
*/
@NonNull
public QualityLevel upsampling = QualityLevel.LOW;
/**
* enable or disable screen space ambient occlusion
*/
public boolean enabled = false;
/**
* Minimal angle to consider in radian. This is used to reduce the creases that can
* appear due to insufficiently tessellated geometry.
* For e.g. a good values to try could be around 0.2.
*/
public float minHorizonAngleRad = 0.0f;
}
/**
* Sets the quality of the HDR color buffer.
*
* <p>
* A quality of <code>HIGH</code> or <code>ULTRA</code> means using an RGB16F or RGBA16F color
* buffer. This means colors in the LDR range (0..1) have 10 bit precision. A quality of
* <code>LOW</code> or <code>MEDIUM</code> means using an R11G11B10F opaque color buffer or an
* RGBA16F transparent color buffer. With R11G11B10F colors in the LDR range have a precision of
* either 6 bits (red and green channels) or 5 bits (blue channel).
* </p>
* Options for Temporal Anti-aliasing (TAA)
* @see View#setTemporalAntiAliasingOptions()
*/
public enum QualityLevel {
LOW,
MEDIUM,
HIGH,
ULTRA
public static class TemporalAntiAliasingOptions {
/** reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother) */
public float filterWidth = 1.0f;
/** history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA). */
public float feedback = 0.04f;
/** enables or disables temporal anti-aliasing */
public boolean enabled = false;
};
/**
* Options for controlling the Bloom effect
*
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
* maximum is 12. This value together with resolution influences the spread of the
* blur effect. This value can be silently reduced to accommodate the original
* image size.
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
* the maximum is lower of the original resolution and 4096. This parameter is
* silently clamped to the minimum and maximum.
* It is highly recommended that this value be smaller than the target resolution
* after dynamic resolution is applied (horizontally and vertically).
* strength: how much of the bloom is added to the original image. Between 0 and 1.
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
* image (true).
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
* useful for artistic reasons and is usually needed when a dirt texture is used.
* dirt: A dirt/scratch/smudges texture (that can be RGB), which gets added to the
* bloom effect. Smudges are visible where bloom occurs. Threshold must be
* enabled for the dirt effect to work properly.
* dirtStrength: Strength of the dirt texture.
*
* @see View#setBloomOptions
*/
public static class BloomOptions {
public enum BlendingMode {
ADD,
INTERPOLATE
}
/**
* User provided dirt texture
*/
@Nullable
public Texture dirt = null;
/**
* strength of the dirt texture
*/
public float dirtStrength = 0.2f;
/**
* Strength of the bloom effect, between 0.0 and 1.0
*/
public float strength = 0.10f;
/**
* Resolution of minor axis (2^levels to 4096)
*/
public int resolution = 360;
/**
* Bloom x/y aspect-ratio (1/32 to 32)
*/
public float anamorphism = 1.0f;
/**
* Number of blur levels (3 to 12)
*/
public int levels = 6;
/**
* How the bloom effect is applied
*/
public BlendingMode blendingMode = BlendingMode.ADD;
/**
* Whether to threshold the source
*/
public boolean threshold = true;
/**
* enable or disable bloom
*/
public boolean enabled = false;
/**
* limit highlights to this value before bloom. Use +inf for no limiting.
* minimum value is 10.0.
*/
public float highlight = 1000.0f;
}
/**
* Options to control fog in the scene
*
* @see View#setFogOptions
*/
public static class FogOptions {
/**
* distance in world units from the camera where the fog starts ( >= 0.0 )
*/
public float distance = 0.0f;
/**
* fog's maximum opacity between 0 and 1
*/
public float maximumOpacity = 1.0f;
/**
* fog's floor in world units
*/
public float height = 0.0f;
/**
* how fast fog dissipates with altitude
*/
public float heightFalloff = 1.0f;
/**
* Fog's color as a linear RGB color.
*/
@NonNull
@Size(min = 3)
public float[] color = { 0.5f, 0.5f, 0.5f };
/**
* fog's density at altitude given by 'height'
*/
public float density = 0.1f;
/**
* distance in world units from the camera where in-scattering starts
*/
public float inScatteringStart = 0.0f;
/**
* size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100)
*/
public float inScatteringSize = -1.0f;
/**
* fog color will be modulated by the IBL color in the view direction
*/
public boolean fogColorFromIbl = false;
/**
* enable or disable fog
*/
public boolean enabled = false;
}
/**
* Options to control Depth of Field (DoF) effect in the scene
*
* @see View#setDepthOfFieldOptions
*/
public static class DepthOfFieldOptions {
/** focus distance in world units */
public float focusDistance = 10.0f;
/**
* circle of confusion scale factor (amount of blur)
*
* <p>cocScale can be used to set the depth of field blur independently from the camera
* aperture, e.g. for artistic reasons. This can be achieved by setting:</p>
* <code>
* cocScale = cameraAperture / desiredDoFAperture
* </code>
*
*/
public float cocScale = 1.0f;
/** maximum aperture diameter in meters (zero to disable bokeh rotation) */
public float maxApertureDiameter = 0.01f;
/** enable or disable Depth of field effect */
public boolean enabled = false;
};
/**
* Options to control the vignetting effect.
*/
public static class VignetteOptions {
/**
* High values restrict the vignette closer to the corners, between 0 and 1.
*/
public float midPoint = 0.5f;
/**
* Controls the shape of the vignette, from a rounded rectangle (0.0), to an oval (0.5),
* to a circle (1.0). The value must be between 0 and 1.
*/
public float roundness = 0.5f;
/**
* Softening amount of the vignette effect, between 0 and 1.
*/
public float feather = 0.5f;
/**
* Color of the vignette effect as a linear RGBA color. The alpha channel is currently
* ignored.
*/
@NonNull
@Size(min = 4)
public float[] color = { 0.0f, 0.0f, 0.0f, 1.0f };
/**
* Enables or disables the vignette effect.
*/
public boolean enabled = false;
}
/**
@@ -186,14 +432,24 @@ public class View {
* @see #getRenderQuality
*/
public static class RenderQuality {
/**
* <p>
* A quality of <code>HIGH</code> or <code>ULTRA</code> means using an RGB16F or RGBA16F color
* buffer. This means colors in the LDR range (0..1) have 10 bit precision. A quality of
* <code>LOW</code> or <code>MEDIUM</code> means using an R11G11B10F opaque color buffer or an
* RGBA16F transparent color buffer. With R11G11B10F colors in the LDR range have a precision of
* either 6 bits (red and green channels) or 5 bits (blue channel).
* </p>
*/
public QualityLevel hdrColorBuffer = QualityLevel.HIGH;
}
/**
* List of available ambient occlusion techniques.
*
* @deprecated use setAmbientOcclusionOptions instead
* @see #setAmbientOcclusion
*/
*/
@Deprecated
public enum AmbientOcclusion {
NONE,
SSAO
@@ -219,7 +475,10 @@ public class View {
/**
* List of available tone-mapping operators
*
* @deprecated Use ColorGrading instead
*/
@Deprecated
public enum ToneMapping {
/**
* Equivalent to disabling tone-mapping.
@@ -240,18 +499,68 @@ public class View {
TEMPORAL
}
/** @see #setDepthPrepass */
public enum DepthPrepass {
DEFAULT(-1),
DISABLED(0),
ENABLED(1);
/**
* Used to select buffers.
*/
public enum TargetBufferFlags {
/**
* Color 0 buffer selected.
*/
COLOR0(0x1),
/**
* Color 1 buffer selected.
*/
COLOR1(0x2),
/**
* Color 2 buffer selected.
*/
COLOR2(0x4),
/**
* Color 3 buffer selected.
*/
COLOR3(0x8),
/**
* Depth buffer selected.
*/
DEPTH(0x10),
/**
* Stencil buffer selected.
*/
STENCIL(0x20);
final int value;
/*
* No buffer selected
*/
public static EnumSet<TargetBufferFlags> NONE = EnumSet.noneOf(TargetBufferFlags.class);
DepthPrepass(int value) {
this.value = value;
/*
* All color buffers selected
*/
public static EnumSet<TargetBufferFlags> ALL_COLOR =
EnumSet.of(COLOR0, COLOR1, COLOR2, COLOR3);
/**
* Depth and stencil buffer selected.
*/
public static EnumSet<TargetBufferFlags> DEPTH_STENCIL = EnumSet.of(DEPTH, STENCIL);
/**
* All buffers are selected.
*/
public static EnumSet<TargetBufferFlags> ALL = EnumSet.range(COLOR0, STENCIL);
private int mFlags;
TargetBufferFlags(int flags) {
mFlags = flags;
}
};
static int flags(EnumSet<TargetBufferFlags> flags) {
int result = 0;
for (TargetBufferFlags flag : flags) {
result |= flag.mFlags;
}
return result;
}
}
View(long nativeView) {
mNativeObject = nativeView;
@@ -367,39 +676,23 @@ public class View {
}
/**
* Sets the color used to clear the Viewport when rendering this View.
* Sets the blending mode used to draw the view into the SwapChain.
*
* <p>This is ignored if a {@link Skybox} is present or if clearing has been disabled
* via {@link #setClearTargets}. Defaults to black.</p>
*
* @see #getClearColor
* @param blendMode either {@link BlendMode#OPAQUE} or {@link BlendMode#TRANSLUCENT}
* @see #getBlendMode
*/
public void setClearColor(
@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) {
nSetClearColor(getNativeObject(), r, g, b, a);
public void setBlendMode(BlendMode blendMode) {
mBlendMode = blendMode;
nSetBlendMode(getNativeObject(), blendMode.ordinal());
}
/**
* Returns the View clear color in a provided 4-tuple.
*
* @return A reference to the passed-in array.
*
* @see #setClearColor
* @return blending mode set by setBlendMode
* @see #setBlendMode
*/
@NonNull @Size(min = 4)
public float[] getClearColor(@NonNull @Size(min = 4) float[] out) {
out = Asserts.assertFloat4(out);
nGetClearColor(getNativeObject(), out);
return out;
}
/**
* Sets which targets to clear (default: true, true, false)
*
* @see #setClearColor
*/
public void setClearTargets(boolean color, boolean depth, boolean stencil) {
nSetClearTargets(getNativeObject(), color, depth, stencil);
public BlendMode getBlendMode() {
return mBlendMode;
}
/**
@@ -442,6 +735,11 @@ public class View {
* SwapChain associated with the engine.
* </p>
*
* <p>
* A view with a custom render target cannot rely on Renderer.ClearOptions, which only applies
* to the SwapChain. Such view can use a Skybox instead.
* </p>
*
* @param target render target associated with view, or null for the swap chain
*/
public void setRenderTarget(@Nullable RenderTarget target) {
@@ -513,22 +811,74 @@ public class View {
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
}
/**
* Enables or disable temporal anti-aliasing (TAA). Disabled by default.
*
* @param options temporal anti-aliasing options
*/
public void setTemporalAntiAliasingOptions(@NonNull TemporalAntiAliasingOptions options) {
mTemporalAntiAliasingOptions = options;
nSetTemporalAntiAliasingOptions(getNativeObject(),
options.feedback, options.filterWidth, options.enabled);
}
/**
* Returns temporal anti-aliasing options.
*
* @return temporal anti-aliasing options
*/
@NonNull
public TemporalAntiAliasingOptions getTemporalAntiAliasingOptions() {
if (mTemporalAntiAliasingOptions == null) {
mTemporalAntiAliasingOptions = new TemporalAntiAliasingOptions();
}
return mTemporalAntiAliasingOptions;
}
/**
* Enables or disables tone-mapping in the post-processing stage. Enabled by default.
*
* @param type Tone-mapping function.
*
* @deprecated Use {@link #setColorGrading(com.google.android.filament.ColorGrading)}
*/
@Deprecated
public void setToneMapping(@NonNull ToneMapping type) {
nSetToneMapping(getNativeObject(), type.ordinal());
}
/**
* Returns the tone-mapping function.
* @return tone-mapping function.
*
* @deprecated Use {@link #getColorGrading()}. This always returns {@link ToneMapping#ACES}
*/
@Deprecated
@NonNull
public ToneMapping getToneMapping() {
return ToneMapping.values()[nGetToneMapping(getNativeObject())];
return ToneMapping.ACES;
}
/**
* Sets this View's color grading transforms.
*
* @param colorGrading Associate the specified {@link ColorGrading} to this view. A ColorGrading
* can be associated to several View instances. Can be null to dissociate
* the currently set ColorGrading from this View. Doing so will revert to
* the use of the default color grading transforms.
*/
public void setColorGrading(@Nullable ColorGrading colorGrading) {
nSetColorGrading(getNativeObject(),
colorGrading != null ? colorGrading.getNativeObject() : 0);
mColorGrading = colorGrading;
}
/**
* Returns the {@link ColorGrading} associated to this view.
*
* @return A {@link ColorGrading} or null if the default {@link ColorGrading} is in use
*/
public ColorGrading getColorGrading() {
return mColorGrading;
}
/**
@@ -570,12 +920,9 @@ public class View {
nSetDynamicResolutionOptions(getNativeObject(),
options.enabled,
options.homogeneousScaling,
options.targetFrameTimeMilli,
options.headRoomRatio,
options.scaleRate,
options.minScale,
options.maxScale,
options.history);
options.quality.ordinal());
}
/**
@@ -612,49 +959,6 @@ public class View {
return mRenderQuality;
}
/**
* Checks if this view is rendered with a depth-only prepass.
*
* @return the value set by {@link #setDepthPrepass}.
*/
@NonNull
public DepthPrepass getDepthPrepass() {
return mDepthPrepass;
}
/**
* Sets whether this view is rendered with or without a depth pre-pass.
*
* <p><b>This setting is ignored and will be removed in future versions of Filament.</b></p>
*
* <p>
* By default, the system picks the most appropriate strategy for your platform; this method
* lets you override that strategy.
* </p>
*
* <p>
* When the depth pre-pass is enabled, the renderer will first draw all objects in the
* depth buffer from front to back, and then draw the objects again but sorted to minimize
* state changes. With the depth pre-pass disabled, objects are drawn only once, but it may
* result in more state changes or more overdraw.
* </p>
*
* <p>
* The best strategy may depend on the scene and/or GPU.
* </p>
*
* <ul>
* <li>DepthPrepass::DEFAULT uses the most appropriate strategy</li>
* <li>DepthPrepass::DISABLED disables the depth pre-pass</li>
* <li>DepthPrepass::ENABLE enables the depth pre-pass</li>
* </ul>
*/
@Deprecated
public void setDepthPrepass(@NonNull DepthPrepass depthPrepass) {
mDepthPrepass = depthPrepass;
nSetDepthPrepass(getNativeObject(), depthPrepass.value);
}
/**
* Returns true if post-processing is enabled.
*
@@ -745,18 +1049,20 @@ public class View {
/**
* Activates or deactivates ambient occlusion.
*
* @see #setAmbientOcclusionOptions
* @param ao Type of ambient occlusion to use.
*/
@Deprecated
public void setAmbientOcclusion(@NonNull AmbientOcclusion ao) {
nSetAmbientOcclusion(getNativeObject(), ao.ordinal());
}
/**
* Queries the type of ambient occlusion active for this View.
*
* @see #getAmbientOcclusionOptions
* @return ambient occlusion type.
*/
@Deprecated
@NonNull
public AmbientOcclusion getAmbientOcclusion() {
return AmbientOcclusion.values()[nGetAmbientOcclusion(getNativeObject())];
@@ -770,7 +1076,8 @@ public class View {
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
mAmbientOcclusionOptions = options;
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
options.resolution, options.intensity);
options.resolution, options.intensity, options.quality.ordinal(), options.upsampling.ordinal(),
options.enabled, options.minHorizonAngleRad);
}
/**
@@ -786,6 +1093,120 @@ public class View {
return mAmbientOcclusionOptions;
}
/**
* Sets bloom options.
*
* @param options Options for bloom.
* @see #getBloomOptions
*/
public void setBloomOptions(@NonNull BloomOptions options) {
mBloomOptions = options;
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
options.dirtStrength, options.strength, options.resolution,
options.anamorphism, options.levels, options.blendingMode.ordinal(),
options.threshold, options.enabled, options.highlight);
}
/**
* Gets the bloom options
* @see #setBloomOptions
*
* @return bloom options currently set.
*/
@NonNull
public BloomOptions getBloomOptions() {
if (mBloomOptions == null) {
mBloomOptions = new BloomOptions();
}
return mBloomOptions;
}
/**
* Sets vignette options.
*
* @param options Options for vignetting.
* @see #getVignetteOptions
*/
public void setVignetteOptions(@NonNull VignetteOptions options) {
assertFloat4In(options.color);
mVignetteOptions = options;
nSetVignetteOptions(getNativeObject(),
options.midPoint, options.roundness, options.feather,
options.color[0], options.color[1], options.color[2], options.color[3],
options.enabled);
}
/**
* Gets the vignette options
* @see #setVignetteOptions
*
* @return vignetting options currently set.
*/
@NonNull
public VignetteOptions getVignetteOptions() {
if (mVignetteOptions == null) {
mVignetteOptions = new VignetteOptions();
}
return mVignetteOptions;
}
/**
* Sets fog options.
*
* @param options Options for fog.
* @see #getFogOptions
*/
public void setFogOptions(@NonNull FogOptions options) {
assertFloat3In(options.color);
mFogOptions = options;
nSetFogOptions(getNativeObject(), options.distance, options.maximumOpacity, options.height,
options.heightFalloff, options.color[0], options.color[1], options.color[2],
options.density, options.inScatteringStart, options.inScatteringSize,
options.fogColorFromIbl,
options.enabled);
}
/**
* Gets the fog options
*
* @return fog options currently set.
* @see #setFogOptions
*/
@NonNull
public FogOptions getFogOptions() {
if (mFogOptions == null) {
mFogOptions = new FogOptions();
}
return mFogOptions;
}
/**
* Sets Depth of Field options.
*
* @param options Options for depth of field effect.
* @see #getDepthOfFieldOptions
*/
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
mDepthOfFieldOptions = options;
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale, options.maxApertureDiameter, options.enabled);
}
/**
* Gets the Depth of Field options
*
* @return Depth of Field options currently set.
* @see #setDepthOfFieldOptions
*/
@NonNull
public DepthOfFieldOptions getDepthOfFieldOptions() {
if (mDepthOfFieldOptions == null) {
mDepthOfFieldOptions = new DepthOfFieldOptions();
}
return mDepthOfFieldOptions;
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed View");
@@ -801,9 +1222,6 @@ public class View {
private static native void nSetScene(long nativeView, long nativeScene);
private static native void nSetCamera(long nativeView, long nativeCamera);
private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height);
private static native void nSetClearColor(long nativeView, float r, float g, float b, float a);
private static native void nGetClearColor(long nativeView, float[] out);
private static native void nSetClearTargets(long nativeView, boolean color, boolean depth, boolean stencil);
private static native void nSetVisibleLayers(long nativeView, int select, int value);
private static native void nSetShadowsEnabled(long nativeView, boolean enabled);
private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget);
@@ -811,22 +1229,23 @@ public class View {
private static native int nGetSampleCount(long nativeView);
private static native void nSetAntiAliasing(long nativeView, int type);
private static native int nGetAntiAliasing(long nativeView);
private static native void nSetToneMapping(long nativeView, int type);
private static native int nGetToneMapping(long nativeView);
private static native void nSetDithering(long nativeView, int dithering);
private static native int nGetDithering(long nativeView);
private static native void nSetDynamicResolutionOptions(long nativeView,
boolean enabled, boolean homogeneousScaling,
float targetFrameTimeMilli, float headRoomRatio, float scaleRate,
float minScale, float maxScale, int history);
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, int quality);
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetDepthPrepass(long nativeView, int value);
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
private static native boolean nIsPostProcessingEnabled(long nativeView);
private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted);
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
private static native int nGetAmbientOcclusion(long nativeView);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int upsampling, boolean enabled, float minHorizonAngleRad);
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 nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled);
private static native void 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

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.android;
import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
import android.view.Display;
import com.google.android.filament.Renderer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* DisplayHelper is here to help managing a Display, for instance being notified when its
* resolution or refresh rate changes.
*/
public class DisplayHelper {
private Handler mHandler = null;
private DisplayManager mDisplayManager;
private Display mDisplay;
private Renderer mRenderer;
private DisplayManager.DisplayListener mListener;
/**
* Creates a DisplayHelper which helps managing a {@link Display}.
*
* The {@link Display} to manage is specified with {@link #attach}
*
* @param context a {@link Context} to used to retrieve the {@link DisplayManager}
*/
public DisplayHelper(@NonNull Context context) {
mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
}
/**
* Creates a DisplayHelper which helps manage a {@link Display} and provides a Handler
* where callbacks can execute filament code. Use this method if filament is executing
* on another thread.
*
* @param context a {@link Context} to used to retrieve teh {@link DisplayManager}
* @param handler a {@link Handler} used to run callbacks accessing filament
*/
public DisplayHelper(@NonNull Context context, @NonNull Handler handler) {
this(context);
mHandler = handler;
}
@Override
protected void finalize() throws Throwable {
try {
// just for safety
detach();
} finally {
super.finalize();
}
}
/**
* Sets the filament {@link Renderer} associated to the {@link Display}, from this point
* on, {@link Renderer.DisplayInfo} will be automatically updated when the {@link Display}
* properties change.
*
* This is typically called from {@link UiHelper.RendererCallback#onNativeWindowChanged}.
*
* @param renderer a filament {@link Renderer} instance
* @param display a {@link Display} to be associated with the {@link Renderer}
*/
public void attach(@NonNull Renderer renderer, @NonNull Display display) {
if (renderer == mRenderer && display == mDisplay) {
return;
}
mRenderer = renderer;
mDisplay = display;
mListener = new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
}
@Override
public void onDisplayRemoved(int displayId) {
}
@Override
public void onDisplayChanged(int displayId) {
if (displayId == display.getDisplayId()) {
updateDisplayInfo();
}
}
};
mDisplayManager.registerDisplayListener(mListener, mHandler);
// always invoke the callback when it's registered
if (mHandler != null) {
mHandler.post(new Runnable() {
@Override
public void run() {
updateDisplayInfo();
}
});
} else {
updateDisplayInfo();
}
}
/**
* Disconnect the previously set {@link Renderer} from {@link Display}
* This is typically called from {@link UiHelper.RendererCallback#onDetachedFromSurface}.
*/
public void detach() {
if (mListener != null) {
mDisplayManager.unregisterDisplayListener(mListener);
mListener = null;
mDisplay = null;
mRenderer = null;
}
}
private void updateDisplayInfo() {
mRenderer.setDisplayInfo(
DisplayHelper.getDisplayInfo(mDisplay, mRenderer.getDisplayInfo()));
}
/**
* Returns the {@link Display} currently monitored
* @return the {@link Display} set in {@link #attach} or null
*/
public Display getDisplay() {
return mDisplay;
}
/**
* Populate a {@link Renderer.DisplayInfo} with properties from the given {@link Display}
*
* @param display {@link Display} to get {@link Renderer.DisplayInfo} from
* @param info an instance of {@link Renderer.DisplayInfo} or null
* @return an populated instance of {@link Renderer.DisplayInfo}
*/
@NonNull
public static Renderer.DisplayInfo getDisplayInfo(@NonNull Display display, @Nullable Renderer.DisplayInfo info) {
if (info == null) {
info = new Renderer.DisplayInfo();
}
info.refreshRate = DisplayHelper.getRefreshRate(display);
info.presentationDeadlineNanos = DisplayHelper.getPresentationDeadlineNanos(display);
info.vsyncOffsetNanos = DisplayHelper.getAppVsyncOffsetNanos(display);
return info;
}
/**
* @return the {@link Display} application vsync offset 0 if not supported
* @see Display#getAppVsyncOffsetNanos
*/
public static long getAppVsyncOffsetNanos(@NonNull Display display) {
if (Build.VERSION.SDK_INT >= 29) {
return display.getAppVsyncOffsetNanos();
}
return 0;
}
/**
* @return the {@link Display} presentation deadline before the h/w vsync event in nanoseconds
* @see Display#getPresentationDeadlineNanos
*/
public static long getPresentationDeadlineNanos(@NonNull Display display) {
if (Build.VERSION.SDK_INT >= 29) {
return display.getPresentationDeadlineNanos();
}
// not supported, pick something reasonable
return 11_600_000;
}
/**
* @return the {@link Display} refresh rate in Hz
* @see Display#getRefreshRate
*/
public static float getRefreshRate(@NonNull Display display) {
return display.getRefreshRate();
}
/**
* Returns a {@link Display}'s refresh period in nanoseconds
* @param display the {@link Display} to get the refresh period from
* @return the {@link Display} refresh period in nanoseconds
*/
public static long getRefreshPeriodNanos(@NonNull Display display) {
return (long) (1_000_000_000.0 / display.getRefreshRate());
}
}

View File

@@ -43,6 +43,14 @@ public final class TextureHelper {
level, 0, 0, texture.getWidth(level), texture.getHeight(level), bitmap);
}
public static void setBitmap(@NonNull Engine engine,
@NonNull Texture texture, @IntRange(from = 0) int level, @NonNull Bitmap bitmap,
Object handler, Runnable callback) {
setBitmap(engine, texture,
level, 0, 0, texture.getWidth(level), texture.getHeight(level), bitmap,
handler, callback);
}
public static void setBitmap(@NonNull Engine engine,
@NonNull Texture texture, @IntRange(from = 0) int level,
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
@@ -60,6 +68,23 @@ public final class TextureHelper {
bitmap, format);
}
public static void setBitmap(@NonNull Engine engine,
@NonNull Texture texture, @IntRange(from = 0) int level,
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
@NonNull Bitmap bitmap, Object handler, Runnable callback) {
int format = toNativeFormat(bitmap.getConfig());
if (format == BITMAP_CONFIG_RGBA_4444 || format == BITMAP_CONFIG_HARDWARE) {
throw new IllegalArgumentException("Unsupported config: ARGB_4444 or HARDWARE");
}
long nativeTexture = texture.getNativeObject();
long nativeEngine = engine.getNativeObject();
nSetBitmapWithCallback(nativeTexture, nativeEngine, level, xoffset, yoffset, width, height,
bitmap, format, handler, callback);
}
private static int toNativeFormat(Bitmap.Config config) {
switch (config) {
case ALPHA_8: return BITMAP_CONFIG_ALPHA_8;
@@ -74,4 +99,8 @@ public final class TextureHelper {
private static native void nSetBitmap(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height, Bitmap bitmap, int format);
private static native void nSetBitmapWithCallback(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height, Bitmap bitmap, int format,
Object handler, Runnable callback);
}

View File

@@ -454,7 +454,12 @@ public class UiHelper {
public void onSurfaceTextureSizeChanged(
SurfaceTexture surfaceTexture, int width, int height) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureSizeChanged()");
mRenderCallback.onResized(width, height);
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
mRenderCallback.onResized(mDesiredWidth, mDesiredHeight);
} else {
mRenderCallback.onResized(width, height);
}
}
@Override

View File

@@ -2,61 +2,16 @@ cmake_minimum_required(VERSION 3.6)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(DISABLE_GLTFIO_JNI TRUE)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gltfio-android ${CMAKE_CURRENT_BINARY_DIR}/gltfio-android)
add_library(filament STATIC IMPORTED)
set_target_properties(filament PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament.a)
add_library(backend STATIC IMPORTED)
set_target_properties(backend PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbackend.a)
add_library(camutils STATIC IMPORTED)
set_target_properties(camutils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcamutils.a)
add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
add_library(image STATIC IMPORTED)
set_target_properties(image PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
add_library(ibl STATIC IMPORTED)
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
add_library(geometry STATIC IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
add_library(filabridge STATIC IMPORTED)
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
add_library(gltfio STATIC IMPORTED)
set_target_properties(gltfio PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
add_library(gltfio_resources STATIC IMPORTED)
set_target_properties(gltfio_resources PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources.a)
add_library(bluevk STATIC IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(smol-v STATIC IMPORTED)
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
include_directories(${FILAMENT_DIR}/include
..
../../libs/utils/include)
@@ -70,9 +25,6 @@ add_library(filament-utils-jni SHARED
../common/CallbackUtils.cpp
../common/NioUtils.cpp
$<TARGET_OBJECTS:gltfio-jni-obj>
$<TARGET_OBJECTS:filament-jni-obj>
)
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
@@ -80,25 +32,7 @@ set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
# The ordering in the following list is important because CMake does not have dependency information.
target_link_libraries(filament-utils-jni
gltfio
filament
backend
filaflat
filabridge
gltfio-jni
camutils
geometry
image
ibl
utils
log
GLESv3
EGL
android
jnigraphics
gltfio_resources
m
)
if (FILAMENT_SUPPORTS_VULKAN)
target_link_libraries(filament-utils-jni bluevk smol-v)
endif()

View File

@@ -1,44 +1,43 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
buildToolsVersion versions.buildTools
compileSdkVersion versions.compileSdk
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
}
}
flavorDimensions "functionality"
productFlavors {
full {
dimension "functionality"
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
lite {
dimension "functionality"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
kotlin.srcDirs += "src/main/java"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
// No need to package up the following shared libs, which arise as a side effect of our
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
// "More than one file was found with OS independent path ..."
packagingOptions {
exclude 'lib/*/libfilament-jni.so'
exclude 'lib/*/libgltfio-jni.so'
}
}
configurations.all { config ->
// Hack to preserve the version of the dependencies
if (!config.name.endsWith('Publication')) {
resolutionStrategy {
dependencySubstitution {
substitute(module("com.google.android.filament:gltfio-android:${VERSION_NAME}")).with(project(":gltfio-android"))
substitute(module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")).with(project(":gltfio-android"))
}
}
}
}
@@ -46,17 +45,27 @@ dependencies {
implementation deps.kotlin
implementation deps.androidx.annotations
implementation project(':filament-android')
implementation project(':gltfio-android')
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
fullImplementation module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
liteImplementation module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
afterEvaluate { project ->
afterEvaluate {
publishing {
publications {
release(MavenPublication) {
artifactId = POM_ARTIFACT_ID
from components.release
fullRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_FULL
from components.fullRelease
}
liteRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_LITE
from components.liteRelease
}
}
}

View File

@@ -1,3 +1,4 @@
POM_NAME=Filament Android Utilities
POM_ARTIFACT_ID=filament-utils-android
POM_ARTIFACT_ID_FULL=filament-utils-android
POM_ARTIFACT_ID_LITE=filament-utils-android-lite
POM_PACKAGING=aar

View File

@@ -90,6 +90,36 @@ extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBu
builder->mapMinDistance(arg);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightStartPosition(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightStartPosition(x, y, z);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightStartOrientation(JNIEnv*, jclass, jlong nativeBuilder, jfloat pitch, jfloat yaw) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightStartOrientation(pitch, yaw);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightMaxMoveSpeed(JNIEnv*, jclass, jlong nativeBuilder, jfloat maxSpeed) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightMaxMoveSpeed(maxSpeed);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightSpeedSteps(JNIEnv*, jclass, jlong nativeBuilder, jint steps) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightSpeedSteps(steps);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightPanSpeed(JNIEnv*, jclass, jlong nativeBuilder, jfloat x, jfloat y) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightPanSpeed(x, y);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderFlightMoveDamping(JNIEnv*, jclass, jlong nativeBuilder, jfloat damping) {
Builder* builder = (Builder*) nativeBuilder;
builder->flightMoveDamping(damping);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderGroundPlane(JNIEnv*, jclass, jlong nativeBuilder, jfloat a, jfloat b, jfloat c, jfloat d) {
Builder* builder = (Builder*) nativeBuilder;
builder->groundPlane(a, b, c, d);
@@ -170,9 +200,24 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipul
manip->grabEnd();
}
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nZoom(JNIEnv*, jclass, jlong nativeManip, jint x, jint y, jfloat scrolldelta) {
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nKeyDown(JNIEnv*, jclass, jlong nativeManip, jint key) {
auto manip = (Manipulator<float>*) nativeManip;
manip->zoom(x, y, scrolldelta);
manip->keyDown((Manipulator<float>::Key) key);
}
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nKeyUp(JNIEnv*, jclass, jlong nativeManip, jint key) {
auto manip = (Manipulator<float>*) nativeManip;
manip->keyUp((Manipulator<float>::Key) key);
}
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nScroll(JNIEnv*, jclass, jlong nativeManip, jint x, jint y, jfloat scrolldelta) {
auto manip = (Manipulator<float>*) nativeManip;
manip->scroll(x, y, scrolldelta);
}
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_utils_Manipulator_nUpdate(JNIEnv*, jclass, jlong nativeManip, jfloat deltaTime) {
auto manip = (Manipulator<float>*) nativeManip;
manip->update(deltaTime);
}
extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_utils_Manipulator_nGetCurrentBookmark(JNIEnv*, jclass, jlong nativeManip) {

View File

@@ -28,23 +28,7 @@ using namespace filament;
using namespace filament::math;
using namespace image;
extern void registerCallbackUtils(JNIEnv*);
extern void registerNioUtils(JNIEnv*);
jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
registerCallbackUtils(env);
registerNioUtils(env);
return JNI_VERSION_1_6;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_KtxLoader_nCreateTexture(JNIEnv* env, jclass,
static jlong nCreateTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
@@ -55,8 +39,7 @@ Java_com_google_android_filament_utils_KtxLoader_nCreateTexture(JNIEnv* env, jcl
}, bundle);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_KtxLoader_nCreateIndirectLight(JNIEnv* env, jclass,
static jlong nCreateIndirectLight(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
@@ -78,8 +61,7 @@ Java_com_google_android_filament_utils_KtxLoader_nCreateIndirectLight(JNIEnv* en
return (jlong) indirectLight;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_KtxLoader_nCreateSkybox(JNIEnv* env, jclass,
static jlong nCreateSkybox(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
@@ -90,3 +72,24 @@ Java_com_google_android_filament_utils_KtxLoader_nCreateSkybox(JNIEnv* env, jcla
}, bundle);
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
}
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
jclass c = env->FindClass("com/google/android/filament/utils/KtxLoader");
if (c == nullptr) return JNI_ERR;
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)},
};
int rc = env->RegisterNatives(c, methods, sizeof(methods) / sizeof(JNINativeMethod));
if (rc != JNI_OK) return rc;
return JNI_VERSION_1_6;
}

View File

@@ -77,7 +77,7 @@ class GestureDetector(private val view: View, private val manipulator: Manipulat
if (currentGesture == Gesture.ZOOM) {
val d0 = previousTouch.separation
val d1 = touch.separation
manipulator.zoom(touch.x, touch.y, (d0 - d1) * kZoomSpeed)
manipulator.scroll(touch.x, touch.y, (d0 - d1) * kZoomSpeed)
previousTouch = touch
return
}

View File

@@ -42,10 +42,10 @@ object KtxLoader {
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
fun createTexture(engine: Engine, buffer: Buffer, options: Options): Texture {
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(nativeTexture)
return Texture(engine, nativeTexture)
}
/**
@@ -56,10 +56,10 @@ object KtxLoader {
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
fun createIndirectLight(engine: Engine, buffer: Buffer, options: Options): IndirectLight {
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(nativeIndirectLight)
return IndirectLight(engine, nativeIndirectLight)
}
/**
@@ -70,10 +70,10 @@ object KtxLoader {
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
fun createSkybox(engine: Engine, buffer: Buffer, options: Options): Skybox {
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(nativeSkybox)
return Skybox(engine, nativeSkybox)
}
private external fun nCreateTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long

View File

@@ -25,8 +25,9 @@ import androidx.annotation.Size;
* Helper that enables camera interaction similar to sketchfab or Google Maps.
*
* Clients notify the camera manipulator of various mouse or touch events, then periodically call
* its getLookAt() method so that they can adjust their camera(s). Two modes are supported: ORBIT
* and MAP. To construct a manipulator instance, the desired mode is passed into the create method.
* its getLookAt() method so that they can adjust their camera(s). Three modes are supported: ORBIT,
* MAP, and FREE_FLIGHT. To construct a manipulator instance, the desired mode is passed into the
* create method.
*
* @see Bookmark
*/
@@ -37,10 +38,24 @@ public class Manipulator {
mNativeObject = nativeIndexBuffer;
}
public enum Mode { ORBIT, MAP };
public enum Mode { ORBIT, MAP, FREE_FLIGHT };
public enum Fov { VERTICAL, HORIZONTAL };
/**
* Keys used to translate the camera in FREE_FLIGHT mode.
* UP and DOWN dolly the camera forwards and backwards.
* LEFT and RIGHT strafe the camera left and right.
*/
public enum Key {
FORWARD,
LEFT,
BACKWARD,
RIGHT,
UP,
DOWN
}
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
@@ -178,6 +193,72 @@ public class Manipulator {
return this;
}
/**
* Sets the initial eye position in world space for FREE_FLIGHT mode. Defaults to (0,0,0).
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightStartPosition(float x, float y, float z) {
nFlightStartPosition(mNativeBuilder, x, y, z);
return this;
}
/**
* Sets the initial orientation in pitch and yaw for FREE_FLIGHT mode. Defaults to (0,0).
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightStartOrientation(float pitch, float yaw) {
nFlightStartOrientation(mNativeBuilder, pitch, yaw);
return this;
}
/**
* Sets the maximum camera translation speed in world units per second for FREE_FLIGHT mode.
* Defaults to 10.
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightMaxMoveSpeed(float maxSpeed) {
nFlightMaxMoveSpeed(mNativeBuilder, maxSpeed);
return this;
}
/**
* Sets the number of speed steps adjustable with scroll wheel for FREE_FLIGHT mode.
* Defaults to 80.
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightSpeedSteps(int steps) {
nFlightSpeedSteps(mNativeBuilder, steps);
return this;
}
/**
* Sets the multiplier with viewport delta for FREE_FLIGHT mode.
* This defaults to 0.01.
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightPanSpeed(float x, float y) {
nFlightPanSpeed(mNativeBuilder, x, y);
return this;
}
/**
* Applies a deceleration to camera movement in FREE_FLIGHT mode. Defaults to 0 (no damping).
*
* Lower values give slower damping times. A good default is 15.0. Too high a value may lead
* to instability.
*
* @return this <code>Builder</code> object for chaining calls
*/
public Builder flightMoveDamping(float damping) {
nFlightMoveDamping(mNativeBuilder, damping);
return this;
}
/**
* Sets the ground plane equation used for ray casts.
* This is a plane equation as in Ax + By + Cz + D = 0.
@@ -281,11 +362,13 @@ public class Manipulator {
/**
* Starts a grabbing session (i.e. the user is dragging around in the viewport).
*
* This starts a panning session in MAP mode, and start either rotating or strafing in ORBIT.
* In MAP mode, this starts a panning session.
* In ORBIT mode, this starts either rotating or strafing.
* In FREE_FLIGHT mode, this starts a nodal panning session.
*
* @param x X-coordinate for point of interest in viewport space
* @param y Y-coordinate for point of interest in viewport space
* @param strafe ORBIT mode only; if true, starts a translation rather than a rotation.
* @param strafe ORBIT mode only; if true, starts a translation rather than a rotation
*/
public void grabBegin(int x, int y, boolean strafe) {
nGrabBegin(mNativeObject, x, y, strafe);
@@ -308,14 +391,46 @@ public class Manipulator {
}
/**
* Dollys the camera along the viewing direction.
*
* @param x X-coordinate for point of interest in viewport space
* @param y Y-coordinate for point of interest in viewport space
* @param scrolldelta Positive means "zoom in", negative means "zoom out"
* Keys used to translate the camera in FREE_FLIGHT mode.
* UP and DOWN dolly the camera forwards and backwards.
* LEFT and RIGHT strafe the camera left and right.
* UP and DOWN boom the camera upwards and downwards.
*/
public void zoom(int x, int y, float scrolldelta) {
nZoom(mNativeObject, x, y, scrolldelta);
public void keyDown(Key key) {
nKeyDown(mNativeObject, key.ordinal());
}
/**
* Signals that a key is now in the up state.
*
* @see keyDown
*/
public void keyUp(Key key) {
nKeyUp(mNativeObject, key.ordinal());
}
/**
* In MAP and ORBIT modes, dollys the camera along the viewing direction.
* In FREE_FLIGHT mode, adjusts the move speed of the camera.
*
* @param x X-coordinate for point of interest in viewport space, ignored in FREE_FLIGHT mode
* @param y Y-coordinate for point of interest in viewport space, ignored in FREE_FLIGHT mode
* @param scrolldelta In MAP and ORBIT modes, negative means "zoom in", positive means "zoom out"
* In FREE_FLIGHT mode, negative means "slower", positive means "faster"
*/
public void scroll(int x, int y, float scrolldelta) {
nScroll(mNativeObject, x, y, scrolldelta);
}
/**
* Processes input and updates internal state.
*
* This must be called once every frame before getLookAt is valid.
*
* @param deltaTime The amount of time, in seconds, passed since the previous call to update.
*/
public void update(float deltaTime) {
nUpdate(mNativeObject, deltaTime);
}
/**
@@ -359,6 +474,12 @@ public class Manipulator {
private static native void nBuilderFarPlane(long nativeBuilder, float distance);
private static native void nBuilderMapExtent(long nativeBuilder, float width, float height);
private static native void nBuilderMapMinDistance(long nativeBuilder, float arg);
private static native void nFlightStartPosition(long nativeBuilder, float x, float y, float z);
private static native void nFlightStartOrientation(long nativeBuilder, float pitch, float yaw);
private static native void nFlightMaxMoveSpeed(long nativeBuilder, float maxSpeed);
private static native void nFlightSpeedSteps(long nativeBuilder, int steps);
private static native void nFlightPanSpeed(long nativeBuilder, float x, float y);
private static native void nFlightMoveDamping(long nativeBuilder, float damping);
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
private static native long nBuilderBuild(long nativeBuilder, int mode);
@@ -371,7 +492,10 @@ public class Manipulator {
private static native void nGrabBegin(long nativeManip, int x, int y, boolean strafe);
private static native void nGrabUpdate(long nativeManip, int x, int y);
private static native void nGrabEnd(long nativeManip);
private static native void nZoom(long nativeManip, int x, int y, float scrolldelta);
private static native void nKeyDown(long nativeManip, int key);
private static native void nKeyUp(long nativeManip, int key);
private static native void nScroll(long nativeManip, int x, int y, float scrolldelta);
private static native void nUpdate(long nativeManip, float deltaTime);
private static native long nGetCurrentBookmark(long nativeManip);
private static native long nGetHomeBookmark(long nativeManip);
private static native void nJumpToBookmark(long nativeManip, long nativeBookmark);

View File

@@ -21,10 +21,19 @@ import android.view.Surface
import android.view.SurfaceView
import android.view.TextureView
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
private const val kNearPlane = 0.5
private const val kFarPlane = 10000.0
private const val kFovDegrees = 45.0
private const val kAperture = 16f
private const val kShutterSpeed = 1f / 125f
private const val kSensitivity = 100f
/**
* Helps render glTF models into a [SurfaceView] or [TextureView] with an orbit controller.
*
@@ -41,7 +50,8 @@ import java.nio.Buffer
* clients still have the responsibility of adding an [IndirectLight] and [Skybox] to the scene.
* Additionally, clients should:
*
* 1. Call [onTouchEvent] from a touch handler.
* 1. Pass the model viewer into [SurfaceView.setOnTouchListener] or call its [onTouchEvent]
* method from your touch handler.
* 2. Call [render] and [Animator.applyAnimation] from a `Choreographer` frame callback.
*
* NOTE: if its associated SurfaceView or TextureView has become detached from its window, the
@@ -49,40 +59,45 @@ import java.nio.Buffer
*
* See `sample-gltf-viewer` for a usage example.
*/
class ModelViewer {
class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
var asset: FilamentAsset? = null
private set
var animator: Animator? = null
private set
val engine: Engine
@Suppress("unused")
val progress
get() = resourceLoader.asyncGetLoadProgress()
var normalizeSkinningWeights = true
var recomputeBoundingBoxes = false
val scene: Scene
val view: View
val camera: Camera
@Entity val light: Int
private val uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
private val cameraManipulator: Manipulator
private val gestureDetector: GestureDetector
private lateinit var displayHelper: DisplayHelper
private lateinit var cameraManipulator: Manipulator
private lateinit var gestureDetector: GestureDetector
private var surfaceView: SurfaceView? = null
private var textureView: TextureView? = null
private var fetchResourcesJob: Job? = null
private val renderer: Renderer
private var swapChain: SwapChain? = null
private var assetLoader: AssetLoader
private var resourceLoader: ResourceLoader
private val readyRenderables = IntArray(128) // add up to 128 entities at a time
private val eyePos = DoubleArray(3)
private val target = DoubleArray(3)
private val upward = DoubleArray(3)
private val kNearPlane = 0.5
private val kFarPlane = 10000.0
private val kFovDegrees = 45.0
private val kAperture = 16f
private val kShutterSpeed = 1f / 125f
private val kSensitivity = 100f
init {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
camera = engine.createCamera().apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
@@ -91,6 +106,7 @@ class ModelViewer {
view.camera = camera
assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
// Always add a direct light source since it is required for shadowing.
// We highly recommend adding an indirect light as well.
@@ -100,7 +116,7 @@ class ModelViewer {
val (r, g, b) = Colors.cct(6_500.0f)
LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(r, g, b)
.intensity(300_000.0f)
.intensity(100_000.0f)
.direction(0.0f, -1.0f, 0.0f)
.castShadows(true)
.build(engine, light)
@@ -108,26 +124,30 @@ class ModelViewer {
scene.addEntity(light)
}
constructor(surfaceView: SurfaceView) {
cameraManipulator = Manipulator.Builder()
.targetPosition(0.0f, 0.0f, -4.0f)
constructor(surfaceView: SurfaceView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
cameraManipulator = manipulator ?: Manipulator.Builder()
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
.viewport(surfaceView.width, surfaceView.height)
.build(Manipulator.Mode.ORBIT)
this.surfaceView = surfaceView
gestureDetector = GestureDetector(surfaceView, cameraManipulator)
displayHelper = DisplayHelper(surfaceView.context)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
addDetachListener(surfaceView)
}
@Suppress("unused")
constructor(textureView: TextureView) {
cameraManipulator = Manipulator.Builder()
.targetPosition(0.0f, 0.0f, -4.0f)
constructor(textureView: TextureView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
cameraManipulator = manipulator ?: Manipulator.Builder()
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
.viewport(textureView.width, textureView.height)
.build(Manipulator.Mode.ORBIT)
this.textureView = textureView
gestureDetector = GestureDetector(textureView, cameraManipulator)
displayHelper = DisplayHelper(textureView.context)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(textureView)
addDetachListener(textureView)
@@ -138,48 +158,59 @@ class ModelViewer {
*/
fun loadModelGlb(buffer: Buffer) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
asset = assetLoader.createAssetFromBinary(buffer)
asset?.let { asset ->
val resourceLoader = ResourceLoader(engine)
resourceLoader.loadResources(asset)
resourceLoader.destroy()
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
asset.releaseSourceData()
scene.addEntities(asset.entities)
}
}
/**
* Loads a JSON-style glTF file and populates the Filament scene.
*
* The given callback is triggered for each requested resource.
*/
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
asset?.let { asset ->
val resourceLoader = ResourceLoader(engine)
for (uri in asset.resourceUris) {
resourceLoader.addResourceData(uri, callback(uri))
}
resourceLoader.loadResources(asset)
resourceLoader.destroy()
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
asset.releaseSourceData()
scene.addEntities(asset.entities)
}
}
/**
* Sets up a root transform on the current model to make it fit into the viewing frustum.
* Loads a JSON-style glTF file and populates the Filament scene.
*
* The given callback is triggered from a worker thread for each requested resource.
*/
fun transformToUnitCube() {
fun loadModelGltfAsync(buffer: Buffer, callback: (String) -> Buffer) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
fetchResourcesJob = CoroutineScope(Dispatchers.IO).launch {
fetchResources(asset!!, callback)
}
}
/**
* Sets up a root transform on the current model to make it fit into a unit cube.
*
* @param centerPoint Coordinate of center point of unit cube, defaults to < 0, 0, -4 >
*/
fun transformToUnitCube(centerPoint: Float3 = kDefaultObjectPosition) {
asset?.let { asset ->
val tm = engine.transformManager
val center = asset.boundingBox.center.let { v-> Float3(v[0], v[1], v[2]) }
var center = asset.boundingBox.center.let { v-> Float3(v[0], v[1], v[2]) }
val halfExtent = asset.boundingBox.halfExtent.let { v-> Float3(v[0], v[1], v[2]) }
val maxExtent = 2.0f * max(halfExtent)
val scaleFactor = 2.0f / maxExtent
center.z = center.z + 4.0f / scaleFactor
val transform = scale(Float3(scaleFactor)) * translation(Float3(-center))
center -= centerPoint / scaleFactor
val transform = scale(Float3(scaleFactor)) * translation(-center)
tm.setTransform(tm.getInstance(asset.root), transpose(transform).toFloatArray())
}
}
@@ -188,7 +219,9 @@ class ModelViewer {
* Frees all entities associated with the most recently-loaded model.
*/
fun destroyModel() {
fetchResourcesJob?.cancel()
asset?.let { asset ->
this.scene.removeEntities(asset.entities)
assetLoader.destroyAsset(asset)
this.asset = null
this.animator = null
@@ -197,24 +230,44 @@ class ModelViewer {
/**
* Renders the model and updates the Filament camera.
*
* @param frameTimeNanos time in nanoseconds when the frame started being rendered,
* typically comes from {@link android.view.Choreographer.FrameCallback}
*/
fun render() {
fun render(frameTimeNanos: Long) {
if (!uiHelper.isReadyToRender) {
return
}
// Allow the resource loader to finalize textures that have become ready.
resourceLoader.asyncUpdateLoad()
// Add renderable entities to the scene as they become ready.
asset?.let { populateScene(it) }
// Extract the camera basis from the helper and push it to the Filament camera.
cameraManipulator.getLookAt(eyePos, target, upward)
camera.lookAt(
eyePos[0], eyePos[1], eyePos[2],
target[0], target[1], target[2],
upward[0], upward[1], upward[2])
if (renderer.beginFrame(swapChain!!)) {
// Render the scene, unless the renderer wants to skip the frame.
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
renderer.endFrame()
}
}
private fun populateScene(asset: FilamentAsset) {
var count = 0
val popRenderables = {count = asset.popRenderables(readyRenderables); count != 0}
while (popRenderables()) {
scene.addEntities(readyRenderables.take(count).toIntArray())
}
scene.addEntities(asset.lightEntities)
}
private fun addDetachListener(view: android.view.View) {
view.addOnAttachStateChangeListener(object : android.view.View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: android.view.View?) {}
@@ -223,6 +276,7 @@ class ModelViewer {
destroyModel()
assetLoader.destroy()
resourceLoader.destroy()
engine.destroyEntity(light)
engine.destroyRenderer(renderer)
@@ -244,13 +298,39 @@ class ModelViewer {
gestureDetector.onTouchEvent(event)
}
@SuppressWarnings("ClickableViewAccessibility")
override fun onTouch(view: android.view.View, event: MotionEvent): Boolean {
onTouchEvent(event)
return true
}
private suspend fun fetchResources(asset: FilamentAsset, callback: (String) -> Buffer) {
val items = HashMap<String, Buffer>()
val resourceUris = asset.resourceUris
for (resourceUri in resourceUris) {
items[resourceUri] = callback(resourceUri)
}
withContext(Dispatchers.Main) {
for ((uri, buffer) in items) {
resourceLoader.addResourceData(uri, buffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
asset.releaseSourceData()
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
surfaceView?.let { displayHelper.attach(renderer, it.display) }
textureView?.let { displayHelper.attach(renderer, it.display) }
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
engine.flushAndWait()
@@ -265,4 +345,8 @@ class ModelViewer {
cameraManipulator.setViewport(width, height)
}
}
}
companion object {
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
}
}

View File

@@ -90,8 +90,8 @@ private fun format(bitmap: Bitmap) = when (bitmap.config.name) {
// Not required when SKIP_BITMAP_COPY is true
private fun type(bitmap: Bitmap) = when (bitmap.config.name) {
"ALPHA_8" -> Texture.Type.UBYTE
"RGB_565" -> Texture.Type.UBYTE
"ALPHA_8" -> Texture.Type.USHORT
"RGB_565" -> Texture.Type.USHORT_565
"ARGB_8888" -> Texture.Type.UBYTE
"RGBA_F16" -> Texture.Type.HALF
else -> throw IllegalArgumentException("Unsupported bitmap configuration")

View File

@@ -14,13 +14,17 @@
* limitations under the License.
*/
package com.google.android.filament.utils;
package com.google.android.filament.utils
import com.google.android.filament.Filament
object Utils {
/**
* Initializes the utils JNI layer. Must be called before using any utils functionality.
*/
fun init() {
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
Filament.init()
System.loadLibrary("filament-utils-jni")
}
}

View File

@@ -1,104 +1,96 @@
cmake_minimum_required(VERSION 3.6)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
set(GLTFIO_DIR ../../libs/gltfio)
set(DRACO_DIR ../../third_party/draco)
set(DISABLE_FILAMENT_JNI TRUE)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../filament-android ${CMAKE_CURRENT_BINARY_DIR}/filament-android)
add_library(filament STATIC IMPORTED)
set_target_properties(filament PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament.a)
add_library(backend STATIC IMPORTED)
set_target_properties(backend PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbackend.a)
add_library(dracodec STATIC IMPORTED)
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
add_library(ibl STATIC IMPORTED)
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
add_library(geometry STATIC IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
add_library(filabridge STATIC IMPORTED)
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
add_library(gltfio STATIC IMPORTED)
set_target_properties(gltfio PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
add_library(gltfio_resources STATIC IMPORTED)
set_target_properties(gltfio_resources PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources.a)
add_library(bluevk STATIC IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(gltfio_resources_lite STATIC IMPORTED)
set_target_properties(gltfio_resources_lite PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources_lite.a)
add_library(smol-v STATIC IMPORTED)
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
include_directories(${FILAMENT_DIR}/include
..
../../libs/utils/include)
set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/Animator.h
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
${GLTFIO_DIR}/include/gltfio/SimpleViewer.h
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
${GLTFIO_DIR}/src/Animator.cpp
${GLTFIO_DIR}/src/AssetLoader.cpp
${GLTFIO_DIR}/src/DracoCache.cpp
${GLTFIO_DIR}/src/DracoCache.h
${GLTFIO_DIR}/src/DependencyGraph.cpp
${GLTFIO_DIR}/src/DependencyGraph.h
${GLTFIO_DIR}/src/FFilamentAsset.h
${GLTFIO_DIR}/src/FilamentAsset.cpp
${GLTFIO_DIR}/src/FFilamentInstance.h
${GLTFIO_DIR}/src/FilamentInstance.cpp
${GLTFIO_DIR}/src/GltfEnums.h
${GLTFIO_DIR}/src/MaterialProvider.cpp
${GLTFIO_DIR}/src/ResourceLoader.cpp
${GLTFIO_DIR}/src/UbershaderLoader.cpp
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/math.h
${GLTFIO_DIR}/src/upcast.h
${GLTFIO_DIR}/src/Image.cpp
add_library(gltfio-jni-obj OBJECT
src/main/cpp/Animator.cpp
src/main/cpp/AssetLoader.cpp
src/main/cpp/FilamentAsset.cpp
src/main/cpp/FilamentInstance.cpp
src/main/cpp/MaterialProvider.cpp
src/main/cpp/ResourceLoader.cpp)
src/main/cpp/ResourceLoader.cpp
if (NOT DISABLE_GLTFIO_JNI)
${FILAMENT_DIR}/include/gltfio/resources/gltfresources_lite.h
${FILAMENT_DIR}/include/gltfio/resources/gltfresources.h
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
../common/NioUtils.cpp
)
add_library(gltfio-jni SHARED
$<TARGET_OBJECTS:gltfio-jni-obj>
set(GLTFIO_INCLUDE_DIRS
..
${FILAMENT_DIR}/include
${FILAMENT_DIR}/include/gltfio/resources
../../third_party/cgltf
../../third_party/robin-map
../../third_party/hat-trie
../../third_party/stb
../../libs/utils/include
)
src/main/cpp/Gltfio.cpp
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map)
../common/CallbackUtils.cpp
../common/NioUtils.cpp
$<TARGET_OBJECTS:filament-jni-obj>
)
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
# The ordering in the following list is important because CMake does not have dependency information.
target_link_libraries(gltfio-jni
gltfio
filament
backend
filaflat
filabridge
geometry
ibl
utils
log
GLESv3
EGL
android
jnigraphics
gltfio_resources
m
)
if (FILAMENT_SUPPORTS_VULKAN)
target_link_libraries(gltfio-jni bluevk smol-v)
endif()
if(GLTFIO_LITE)
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_LITE=1)
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources_lite)
else()
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources)
# Enable Draco in the non-lite variant of gltfio.
target_link_libraries(gltfio-jni dracodec)
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)
endif()

View File

@@ -1,41 +1,27 @@
apply plugin: 'com.android.library'
android {
buildToolsVersion versions.buildTools
compileSdkVersion versions.compileSdk
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
flavorDimensions "functionality"
productFlavors {
full {
dimension "functionality"
}
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-${versions.targetSdk}".toString())
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filamentPath}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
lite {
dimension "functionality"
externalNativeBuild {
cmake {
arguments.add("-DGLTFIO_LITE=ON")
}
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
// No need to package up the following shared libs, which arise as a side effect of our
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
// "More than one file was found with OS independent path ..."
packagingOptions {
exclude 'lib/*/libfilament-jni.so'
}
}
@@ -49,9 +35,14 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
afterEvaluate { project ->
publishing {
publications {
release(MavenPublication) {
artifactId = POM_ARTIFACT_ID
from components.release
fullRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_FULL
from components.fullRelease
}
liteRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_LITE
from components.liteRelease
}
}
}

View File

@@ -1,3 +1,4 @@
POM_NAME=Filament glTF Loader
POM_ARTIFACT_ID=gltfio-android
POM_ARTIFACT_ID_FULL=gltfio-android
POM_ARTIFACT_ID_LITE=gltfio-android-lite
POM_PACKAGING=aar

View File

@@ -1,4 +1,4 @@
LIBGLTFIO {
global: Java_com_google_android_filament_*; JNI*;
global: Java_com_google_android_filament_*; *gltfio*; JNI*;
local: *;
};

View File

@@ -19,6 +19,7 @@
#include <filament/Engine.h>
#include <utils/EntityManager.h>
#include <utils/NameComponentManager.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/MaterialProvider.h>
@@ -29,23 +30,23 @@ using namespace filament;
using namespace gltfio;
using namespace utils;
extern void registerCallbackUtils(JNIEnv*);
extern void registerNioUtils(JNIEnv*);
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeProvider, jlong nativeEntities) {
Engine* engine = (Engine*) nativeEngine;
MaterialProvider* materials = (MaterialProvider*) nativeProvider;
EntityManager* entities = (EntityManager*) nativeEntities;
return (jlong) AssetLoader::create({engine, materials, nullptr, entities});
NameComponentManager* names = new NameComponentManager(*entities);
return (jlong) AssetLoader::create({engine, materials, names, entities});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*, jclass,
jlong nativeLoader) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
NameComponentManager* names = loader->getNames();
AssetLoader::destroy(&loader);
delete names;
}
extern "C" JNIEXPORT jlong JNICALL
@@ -66,6 +67,27 @@ Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetFromJson(JNIEnv*
buffer.getSize());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateInstancedAsset(JNIEnv* env, jclass,
jlong nativeLoader, jobject javaBuffer, jint remaining, jlongArray instances) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AutoBuffer buffer(env, javaBuffer, remaining);
jsize numInstances = env->GetArrayLength(instances);
using Handle = FilamentInstance*;
Handle* ptrInstances = new Handle[numInstances];
jlong asset = (jlong) loader->createInstancedAsset((const uint8_t *) buffer.getData(),
buffer.getSize(), ptrInstances, numInstances);
if (asset) {
jlong* longInstances = env->GetLongArrayElements(instances, nullptr);
for (jsize i = 0; i < numInstances; i++) {
longInstances[i] = (jlong) ptrInstances[i];
}
env->ReleaseLongArrayElements(instances, longInstances, 0);
}
delete[] ptrInstances;
return asset;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nEnableDiagnostics(JNIEnv*, jclass,
jlong nativeLoader, jboolean enable) {
@@ -76,7 +98,7 @@ Java_com_google_android_filament_gltfio_AssetLoader_nEnableDiagnostics(JNIEnv*,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAsset(JNIEnv*, jclass,
jlong nativeLoader, jlong nativeAsset) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AssetLoader* loader = (AssetLoader*) nativeLoader;
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
loader->destroyAsset(asset);
}

View File

@@ -29,6 +29,24 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetRoot(JNIEnv*, jclass,
return asset->getRoot().getId();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nPopRenderable(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->popRenderable().getId();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nPopRenderables(JNIEnv* env, jclass,
jlong nativeAsset, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
size_t retval = asset->popRenderables(entities, available);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
return retval;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntityCount(JNIEnv*, jclass,
jlong nativeAsset) {
@@ -40,11 +58,114 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntities(JNIEnv* env, jclass,
jlong nativeAsset, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getEntities(), asset->getEntityCount(), entities);
std::copy_n(asset->getEntities(),
std::min(available, (jsize) asset->getEntityCount()), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT jint
Java_com_google_android_filament_gltfio_FilamentAsset_nGetFirstEntityByName(JNIEnv* env, jclass,
jlong nativeAsset, jstring name) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* cname = env->GetStringUTFChars(name, nullptr);
Entity result = asset->getFirstEntityByName(cname);
env->ReleaseStringUTFChars(name, cname);
return result.getId();
}
extern "C" JNIEXPORT jint
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntitiesByName(JNIEnv* env, jclass,
jlong nativeAsset, jstring name, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* cname = env->GetStringUTFChars(name, nullptr);
size_t numEntities = asset->getEntitiesByName(cname, nullptr, 0);
if (result == nullptr) {
env->ReleaseStringUTFChars(name, cname);
return numEntities;
}
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
numEntities = asset->getEntitiesByName(cname, entities, env->GetArrayLength(result));
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
env->ReleaseStringUTFChars(name, cname);
return numEntities;
}
extern "C" JNIEXPORT jint
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntitiesByPrefix(JNIEnv* env, jclass,
jlong nativeAsset, jstring prefix, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* cprefix = env->GetStringUTFChars(prefix, nullptr);
size_t numEntities = asset->getEntitiesByPrefix(cprefix, nullptr, 0);
if (result == nullptr) {
env->ReleaseStringUTFChars(prefix, cprefix);
return numEntities;
}
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
numEntities = asset->getEntitiesByPrefix(cprefix, entities, env->GetArrayLength(result));
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
env->ReleaseStringUTFChars(prefix, cprefix);
return numEntities;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetLightEntityCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getLightEntityCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetLightEntities(JNIEnv* env, jclass,
jlong nativeAsset, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getLightEntities(),
std::min(available, (jsize) asset->getLightEntityCount()), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetCameraEntities(JNIEnv* env, jclass,
jlong nativeAsset, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getCameraEntities(),
std::min(available, (jsize) asset->getCameraEntityCount()), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetCameraEntityCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getCameraEntityCount();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstanceCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getMaterialInstanceCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstances(JNIEnv* env, jclass,
jlong nativeAsset, jlongArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
jsize count = std::min(available, (jsize) asset->getMaterialInstanceCount());
jlong* dst = env->GetLongArrayElements(result, nullptr);
const MaterialInstance * const* src = asset->getMaterialInstances();
for (jsize i = 0; i < count; i++) {
dst[i] = (jlong) src[i];
}
env->ReleaseLongArrayElements(result, dst, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetBoundingBox(JNIEnv* env, jclass,
jlong nativeAsset, jfloatArray result) {
@@ -65,10 +186,9 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetBoundingBox(JNIEnv* en
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetName(JNIEnv* env, jclass,
jlong nativeAsset, jint entityId) {
uint32_t id = static_cast<uint32_t>(entityId);
Entity* entity = (Entity*) &id;
Entity entity = Entity::import(entityId);
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* val = asset->getName(*entity);
const char* val = asset->getName(entity);
return val ? env->NewStringUTF(val) : nullptr;
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <gltfio/FilamentInstance.h>
#include <algorithm>
using namespace gltfio;
using namespace utils;
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetRoot(JNIEnv*, jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return instance->getRoot().getId();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetEntityCount(JNIEnv*, jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return instance->getEntityCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetEntities(JNIEnv* env, jclass,
jlong nativeInstance, jintArray result) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(instance->getEntities(),
std::min(available, (jsize) instance->getEntityCount()), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetAnimator(JNIEnv* , jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return (jlong) instance->getAnimator();
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include "common/NioUtils.h"
extern void registerCallbackUtils(JNIEnv*);
extern void registerNioUtils(JNIEnv*);
jint JNI_OnLoad(JavaVM* vm, void*) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
registerCallbackUtils(env);
registerNioUtils(env);
return JNI_VERSION_1_6;
}

View File

@@ -35,9 +35,10 @@ static void destroy(void*, size_t, void *userData) {
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateResourceLoader(JNIEnv*, jclass,
jlong nativeEngine) {
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) new ResourceLoader({ engine, utils::Path(), true, true });
return (jlong) new ResourceLoader({ engine, {}, (bool) normalizeSkinningWeights,
(bool) recomputeBoundingBoxes });
}
extern "C" JNIEXPORT void JNICALL
@@ -52,10 +53,21 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAddResourceData(JNIEnv*
jlong nativeLoader, jstring url, jobject javaBuffer, jint remaining) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
AutoBuffer* buffer = new AutoBuffer(env, javaBuffer, remaining);
const char* curl = env->GetStringUTFChars(url, nullptr);
loader->addResourceData(curl,
const char* cstring = env->GetStringUTFChars(url, nullptr);
loader->addResourceData(cstring,
ResourceLoader::BufferDescriptor(buffer->getData(), buffer->getSize(), &destroy,
buffer));
env->ReleaseStringUTFChars(url, cstring);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nHasResourceData(JNIEnv* env, jclass,
jlong nativeLoader, jstring url) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
const char* cstring = env->GetStringUTFChars(url, nullptr);
bool status = loader->hasResourceData(cstring);
env->ReleaseStringUTFChars(url, cstring);
return status;
}
extern "C" JNIEXPORT void JNICALL
@@ -65,3 +77,25 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nLoadResources(JNIEnv*, j
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
loader->loadResources(asset);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncBeginLoad(JNIEnv*, jclass,
jlong nativeLoader, jlong nativeAsset) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return loader->asyncBeginLoad(asset);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncGetLoadProgress(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
return loader->asyncGetLoadProgress();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncUpdateLoad(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncUpdateLoad();
}

View File

@@ -24,7 +24,7 @@ import java.nio.Buffer;
/**
* Updates matrices according to glTF <code>animation</code> and <code>skin</code> definitions.
*
* <p>Animator can be used for two things:
* <p>Animator is owned by <code>FilamentAsset</code> and can be used for two things:
* <ul>
* <li>Updating matrices in <code>TransformManager</code> components according to glTF <code>animation</code> definitions.</li>
* <li>Updating bone matrices in <code>RenderableManager</code> components according to glTF <code>skin</code> definitions.</li>
@@ -52,7 +52,7 @@ public class Animator {
* @see #getAnimationCount
*/
public void applyAnimation(@IntRange(from = 0) int animationIndex, float time) {
nApplyAnimation(mNativeObject, animationIndex, time);
nApplyAnimation(getNativeObject(), animationIndex, time);
}
/**
@@ -63,14 +63,14 @@ public class Animator {
* <p>NOTE: this operation is independent of <code>animation</code>.</p>
*/
public void updateBoneMatrices() {
nUpdateBoneMatrices(mNativeObject);
nUpdateBoneMatrices(getNativeObject());
}
/**
* Returns the number of <code>animation</code> definitions in the glTF asset.
*/
public int getAnimationCount() {
return nGetAnimationCount(mNativeObject);
return nGetAnimationCount(getNativeObject());
}
/**
@@ -81,7 +81,7 @@ public class Animator {
* @see #getAnimationCount
* */
public float getAnimationDuration(@IntRange(from = 0) int animationIndex) {
return nGetAnimationDuration(mNativeObject, animationIndex);
return nGetAnimationDuration(getNativeObject(), animationIndex);
}
/**
@@ -93,7 +93,18 @@ public class Animator {
* @see #getAnimationCount
*/
public String getAnimationName(@IntRange(from = 0) int animationIndex) {
return nGetAnimationName(mNativeObject, animationIndex);
return nGetAnimationName(getNativeObject(), animationIndex);
}
long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Using Animator on destroyed asset");
}
return mNativeObject;
}
void clearNativeObject() {
mNativeObject = 0;
}
private static native void nApplyAnimation(long nativeAnimator, int index, float time);

View File

@@ -47,7 +47,7 @@ import java.nio.Buffer;
*
* assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
*
* filamentAsset = assets.open("models/lucy.gltf").use { input ->
* filamentAsset = assets.open("models/lucy.gltf").use { input -&gt;
* val bytes = ByteArray(input.available())
* input.read(bytes)
* assetLoader.createAssetFromJson(ByteBuffer.wrap(bytes))!!
@@ -77,6 +77,7 @@ import java.nio.Buffer;
*/
public class AssetLoader {
private long mNativeObject;
private Engine mEngine;
/**
* Constructs an <code>AssetLoader </code>that can be used to create and destroy instances of
@@ -97,6 +98,8 @@ public class AssetLoader {
if (mNativeObject == 0) {
throw new IllegalStateException("Unable to parse glTF asset.");
}
mEngine = engine;
}
/**
@@ -113,7 +116,7 @@ public class AssetLoader {
@Nullable
public FilamentAsset createAssetFromBinary(@NonNull Buffer buffer) {
long nativeAsset = nCreateAssetFromBinary(mNativeObject, buffer, buffer.remaining());
return nativeAsset != 0 ? new FilamentAsset(nativeAsset) : null;
return nativeAsset != 0 ? new FilamentAsset(mEngine, nativeAsset) : null;
}
/**
@@ -122,12 +125,37 @@ public class AssetLoader {
@Nullable
public FilamentAsset createAssetFromJson(@NonNull Buffer buffer) {
long nativeAsset = nCreateAssetFromJson(mNativeObject, buffer, buffer.remaining());
return nativeAsset != 0 ? new FilamentAsset(nativeAsset) : null;
return nativeAsset != 0 ? new FilamentAsset(mEngine, nativeAsset) : null;
}
/**
* Consumes the contents of a glTF 2.0 file and produces a primary asset with one or more
* instances.
*
* The given instance array must be sized to the desired number of instances. If successful,
* this method will populate the array with secondary instances whose resources are shared with
* the primary asset.
*/
@Nullable
@SuppressWarnings("unused")
public FilamentAsset createInstancedAsset(@NonNull Buffer buffer,
@NonNull FilamentInstance[] instances) {
long[] nativeInstances = new long[instances.length];
long nativeAsset = nCreateInstancedAsset(mNativeObject, buffer, buffer.remaining(),
nativeInstances);
if (nativeAsset == 0) {
return null;
}
for (int i = 0; i < nativeInstances.length; i++) {
instances[i] = new FilamentInstance(nativeInstances[i]);
}
return new FilamentAsset(mEngine, nativeAsset);
}
/**
* Allows clients to enable diagnostic shading on newly-loaded assets.
*/
@SuppressWarnings("unused")
public void enableDiagnostics(boolean enable) {
nEnableDiagnostics(mNativeObject, enable);
}
@@ -145,6 +173,8 @@ public class AssetLoader {
private static native void nDestroyAssetLoader(long nativeLoader);
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateAssetFromJson(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateInstancedAsset(long nativeLoader, Buffer buffer, int remaining,
long[] nativeInstances);
private static native void nEnableDiagnostics(long nativeLoader, boolean enable);
private static native void nDestroyAsset(long nativeLoader, long nativeAsset);
}

View File

@@ -17,9 +17,12 @@
package com.google.android.filament.gltfio;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.filament.Box;
import com.google.android.filament.Engine;
import com.google.android.filament.Entity;
import com.google.android.filament.MaterialInstance;
/**
* Owns a bundle of Filament objects that have been created by <code>AssetLoader</code>.
@@ -44,8 +47,10 @@ import com.google.android.filament.Entity;
public class FilamentAsset {
private long mNativeObject;
private Animator mAnimator;
private Engine mEngine;
FilamentAsset(long nativeObject) {
FilamentAsset(Engine engine, long nativeObject) {
mEngine = engine;
mNativeObject = nativeObject;
mAnimator = null;
}
@@ -61,11 +66,36 @@ public class FilamentAsset {
return nGetRoot(mNativeObject);
}
/**
* Pops a ready renderable off the queue, or returns 0 if no renderables have become ready.
*
* NOTE: To determine the progress percentage or completion status, please use
* ResourceLoader#asyncGetLoadProgress.
*
* This helper method allows clients to progressively add renderables to the scene as textures
* gradually become ready through asynchronous loading.
*
* See also ResourceLoader#asyncBeginLoad.
*/
public @Entity int popRenderable() {
return nPopRenderable(mNativeObject);
}
/**
* Pops one or more renderables off the queue, or returns the available number.
*
* Returns the number of entities written into the given array. If the given array
* is null, returns the number of available renderables.
*/
public int popRenderables(@Nullable @Entity int[] entities) {
return nPopRenderables(mNativeObject, entities);
}
/**
* Gets the list of entities, one for each glTF node.
*
* <p>All of these have a transform component. Some of the returned entities may also have a
* renderable component.</p>
* renderable or light component.</p>
*/
public @NonNull @Entity int[] getEntities() {
int[] result = new int[nGetEntityCount(mNativeObject)];
@@ -73,6 +103,73 @@ public class FilamentAsset {
return result;
}
/**
* Gets only the entities that have light components.
*/
public @NonNull @Entity int[] getLightEntities() {
int[] result = new int[nGetLightEntityCount(mNativeObject)];
nGetLightEntities(mNativeObject, result);
return result;
}
/**
* Gets only the entities that have camera components.
*
* <p>
* Note about aspect ratios:<br>
*
* gltfio always uses an aspect ratio of 1.0 when setting the projection matrix for perspective
* cameras. gltfio then sets the camera's scaling matrix with the aspect ratio specified in the
* glTF file (if present).<br>
*
* The camera's scaling matrix allows clients to adjust the aspect ratio independently from the
* camera's projection.
* </p>
*
* @see com.google.android.filament.Camera#setScaling
*/
public @NonNull @Entity int[] getCameraEntities() {
int[] result = new int[nGetCameraEntityCount(mNativeObject)];
nGetCameraEntities(mNativeObject, result);
return result;
}
/**
* Returns the first entity with the given name, or 0 if none exist.
*/
public @Entity int getFirstEntityByName(String name) {
return nGetFirstEntityByName(mNativeObject, name);
}
/**
* Gets a list of entities with the given name.
*/
public @NonNull @Entity int[] getEntitiesByName(String name) {
int[] result = new int[nGetEntitiesByName(mNativeObject, name, null)];
nGetEntitiesByName(mNativeObject, name, result);
return result;
}
/**
* Gets a list of entities whose names start with the given prefix.
*/
public @NonNull @Entity int[] getEntitiesByPrefix(String prefix) {
int[] result = new int[nGetEntitiesByPrefix(mNativeObject, prefix, null)];
nGetEntitiesByPrefix(mNativeObject, prefix, result);
return result;
}
public @NonNull MaterialInstance[] getMaterialInstances() {
final int count = nGetMaterialInstanceCount(mNativeObject);
MaterialInstance[] result = new MaterialInstance[count];
long[] natives = new long[count];
nGetMaterialInstances(mNativeObject, natives);
for (int i = 0; i < count; i++) {
result[i] = new MaterialInstance(mEngine, natives[i]);
}
return result;
}
/**
* Gets the bounding box computed from the supplied min / max values in glTF accessors.
*/
@@ -90,10 +187,11 @@ public class FilamentAsset {
}
/**
* Creates or retrieves the <code>Animator</code> for this asset.
* Creates or retrieves the <code>Animator</code> interface for this asset.
*
* <p>When calling this for the first time, this must be called after
* {@link ResourceLoader#loadResources}.</p>
* {@link ResourceLoader#loadResources}. When the asset is destroyed, its
* animator becomes invalid.</p>
*/
public @NonNull Animator getAnimator() {
if (mAnimator != null) {
@@ -123,12 +221,30 @@ public class FilamentAsset {
}
void clearNativeObject() {
if (mAnimator != null) mAnimator.clearNativeObject();
mNativeObject = 0;
}
private static native int nGetRoot(long nativeAsset);
private static native int nPopRenderable(long nativeAsset);
private static native int nPopRenderables(long nativeAsset, int[] result);
private static native int nGetEntityCount(long nativeAsset);
private static native void nGetEntities(long nativeAsset, int[] result);
private static native int nGetFirstEntityByName(long nativeAsset, String name);
private static native int nGetEntitiesByName(long nativeAsset, String name, int[] result);
private static native int nGetEntitiesByPrefix(long nativeAsset, String prefix, int[] result);
private static native int nGetLightEntityCount(long nativeAsset);
private static native void nGetLightEntities(long nativeAsset, int[] result);
private static native int nGetCameraEntityCount(long nativeAsset);
private static native void nGetCameraEntities(long nativeAsset, int[] result);
private static native int nGetMaterialInstanceCount(long nativeAsset);
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
private static native void nGetBoundingBox(long nativeAsset, float[] box);
private static native String nGetName(long nativeAsset, int entity);
private static native long nGetAnimator(long nativeAsset);

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import androidx.annotation.NonNull;
import com.google.android.filament.Entity;
/**
* Provides access to a hierarchy of entities that have been instanced from a glTF asset.
*
* @see FilamentAsset
* @see Animator
* @see AssetLoader
*/
public class FilamentInstance {
private long mNativeObject;
private Animator mAnimator;
FilamentInstance(long nativeObject) {
mNativeObject = nativeObject;
mAnimator = null;
}
@SuppressWarnings("unused")
long getNativeObject() {
return mNativeObject;
}
@SuppressWarnings("unused")
void clearNativeObject() {
mNativeObject = 0;
}
/**
* Gets the transform root for the asset, which has no matching glTF node.
*/
@SuppressWarnings("unused")
public @Entity int getRoot() {
return nGetRoot(mNativeObject);
}
/**
* Gets the list of entities for this instance, one for each glTF node.
*
* <p>All of these have a transform component. Some of the returned entities may also have a
* renderable component.</p>
*/
public @NonNull @Entity int[] getEntities() {
int[] result = new int[nGetEntityCount(mNativeObject)];
nGetEntities(mNativeObject, result);
return result;
}
/**
* Creates or retrieves the <code>Animator</code> for this instance.
*
* <p>When calling this for the first time, this must be called after
* {@link ResourceLoader#loadResources}.</p>
*/
public @NonNull Animator getAnimator() {
if (mAnimator != null) {
return mAnimator;
}
mAnimator = new Animator(nGetAnimator(mNativeObject));
return mAnimator;
}
private static native int nGetRoot(long nativeAsset);
private static native int nGetEntityCount(long nativeAsset);
private static native void nGetEntities(long nativeAsset, int[] result);
private static native long nGetAnimator(long nativeAsset);
}

View File

@@ -16,11 +16,15 @@
package com.google.android.filament.gltfio;
import com.google.android.filament.Filament;
public class Gltfio {
/**
* Initializes the gltfio JNI layer. Must be called before using any gltfio functionality.
*/
public static void init() {
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
Filament.init();
System.loadLibrary("gltfio-jni");
}
}

View File

@@ -17,7 +17,6 @@
package com.google.android.filament.gltfio;
import androidx.annotation.NonNull;
import android.util.Log;
import com.google.android.filament.Engine;
@@ -26,9 +25,10 @@ import java.lang.reflect.Method;
import java.nio.Buffer;
/**
* Uploads vertex buffers and textures to the GPU and computes tangents.
* Prepares and uploads vertex buffers and textures to the GPU.
*
* <p>For a usage example, see the documentation for {@link AssetLoader}.</p>
* <p>For a usage example, see the documentation for {@link AssetLoader}.
* All methods should be called from the main thread.</p>
*
* @see AssetLoader
* @see FilamentAsset
@@ -45,7 +45,23 @@ public class ResourceLoader {
*/
public ResourceLoader(@NonNull Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine);
mNativeObject = nCreateResourceLoader(nativeEngine, false, false);
}
/**
* Constructs a resource loader tied to the given Filament engine.
*
* @param engine the engine that gets passed to all builder methods
* @param normalizeSkinningWeights scale non-conformant skinning weights so they sum to 1
* @param recomputeBoundingBoxes use computed bounding boxes rather than the ones in the asset
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public ResourceLoader(@NonNull Engine engine, boolean normalizeSkinningWeights,
boolean recomputeBoundingBoxes) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
recomputeBoundingBoxes);
}
/**
@@ -58,12 +74,15 @@ public class ResourceLoader {
/**
* Feeds the binary content of an external resource into the loader's URI cache.
*
* <p><code>ResourceLoader</code> does not know how to download external resources on its own
* (for example, external resources might come from a filesystem, a database, or the internet)
* so this method allows clients to download external resources and push them to the loader.</p>
* On some platforms, `ResourceLoader` does not know how to download external resources on its
* own (external resources might come from a filesystem, a database, or the internet) so this
* method allows clients to download external resources and push them to the loader.
*
* <p>When loading GLB files (as opposed to JSON-based glTF files), clients typically do not
* need to call this method.</p>
* Every resource should be passed in before calling [loadResources] or [asyncBeginLoad]. See
* also [FilamentAsset#getResourceUris].
*
* When loading GLB files (as opposed to JSON-based glTF files), clients typically do not
* need to call this method.
*
* @param uri the string path that matches an image URI or buffer URI in the glTF
* @param buffer the binary blob corresponding to the given URI
@@ -75,12 +94,18 @@ public class ResourceLoader {
return this;
}
/**
* Checks if the given resource has already been added to the URI cache.
*/
public boolean hasResourceData(@NonNull String uri) {
return nHasResourceData(mNativeObject, uri);
}
/**
* Iterates through all external buffers and images and creates corresponding Filament objects
* (vertex buffers, textures, etc), which become owned by the asset.
*
* <p>This is the main entry point for <code>ResourceLoader</code>, and only needs to be called
* once.</p>
* NOTE: this is a synchronous API, please see [asyncBeginLoad] as an alternative.
*
* @param asset the Filament asset that contains URI-based resources
* @return self (for daisy chaining)
@@ -91,9 +116,44 @@ public class ResourceLoader {
return this;
}
private static native long nCreateResourceLoader(long nativeEngine);
/**
* Starts an asynchronous resource load.
*
* Returns false if the loading process was unable to start.
*
* This is an alternative to #loadResources and requires periodic calls to #asyncUpdateLoad.
* On multi-threaded systems this creates threads for texture decoding.
*/
public boolean asyncBeginLoad(@NonNull FilamentAsset asset) {
return nAsyncBeginLoad(mNativeObject, asset.getNativeObject());
}
/**
* Gets the status of an asynchronous resource load as a percentage in [0,1].
*/
public float asyncGetLoadProgress() {
return nAsyncGetLoadProgress(mNativeObject);
}
/**
* Updates an asynchronous load by performing any pending work that must take place
* on the main thread.
*
* Clients must periodically call this until #asyncGetLoadProgress returns 100%.
* After progress reaches 100%, calling this is harmless; it just does nothing.
*/
public void asyncUpdateLoad() {
nAsyncUpdateLoad(mNativeObject);
}
private static native long nCreateResourceLoader(long nativeEngine,
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes);
private static native void nDestroyResourceLoader(long nativeLoader);
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
int remaining);
private static native boolean nHasResourceData(long nativeLoader, String url);
private static native void nLoadResources(long nativeLoader, long nativeAsset);
private static native boolean nAsyncBeginLoad(long nativeLoader, long nativeAsset);
private static native float nAsyncGetLoadProgress(long nativeLoader);
private static native void nAsyncUpdateLoad(long nativeLoader);
}

View File

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

View File

@@ -92,6 +92,7 @@ afterEvaluate { project ->
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.source
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
excludes = ['**/*.kt']
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip

16
android/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,16 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# Keep the annotations that proguard needs to process.
-keep class com.google.android.filament.proguard.UsedBy*
# Just because native code accesses members of a class, does not mean that the
# class itself needs to be annotated - only annotate classes that are
# referenced themselves in native code.
-keep @com.google.android.filament.proguard.UsedBy* class * {
<init>();
}
-keepclassmembers class * {
@com.google.android.filament.proguard.UsedBy* *;
}

View File

@@ -41,8 +41,8 @@ Demonstrates how to render into a `TextureView` instead of a `SurfaceView`:
### `material-builder`
Demonstrates how to programatically generate Filament materials, as opposed to compiling them on the
host machine:
Demonstrates how to programmatically generate Filament materials, as opposed to compiling them on
the host machine:
![Material Builder](../../docs/images/samples/sample_image_based_lighting.jpg)
@@ -52,18 +52,20 @@ Demonstrates how to load glTF models and use the camera manipulator:
![glTF Viewer](../../docs/images/samples/sample_gltf_viewer.jpg)
### `gltf-bloom`
Demonstrates how to load glb models and use the RenderTarget API:
![glTF Bloom](../../docs/images/samples/sample_gltf_bloom.jpg)
### `hello-camera`
Demonstrates how to use `Stream` with Android's Camera2 API:
![Hello Camera](../../docs/images/samples/sample_hello_camera.jpg)
### `page-curl`
Pure Java app that demonstrates custom vertex shader animation and two-sided texturing.
Applies the deformation described in "Deforming Pages of Electronic Books" by Hong et al.
Users can drag horizontally to turn the page.
![Page Curl](../../docs/images/samples/sample_page_curl.jpg)
### `stream-test`
Tests the various ways to interact with `Stream` by drawing into an external texture using Canvas.

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