Compare commits

..

432 Commits

Author SHA1 Message Date
prideout
90fdb95429 Update release notes for v1.4.0 2019-09-30 14:55:39 -07:00
Gregory Popovitch
d5c0d11404 Final changes for building with msvc 2019 on Windows (#1681) 2019-09-30 14:18:06 -07:00
Romain Guy
b0d116632c Add the ability to modify clip space coordinates in the vertex shader (#1704)
* Add the ability to modify clip space coordinates in the vertex shader

This introduces MaterialVertexInputs.clipSpaceTransform, a mat4 that
is applied to gl_Position before exiting the vertex stage.

* Address code review comments
2019-09-28 14:15:32 +03:00
Romain Guy
a67d92c2ca Lower limit from API 21 to API 19 (#1701)
* Lower limit from API 21 to API 19

This was requested by an internal application. API 19 is when OpenGL
ES 3.0 support was added so there is no good reason for us to not
support this API level. The only trick is to avoid referring to the
glTexStorage2DMultisample symbol directly as it only exists in 3.1.

* Compile out code we never use

* Use reflection to handle shared EGL contexts pre-API 21.

* Remove comment

* More fixes required to run on API level 19

- dlym() fails for ashmem on API 19, so we only try on API 26+ instead.
- Older emulation for OpenGL ES 3.0 returns error states for valid API calls so we need to clear the GL error bit before we create the GL driver.
- Activity lifecycle changes since API 19 would cause animations to keep running and to reference destroyed objects.
- EGLContext.getNativeHandle() is new in API 21, we need to use reflection on API 19. The new code path uses the class loading trick to avoid a bytecode verification error on API 19.

* Filament now runs properly on API level 19

This commit adds a new api_level() API to libutils which can be used to
query the platform's API level. On Android it works as expected, other
platforms currently return 0.
2019-09-28 14:13:06 +03:00
Philip Rideout
21b208398b Renderable doxygen now uses \see etc. 2019-09-27 15:26:08 -07:00
Philip Rideout
65b3e956df Add doxygen for RenderableManager and NameComponentMananger. 2019-09-27 15:26:08 -07:00
Mathias Agopian
c8d0715b16 SamplerParams is not default-initialized anymore
This is to allow designated aggregate initialization in C++20.
We do this because we have been relying on C99 designated
initialization, which is only supported by clang, other compilers need
c++20 to get a similar functionality. Therefore, we now try to limit
Ourselves to C++20 rules.

This could break existing code, since now SamplerParams needs to be
zero-initialized:

SamplerParams p{};

This is generally not an issue because the intended use is:

doSomethingWithSamplerParams({
      .filterMag = LINEAR,
   });
2019-09-27 13:53:11 -07:00
Mathias Agopian
16d307e543 enforce that quaternions are made of arithmetic types
I believe this might fix some msvc compiler issues too.
2019-09-26 19:05:33 -07:00
Mathias Agopian
5ed07639af workaround an MSVC bug with brace initialization
the C++ standard says:

   if T is a class type with a default constructor that is neither
   user-provided nor deleted (that is, it may be a class with an
   implicitly-defined or defaulted default constructor), the object
   is zero-initialized and then it is default-initialized if it has a
   non-trivial default constructor

Unfortunately, MSVC always calls the default constructor, even if it
is trivial, which breaks constexpr-ness.
To workaround this, we're always zero-initializing TVecN<>

Also removed constexpr from default constructors, since they never can
be constexpr as they're not initializing the vector.
2019-09-26 19:05:33 -07:00
Ben Doherty
e2655e93bc Add test framework for libbackend (#1697) 2019-09-26 12:30:30 -07:00
Philip Rideout
3a20be1d1a gltfio javadoc: add links, fix formatting. 2019-09-26 14:07:13 -04:00
Philip Rideout
8244f8e9cb Add javadoc comments for gltfio. 2019-09-26 14:07:13 -04:00
Romain Guy
c575fd7395 Add new Camera::setExposure(float) API (#1699)
* Add new setExposure(float) API on Camera

This API can be used to set a specific exposure value. For instance:

camera.setExposure(1.0)

Will set the exposure to 1.0 (or ISO 100, apeture 1.0 and shutter speed 1.2s).
This can be useful to match the lighting setup of other engines/tools. Setting
the exposure to 1.0 can for instance be used to treat lights as being unitless
(a directional light could have a strength of 2.0 for instance).

Fixes #1667

* Update release notes

* Fix Java build error

* Fix Web bindings
2019-09-26 20:08:46 +03:00
Philip Rideout
6a67cf0009 Enhance doxygen annotations for gltfio. 2019-09-26 12:18:56 -04:00
Romain Guy
79292481b3 Update documentation 2019-09-26 16:31:55 +03:00
Mathias Agopian
829f341de3 Engine and Camera javadoc (#1698) 2019-09-26 11:53:14 +03:00
Mathias Agopian
b509ef4dad handle scalar op vector directly to help some compilers 2019-09-25 22:39:13 -07:00
Mathias Agopian
422c8d9a64 Make DriverAPI.inc work with MSVC19 2019-09-25 13:52:41 -07:00
Romain Guy
d0b5c5cee8 Update compile & targetSdk from 28 to 29 (#1691) 2019-09-25 22:25:43 +03:00
Romain Guy
9b9548306d Fix Android samples (#1688)
Fixes #1687
2019-09-25 15:48:30 +03:00
Ben Doherty
b28e535540 Combine license file generation functions for MSVC compatability (#1684) 2019-09-24 12:45:38 -07:00
Mathias Agopian
1f7584ace2 Improve backend documentation (#1674)
We need to document the backend headers that are public.
Added documentation for:
- DriverEnums.h
- BufferDescriptor.h
- PixelBufferDescriptor.h

Disabled doxygen for public headers of backend that don't need to
be public for filament's API.

Also improved documentation for:
- LightManager.h
- RenderTarget.h
- TextureSampler.h
2019-09-24 11:18:15 -07:00
Ben Doherty
21512e8228 Update MaterialBuilder header comments for Doxygen (#1673) 2019-09-24 09:11:35 -07:00
Gregory Popovitch
a34903aa33 Update CMake configuration to support building with MSVC 2019-09-23 10:15:34 -07:00
Philip Rideout
4eba402adb Enhance the deprecation note. 2019-09-23 12:31:24 -04:00
Philip Rideout
64c5f5aee7 Deprecate populateTangentQuaternions. 2019-09-23 12:09:37 -04:00
Philip Rideout
1bda37776b Rename KtxUtility namespace to image::ktx. 2019-09-23 12:08:57 -04:00
Philip Rideout
1c5d7d6cc3 Build OpenImageDenoise only in host builds.
Fixes #1672
2019-09-21 14:31:54 -04:00
Mathias Agopian
b81ff060ae Remove HARD Fence public API
This API will be hard to implement on all backends (e.g. Vulkan) and
isn't that useful other than for timing.
2019-09-20 17:57:48 -07:00
Ben Doherty
0cebbfca23 Fix STB linking issues on Windows (#1669) 2019-09-19 15:31:54 -07:00
prideout
b9c7814dfd Remove unused variable. 2019-09-19 11:05:33 -07:00
Philip Rideout
ba9fd6719a FrameGraph, OpenGL, Vulkan: Clean up RenderPassFlags. 2019-09-19 10:52:29 -07:00
Mathias Agopian
f0ad12ce2e Fix matrix operations when using mixed precision
This is a similar fix to the previous vector fix. Commutative 
operations now always return the same type and the operations are
carried out in the precision resulting from following traditional
C++ rules.
2019-09-18 18:22:05 -07:00
Mathias Agopian
21acf53d3f improve vector operations when using implicit conversion
It used to be that operations e.g. like:

 float3{} + double{} would be computed as
 float3{} + float3{double{}} instead of
 float3{} + double3{double{}}

I other words, when an implicit conversion was involved on the right
it would be converted to the left side’s type, possibly losing 
precision.

Another problem was that swiping the operands could produce different
Results, e.g.:

   float3{1} * 5.0 -> float3{5.0f}
   5.0 * float3{1} -> double3{5.0}


This is no longer the case, now both expressions would return a double3. 

Note:

float3 r{};
r *= 5;

Is now equivalent to:

r[0] *= 5;
r[1] *= 5;
r[2] *= 5;

Instead of before:

r[0] *= 5.0f;
r[1] *= 5.0f;
r[2] *= 5.0f;
2019-09-18 18:22:05 -07:00
Mathias Agopian
2f5927d531 Minor code clean-up 2019-09-18 18:22:05 -07:00
Mathias Agopian
cf950a8d6f improve mixed-precision vector operations
We now follow the same rules than for basic types, when performing
mixed-precision operations, e.g.:

  float3 + double3 -> double3
  double3 + float3 -> double3
  dot(float3, double3) -> double

In particular, e.g. swapping the arguments to arithmetic operations
now always yields to the same result type (before, float3 + double3
would not return the same type than double3 + float3).
2019-09-18 18:22:05 -07:00
Philip Rideout
48b73ad998 Vulkan: use a dummy buffer for missing attributes.
To prevent an excess of variants, sometimes our vertex shaders declare
inputs that they never read from. For example, our skin-and-morph
variant might never read from the skinning attribute, but still declares
the input.

This PR is a sister to #1663, which is a fix for #1525.

See also #1279.
2019-09-18 18:14:45 -07:00
Philip Rideout
8fc94f127b Add language bindings for setCullingMode. 2019-09-18 18:12:02 -07:00
Philip Rideout
ce33f42e62 Fix warning in WebGL builds 2019-09-18 18:12:02 -07:00
Philip Rideout
61032e55b5 Update release notes. 2019-09-18 18:12:02 -07:00
Gregory Popovitch
6160d3f51e more changes for building with vs2019/msvc (#1506) 2019-09-18 17:25:22 -07:00
Ben Doherty
5d725f6de9 Fix, allow missing bone indices vertex attribute in Metal driver (#1663) 2019-09-18 16:59:43 -07:00
Romain Guy
020e9e59ed Don't use shallow fetches
This can cause issues with some PRs.
2019-09-18 16:39:40 -07:00
Mathias Agopian
bd777c1e56 Update View.cpp 2019-09-18 15:25:51 -07:00
Mathias Agopian
087b12c802 Fix minor time calculation imprecision
use double for the shader's 'second' time calculation, since 1 billion cannot be stored
in a float accurately.
2019-09-18 15:25:51 -07:00
prideout
42f2642d72 Vulkan: fix layout and miplevel for depth attachments.
We now use GENERAL layout for depth-sampled images in order to support
the SSAO use case of simultaneous binding + sampling.

We may be able to optimize this in the future by enhancing DriverAPI
so that it feeds more information into the render pass.

Fixes #1627, #1649.
2019-09-18 07:41:04 -07:00
Mathias Agopian
9c8d0ed5a1 handle basis inverting transforms (e.g. planar symmetries)
We now inverse the face winding order based on the determinant of
each render primitive world's transform. This prevents front/back faces
to be reversed when using a left-handed basis, after transform.

Fix #1520
2019-09-17 18:38:52 -07:00
Philip Rideout
9fd1705acf Add support for dynamic backface culling.
Inspired by our recent scissor change (#1639) but motivated by gltfio,
which was forced to create a ton of ubershaders (see #1562).

Tested with:

  gltf_viewer -u ../glTF-Sample-Models/2.0/TextureSettingsTest/glTF/TextureSettingsTest.gltf
2019-09-17 08:22:01 -07:00
Mathias Agopian
c981b52832 use enable_if<> instead of static_assert()
This is nicer because this way the methods that don't match don't
even exist. Also make it better when editing code with a C++ aware
ide.

Also use the less verbose std::enable_if_t<>
2019-09-16 18:13:21 -07:00
prideout
d074b6fd1a Remove unused field from backend::SamplerParams. 2019-09-16 16:04:26 -07:00
Mathias Agopian
7da5a25e2f Split OpenGLDriver in two files
We now have OpenGLContext which only tracks the OpenGL state.
It exposes an API very similar to OpenGL and does all the state
tracking. Currently, it doesn't expose non state-changing APIs 
(e.g. draw methods) and only implements the state-changing API we
need (to track the state of).
2019-09-16 15:53:02 -07:00
Romain Guy
b96b8eb787 Encode sRGB images as sRGB, not linear (#1646)
Fixes #1608
2019-09-16 10:51:17 -07:00
Philip Rideout
a25be5ee6e civetweb: do not build unless matdbg is built 2019-09-16 09:43:49 -07:00
Philip Rideout
bf9d1f1967 civetweb: fix warnings 2019-09-16 09:43:49 -07:00
Philip Rideout
561221fdc3 Rename PostProcessVertexInputs uv to normalizedUV. 2019-09-16 09:04:14 -07:00
Philip Rideout
8548afa231 Fix full-screen triangle winding and tex coords.
If you tried removing `culling: none` from any post-process materials,
everything would be fine in GL but Vulkan would be black because
our full-screen triangle was back-facing.

Continue reading only if you thrive in absurd situations.

- Metal and OpenGL define clip space as Y-up whereas Vulkan is Y-down.
- Metal and Vulkan define tex coords as Y-down whereas OpenGL is Y-up.
2019-09-16 09:04:14 -07:00
Philip Rideout
803e695d5c Add "uvToRenderTargetUV" to public shading API.
Fixes #1626.
2019-09-16 09:03:30 -07:00
Philip Rideout
5c58776313 Repair WebGL builds. 2019-09-16 08:39:20 -07:00
Romain Guy
0db39ea08a Add Android presubmit (#1644)
* Add Android presubmit

* Build Android on Linux, macOS targets have NDK 18 only

* Consolidate workflows and jobs

* Try to build Android on macOS

* Fix typo

* Cleanup scripts

* Try NDK side by side if NDK bundle has the wrong version

* Simplify logic

* Fix NDK logic

* Only update the NDK when necessary

* Fix typo

* Update required NDK version

* Favor NDK side-by-side

* Remove support for obsolete NDK bundle, require NDK side-by-side

* Install the NDK side by side when missing
2019-09-13 19:28:55 -07:00
Romain Guy
d76fb5d7e5 Fix matc dependencies and compilation messages 2019-09-13 18:41:38 -07:00
Romain Guy
f37ab8158c Name build jobs (#1643)
* Name build jobs

* Use build/ prefix instead of presubmit prefix

* Rename desktop workflow for consistency

* Forgot a git add...
2019-09-13 17:01:45 -07:00
Romain Guy
33db5acd13 Add web presubmit (#1642)
* Add web presubmit

* Use macOS not Linux
2019-09-13 16:40:57 -07:00
Mathias Agopian
e068204876 scissor is now part of PipelineState
setViewportScissor is gone, which will avoid a runtime error if
called outside of begin/endRenderPass, making the driver API more
robust.
2019-09-13 13:58:29 -07:00
Ben Doherty
d849231caf Remove old post-process shader pipeline (#1631) 2019-09-13 09:29:28 -07:00
Ben Doherty
996bd58fcb Use bitmask enum utility for MaterialBuilder::TargetApi (#1634) 2019-09-13 09:28:58 -07:00
Mathias Agopian
9b70dc5253 Fix linux/android DEBUG builds 2019-09-12 19:43:27 -07:00
Benjamin Doherty
31af9ca80f Automatically download iOS toolchain for Kokoro / GitHub 2019-09-12 17:41:33 -07:00
Benjamin Doherty
08aa2ec4ca Fix, iOS builds still need to work with Kokoro 2019-09-12 17:15:01 -07:00
Ben Doherty
95be2e24ce Fix iOS CI build (#1635) 2019-09-12 16:59:21 -07:00
Mathias Agopian
7b200ec85e make TextureUsage and TargetBufferFlags enum class
This prevents values like NONE or COLOR which are very generic
names to collide with other classic enums. It also forces us to be
specific about what we're doing when converting to bitfields.

Also added a utility to easily enable any enum or enum class to
support binary operation (i.e. Bitmask contract), e.g.:

template<> struct utils::EnableBitMaskOperators<Foo> : public std::true_type{};

gives all binary operators to 'Foo'. Foo must be an enum.

Also added any() and none() convenience to convert an enum to a boolean.
2019-09-12 11:19:54 -07:00
Mathias Agopian
cf1b45c052 Make SamplerParam a C struct
This simplifies its usage at call sites at lot.

The C++ ctor was needed before to create uninitialized objects, which
was needed in SamplerGroup. Instead we use a custom 'static_vector' 
(instead of std::array), this actually makes SamplerGroup's
implementation clearer.

static_vector<> is just a fixed-capacity, fixed-storage dynamic
vector. we currently don't expose it and implement only what we
need.
2019-09-12 11:18:47 -07:00
Ben Doherty
57e7280ac9 Remove post-process uniform / sampler blocks (#1624) 2019-09-11 16:57:48 -07:00
prideout
64d432cb34 PostProcessManager: another Vulkan-related re-ordering.
My fault, I did not catch this while reviewing #1621.
2019-09-11 11:33:43 -07:00
Ben Doherty
fde23c89e2 Use post-process material domain for FXAA (#1621) 2019-09-11 09:35:40 -07:00
Ben Doherty
0e3bc8a443 Only install iOS builds if requested (#1614) 2019-09-11 09:35:01 -07:00
Philip Rideout
88bcd133f2 filamat: add Backend-to-TargetApi utility. 2019-09-11 08:38:47 -07:00
Philip Rideout
2072b67e04 PostProcessManager: repair Vulkan by re-ordering commands.
The suzanne Vulkan demo was asserting because `setViewportScissor` can
only be called within a render pass, which means that
`MaterialInstance::use` can only be called within a render pass.

We probably need a better way to enforce these rules...
2019-09-11 08:38:19 -07:00
Philip Rideout
2a2974580c resgen: remove unused / incorrect constant. 2019-09-10 10:19:37 -07:00
Ben Doherty
65f72a48fb Terminate tonemapping material (#1619) 2019-09-10 10:15:15 -07:00
Philip Rideout
65674c7c51 filagui: disambiguate the resources header. 2019-09-10 09:08:34 -07:00
Philip Rideout
8d1b630b24 resgen: repair wasm builds. 2019-09-10 08:02:35 -07:00
Philip Rideout
1235a66f83 resgen: avoid overwriting the header if nothing changed. 2019-09-10 08:02:35 -07:00
Philip Rideout
411e7f4511 resgen: use extern int instead of #define. 2019-09-10 08:02:35 -07:00
Philip Rideout
cf095cbdd2 filagui: use resgen for the UI material.
This makes building samples faster when combined with PR #1613.
2019-09-10 08:02:23 -07:00
Philip Rideout
394db90ec9 CMake: Use configure_file for licenses.inc
Every time ninja invoked CMake, we were unconditionally regenerating
all of our "licenses.inc" files which caused a ton of re-compiles.

Before the change, building after touching `ubershader.mat.in` took over
a minute, now it takes 20 seconds.

The CMake "file" commands are bad. The CMake documentation says:

    If the file is a build input, use the configure_file() command
    to update the file only when its content changes.
2019-09-10 08:02:12 -07:00
Philip Rideout
72644f1416 mipgen: add --quiet argument.
Note that some encodings like astc will still be noisy due to
third-party code but this works fine for the s3tc encoder.
2019-09-10 08:01:49 -07:00
Philip Rideout
ed2fc0e391 matdbg: opt-in via environment variable. 2019-09-10 08:01:29 -07:00
Ben Doherty
c9f4d983a0 Convert SSAO shaders to use post-process materials (#1610) 2019-09-09 16:41:49 -07:00
Philip Rideout
694db54d9d Minor cleanup. 2019-09-09 11:10:39 -07:00
Philip Rideout
15b663ba0b matdbg client: show inactive variants in gray.
This makes it easier to find the variants that are actually being used.
2019-09-09 11:04:02 -07:00
Philip Rideout
23ee5e276c matdbg server: add query for active programs.
This uses the program cache to determine the set of variants that
are actually being used.
2019-09-09 11:04:02 -07:00
Ben Doherty
7c24a1bbaa Add custom vertex shaders for post-process materials (#1606) 2019-09-09 09:17:35 -07:00
Ben Doherty
32eee2cdf1 Tungsten: upgrade Gradle, fix IBL (#1604) 2019-09-09 09:13:06 -07:00
Ben Doherty
7dbad8928f Ensure GitHub actions build presubmit (#1605) 2019-09-06 19:43:42 -07:00
Philip Rideout
0e81207758 WebGL: add demo for glTF animation.
Fixes #1583.
2019-09-06 16:44:03 -07:00
Philip Rideout
c67266833a gltfio: rename getResourceUrl => getResourceUri 2019-09-06 16:43:53 -07:00
Philip Rideout
d6b0b6ff52 gltfio: expose all resource URI strings.
Some buffers (like animation data) do not contain any vertex data
but web-based clients still need to know about this.

This interface is much simpler than the bindings lists, and in fact
we might remove the binding lists in the future to simplify the API.

Fixes #1593.
2019-09-06 16:43:53 -07:00
Ben Doherty
9d0ad3586d Update tonemapping to use new post-process material domain (#1428) 2019-09-06 15:04:52 -07:00
Philip Rideout
7393d5d98c WebGL: add LightManager getter methods to fix #1599. 2019-09-06 14:12:33 -07:00
Mathias Agopian
7a819a60ae RGB32F is never supported as a render target 2019-09-06 11:09:20 -07:00
Mathias Agopian
c735659592 better handle float rendertargets. fixes #1533
some driver don't support all float buffers as rendertarget, so we
improve the backends (opengl in this PR) to return what it actually
supports and we update the client (filament) to take that into
account when making decisions.
2019-09-06 11:09:20 -07:00
Mathias Agopian
c36745db97 simplify DriverAPI.inc macros a bit further
we now handle zero argument declaration in some cases.
2019-09-06 11:08:59 -07:00
Philip Rideout
a5284af2b8 Use original glTF filename for FlightHelmet. 2019-09-06 10:47:47 -07:00
Philip Rideout
4989c3dc48 Remove unused material. 2019-09-06 10:47:47 -07:00
Philip Rideout
3925b0a8ec matdbg: Add detailed README describing the design. 2019-09-06 08:17:02 -07:00
Mathias Agopian
356610ba1d simplify DriverAPI.inc macros
by using variadic macros we can greatly simplify the macros
definitions for declaring the backend API.

in particular we don't need a macro per number-of-argument, this is
now done automatically.

Unfortunately, we still can't handle zero-argument declarations, so
we keep the _0 variants.
2019-09-05 15:07:25 -07:00
Philip Rideout
9eae72f99d matdbg: allow editing for GLSL shaders.
This performs surgical modification of the IFF chunks rather than
invoking filamat from within matdbg. Low-level direct manipulation
(bypassing optimization passes etc) allows us to diagnose issues with
the shading pipeline.

This CL also adds keystroke bindings to the Monaco editor. You can
press Cmd+S to rebuild the current materials, or use Ctrl+Arrow to
navigate between shader variants and materials.

In a subsequent CL I will add a README that describes how this works in
detail, it will include a list of limitations and a feature wishlist.
2019-09-05 13:03:49 -07:00
Philip Rideout
1d12fc1aaa Fix default IBL in lucy_bloom. 2019-09-04 13:35:34 -07:00
Philip Rideout
f9bd085757 OpenGL: shader errors should not cause termination.
We now check for FILAMENT_ENABLE_MATDBG and simply skip the draw call
when the program is invalid. The initial error message is still dumped
to the console, but we will not terminate or dump an infinite cascade of
error messages.
2019-09-04 13:11:11 -07:00
Philip Rideout
1003926665 Engine: add support for material edits.
This only adds Engine-side support for edits. The debugger client will
be enhanced in another PR. This works by simply clearing the program
cache and swapping out the MaterialParser. Neat!

However, there are some gotchas:

- The DebugServer callback is triggered on another thread so to be safe
  we defer the swap until the subsequent call to getProgram().

- The getProgram() method is const but in reality it can insert entries
  into a mutable cache. This CL makes the constness of it even more
  misleading by applying edits.

- The edit operation will leak the old HwProgram but I feel this is
  fine because simplicity is crucial for injected behavior and this is
  a developer-only feature.
2019-09-04 13:10:44 -07:00
Mathias Agopian
709180932e use Builder.sample() instead Builder.read() for textures
Texture are special resources that can be read in different ways; either as
attachment (read) or sampled (sample), the user must now declare explicitly if she intends
to sample from a texture.

sample() implies read() so there is no need to call both.

This was already the case, as read() used to take a boolean, essentially meaning the same
thing. However, the bool didn't make sense for non-texture resources.

This also simplifies the implementation.
2019-09-04 11:40:59 -07:00
Mathias Agopian
132326f8f2 getDescriptor() needn't be const 2019-09-04 11:40:59 -07:00
Mathias Agopian
92e86de630 No need to specify the sample count for attachments
the framegraph will figure it out automatically from the 
rendertarget sample count. this is done during resolve(), and after
moveResource is taken into account (so this works with imported and
moved resources).
2019-09-04 11:40:59 -07:00
Mathias Agopian
3e8a145fce importRenderTarget() now returns a FrameGraphRenderTargerHandle
This makes the API more symetric/logical.
2019-09-04 11:40:59 -07:00
Mathias Agopian
a5db6a84b6 add name to rendertarget creation 2019-09-04 11:40:59 -07:00
Mathias Agopian
f192b89ef9 sample count for rendertargets doesn't need to be specified
when creating a rendertarget, if the sample count is not specified,
any existing target with the same attachment will match.
this simplifies both the user and implementation.

getRenderTargetDescriptor() now takes a RenderTargetHandle instead
of a texture handle.
2019-09-04 11:40:59 -07:00
Mathias Agopian
637395b075 declaring a rendertarget now returns a FrameGraphRenderTargetHandle
this makes managing render targets more excplicit and simplify the
code a lot. before, render targets were referenced through one of
their attachment.
2019-09-04 11:40:59 -07:00
Philip Rideout
b03172f4a2 Java bindings: fix CUSTOM attribute mismatch.
Fix #1578
2019-09-03 15:49:22 -07:00
Romain Guy
24225315fa Add iOS presubmit (#1589)
* Add iOS presubmit

* Use a separate workflow for iOS
2019-09-03 11:56:32 -07:00
Romain Guy
2bc9256a7a Fix compilation error when DEBUG_COMMAND_STREAM is true (#1588)
Fixes issue #1585
2019-09-03 10:00:11 -07:00
Philip Rideout
264cf020b6 Minor TypeScript annotations fix. 2019-09-03 08:44:16 -07:00
Romain Guy
ceafc7835b Rename CI workflow to Presubmit 2019-08-31 11:53:20 -07:00
Romain Guy
db8d4ee076 Setup Linux for GitHub CI (#1581)
* Setup Linux for GitHub CI

* Pass env var properly
2019-08-30 15:24:29 -07:00
Romain Guy
26f7907b17 Fix punctuation (#1580) 2019-08-30 14:59:25 -07:00
Romain Guy
c35f1e0b29 More fixes 2019-08-30 14:53:02 -07:00
Romain Guy
e2ee00e36e Fix Linux CI on GitHub 2019-08-30 14:50:40 -07:00
Romain Guy
d87f77c41a Don't set $TARGET 2019-08-30 14:45:03 -07:00
Romain Guy
13fcce2d9a Fix workflow 2019-08-30 14:44:47 -07:00
Romain Guy
216761656f Fix CI 2019-08-30 14:38:37 -07:00
Romain Guy
05e9d708ed Update build scripts for workflows 2019-08-30 14:29:44 -07:00
Romain Guy
cc321385cd Run CI on Linux and macOS 2019-08-30 14:29:18 -07:00
Romain Guy
038d39f294 Fix path 2019-08-30 14:07:01 -07:00
Romain Guy
3555a01541 Support for workflows 2019-08-30 14:03:55 -07:00
Romain Guy
5d52266eac Add workflow 2019-08-30 14:03:37 -07:00
Romain Guy
5368756983 Remove workflow 2019-08-30 13:59:34 -07:00
Romain Guy
f74e136f46 Add GitHub Action for CI duty 2019-08-30 12:02:39 -07:00
Romain Guy
040c1c686a Update build script to support GitHub Actions 2019-08-30 12:02:21 -07:00
Philip Rideout
e74c33ce04 Java bindings now define CUSTOM / MORPH attribs.
Fixes #1578.
2019-08-29 17:13:28 -07:00
Philip Rideout
ab24634637 Add matdbg to READMEs. 2019-08-29 10:19:18 -07:00
Philip Rideout
8f3bdc20ba matdbg: add "install" directive.
Fixes #1576.
2019-08-29 10:19:18 -07:00
Romain Guy
74aaaed4db Code cleanup 2019-08-29 09:34:12 -07:00
Philip Rideout
9c64c20ceb matdbg: fail gracefully, emit logs, fewer threads. 2019-08-29 09:13:20 -07:00
Mathias Agopian
b92c748fcc Use allocator Debug policy in more places 2019-08-28 19:06:54 -07:00
Mathias Agopian
844dde4e6d simple allocation debugger
This can be enabled by using the Tracking::Debug policy,
currently this just fills allocation on alloc() and free(),
which is useful to help detect access to uninitialized memory
and use after free.

Now enabled by default in libfilament allocators on debug builds.

This caught uninitialized access in the froxelizer.
2019-08-28 19:06:54 -07:00
Philip Rideout
c0de0ca36d gltfio: fix transforms for nodes with non-uniform scale.
I tested this with the problem model and a couple other models.

This bug is inherited from cgltf_node_transform_local, so I will
upstream the fix. There are two ways to see that the new math is
correct:

1) Look at decomposeMatrix and note that scales belong to rows,
   not columns.

2) Look at the Brandon Jones implementation:
   http://glmatrix.net/docs/mat4.js.html#line1079

Fixes #1519.
2019-08-28 15:31:33 -07:00
Mathias Agopian
ad3bc4a6f7 ran "optimize imports" on all files
This removed a few unneeded imports.
2019-08-28 15:19:50 -07:00
Mathias Agopian
572b2cff57 fix use after free
We were storing pointer to RenderTarget objects that were allocated
in a vector<>, which obviously is not safe.
This didn't cause any issue most of the time because our allocator is
a linear allocator.
2019-08-28 15:19:26 -07:00
Philip Rideout
fb9cf43768 WebGL: fix JPEG decoding.
We've been using STB for a while now and we already include a JPEG
decoder in our wasm bundle. This removes some vestigial code that was
getting in the way.

Fixes #1565.
2019-08-28 13:15:15 -07:00
Philip Rideout
f41db8bb91 gltfio: add lazy loading to ubershader mode. 2019-08-28 13:01:05 -07:00
Philip Rideout
89c8e7c51a gltfio: support doubleSided in ubershader mode.
Fixes #1562
2019-08-28 13:01:05 -07:00
Jordan Rupprecht
0ad21cd47a Avoid undefined behavior when doing pointer calculation.
Performing `base + offset` pointer arithmetic is only allowed when `base` itself is not nullptr. In other words, the compiler is assumed to allow that `base + offset` is always non-null, which an upcoming compiler release will do in this case. The result is that CommandStream.cpp, which calls this in a loop until the result is nullptr, will never terminate (until it runs junk data and crashes).

Avoid this by using intptr_t instead of actual pointers (i.e. char*), which seems to avoid this failure.
2019-08-28 12:13:09 -07:00
Mathias Agopian
7dbf81fe3d FrameGraphPassResources should use typed FrameGraphId<> 2019-08-28 11:43:27 -07:00
Mathias Agopian
3072309574 rename FrameGraphResource to FrameGraphHandle
also FrameFrapheResourceId to FrameGraphId.
2019-08-28 11:43:27 -07:00
Mathias Agopian
573e9220a2 Improve import API and code 2019-08-28 11:43:27 -07:00
Mathias Agopian
e22f02d228 public APIs only use FrameGraphResourceId<> 2019-08-28 11:43:27 -07:00
Mathias Agopian
b620b7efa1 major framegraph overhaul 2019-08-28 11:43:27 -07:00
Philip Rideout
d1593326cb gltfio: support spec-gloss in ubershader mode.
Fixes #1564.
2019-08-28 10:56:56 -07:00
Romain Guy
6a8e6d45b5 Improve materials under white furnace test (#1563)
* Improve materials under white furnace test

Two major changes:
- Mobile target now implements a cheaper variant of the off specular
  peak bias (which moves the reflected vector towards the normal).
  This greatly helps with rough surfaces that may otherwise point
  toward a bright part of the IBL.
- The indirect diffuse love is now properly attenuated to avoid adding
  the energy reflected by the specular layer. This allows dielectrics
  to be correctly energy conserving under a white furnace.
- Tweak the (hacky) clear coat layer attenuation to behave properly
  under a white furnace.

* Use the same reflected vector modification everywhere
2019-08-28 10:39:57 -07:00
Ben Doherty
11336964a1 Add startCapture and stopCapture debug driver methods (#1560) 2019-08-28 10:34:46 -07:00
Mathias Agopian
71e98d54f5 add missing includes 2019-08-27 18:03:45 -07:00
Mathias Agopian
417ba87fcb don't use hard-coded values for Builder::radiance()
Instead we use constexpr expressions of the values,
which makes it much easier to remember where they
come from.
2019-08-26 17:47:28 -07:00
prideout
f71fea4ef5 Update release notes. 2019-08-26 14:16:07 -07:00
prideout
dc062305b9 Bump to 1.3.2 2019-08-26 14:07:14 -07:00
Philip Rideout
bc94269e73 matdbg: fix a warning when building civetweb. 2019-08-26 12:37:38 -07:00
Philip Rideout
876534330a matdbg: add more info to the details panel. 2019-08-23 16:43:16 -07:00
Philip Rideout
2af8ef81b3 matdbg: add required attributes. 2019-08-23 16:43:16 -07:00
Philip Rideout
8da553db58 matdbg: fix active shader highlight. 2019-08-23 16:43:16 -07:00
Philip Rideout
83e9857b30 matdbg: remove bogus hrefs from anchors. 2019-08-23 16:43:16 -07:00
Philip Rideout
088ed2d472 matdbg: make mat list and shader list scrollable. 2019-08-23 16:43:16 -07:00
Ben Doherty
c826b03411 Break driver dependency on Texture.h (#1549) 2019-08-23 16:13:24 -07:00
Benjamin Doherty
f1257994d1 Disable DirIncluder tests 2019-08-23 13:31:20 -07:00
Benjamin Doherty
efb9e005b2 Fix build due to DirIncluder test 2019-08-23 12:40:47 -07:00
Romain Guy
6f30ff31c8 Fix warnings 2019-08-23 11:55:06 -07:00
Romain Guy
d0f38c2d5d Update Gradle, AGP and Kotlin 2019-08-23 11:52:30 -07:00
Ben Doherty
d4943cc70b Add #include preprocessing to filamat and matc (#1541)
* Add #include preprocessing to filamat and matc

* Update RELEASE_NOTES

* Fix RELEASE_NOTES

* Use final instead of virtual / override

* Clarify comments

* Use pure virtual for includer functions

* Use a callback instead of an interface

* Rename Includer.h to IncludeCallback.h

* Update comment
2019-08-23 11:10:36 -07:00
Ben Doherty
9a47ea1ef0 Fix Tungsten build (#1548) 2019-08-23 11:08:27 -07:00
Romain Guy
ac33331fd6 Update documentation to fix typos 2019-08-23 10:58:08 -07:00
Philip Rideout
a65998bbc1 Fix Linux build, hopefully. 2019-08-23 10:16:22 -07:00
Philip Rideout
5120c18977 Update third_party/cgltf to latest. 2019-08-23 09:50:08 -07:00
Philip Rideout
21347eaa88 Fix build break, re-enable DebugServer. 2019-08-23 09:49:57 -07:00
Philip Rideout
a191cc8171 Fix build break. 2019-08-22 17:07:34 -07:00
Philip Rideout
ad3d823fa3 matdbg: Use Variant enum. 2019-08-22 16:12:20 -07:00
Philip Rideout
8d7c00b0d9 matdbg: add DebugServer class.
matdbg is now linked into the Filament Engine in debug config (allowing
live inspection of GLSL / SPIRV) and into the matinfo tool (to support
the --web-server option).

In both cases, the library spins up a small web server that listens to
http://localhost:8080. You can run any Filament app and attach to it.

The web client caches all material information. This allows the user to
close an atttached Filament app, and the web app will continue to
function properly (useful for crash diagnosis). Moreover the user can
launch a second Filament app and the web client will add its materials
to the existing list (useful when comparing two Filament apps).

For now this only supports inspection, not editing. Some of the material
info such as required attributes is not yet displayed but this will be
easy to flesh out in a subsequent PR.
2019-08-22 16:12:20 -07:00
Ben Doherty
99d9ea73ac Fix potential Metal memory leak (#1542) 2019-08-22 14:15:39 -07:00
Philip Rideout
c4b0edbfe3 Introduce matdbg library, simplify matinfo.
This moves some of the matinfo functionality into a library which will
soon have an embedded web server.
2019-08-22 08:11:06 -07:00
Philip Rideout
6d74d31ecd Add civetweb to third_party (MIT).
This is a dependency of our upcoming web-based material debugger. This
CL also includes `tnt/CMakeLists.txt`, which builds a static lib in a
minimal configuration that enables WebSocket support. The entire library
is built from only 4 files:

    ${PUBLIC_HDR_DIR}/CivetServer.h
    ${PUBLIC_HDR_DIR}/civetweb.h
    ${SRC_DIR}/civetweb.c
    ${SRC_DIR}/CivetServer.cpp
2019-08-21 17:45:37 -07:00
Ben Doherty
bd22bed2fb Fix Windows test cases (#1537) 2019-08-20 15:36:22 -07:00
Ben Doherty
f8aa17c245 Preallocate uniform buffers in Metal (#1528)
* Preallocate uniform buffers in Metal

* Allocate empty uniform at draw time

* Remove unnecessary return
2019-08-19 15:37:13 -07:00
Ben Doherty
6ba20f29d4 Fix normal mapping with skinning or morphing in Metal (#1530) 2019-08-16 17:24:01 -07:00
Philip Rideout
95ef8d85db Minor fixup to suzanne Vulkan demo. 2019-08-16 17:04:32 -07:00
Mathias Agopian
eca381a5be Rename fg::Resource to fg::TextureResource 2019-08-15 16:58:58 -07:00
Mathias Agopian
ea47f0bd87 simplify how we determine if a resource is sample-able 2019-08-15 16:58:58 -07:00
Mathias Agopian
b849008ce5 rename useRenderTarget to createRenderTarget 2019-08-15 16:58:58 -07:00
Mathias Agopian
5389ac963f framegraph: useRenderTarget() doesn't set access anymore
access to resources now needs to be done explicitly before calling
useRenderTarget(). This simplifies things and is needed for more
simplifications to come.
2019-08-15 16:58:58 -07:00
Mathias Agopian
0fd16d760a refactor/cleanup of FrameGraph code
this change mostly puts all internal classes into their own file,
making FrameGraph.cpp much smaller and easier to deal with
2019-08-15 16:58:58 -07:00
Philip Rideout
6754e80c75 gltfio: Minor cleanup. 2019-08-15 14:29:07 -07:00
Benjamin Doherty
fb95d8e7a4 debug 2019-08-14 18:13:57 -07:00
Benjamin Doherty
40efd5fd23 More debug 2019-08-14 18:13:57 -07:00
Benjamin Doherty
d440775775 debug 2019-08-14 18:13:57 -07:00
Benjamin Doherty
e1d9f26dbd Try keyserver 2019-08-14 18:13:57 -07:00
Benjamin Doherty
ee048d259f Try to fix broken Linux and Android CI 2019-08-14 18:13:57 -07:00
Philip Rideout
d7e5f2c26b Web: remove more &free callbacks.
It is not safe to take the address of a stdlib function with emscripten,
this causes an intermittent crash in the WebGL backend.
2019-08-14 15:14:49 -07:00
Philip Rideout
c11a61aa15 Web: add setBoolParameter, fixes #1499. 2019-08-14 13:05:17 -07:00
Philip Rideout
b859b57797 matc, matinfo et al: improve diagnostic output
This enhances the exisiting matc option "--debug" so that it includes
debug information in the resulting SPIR-V.

Previously we tied this to the build configuration which isn't very
flexible. Moreover this needs to be orthogonal to shader opts, because
we often need to debug problems that arise from optimization.

This CL also gives meaningful names to the ubershader materials and
fixes up the new matinfo analysis so that it prints the entire SPIRV
chunk that corresponds to each potentially problematic GLSL codeline.

Motivated by #1516.
2019-08-14 13:01:43 -07:00
Mathias Agopian
76cca21c65 most StructureOfArray<> methods cannot be constexpr
This is because we can't create a constexpr SoA in the first place,
and it wouldn't be very useful if we could.

This change ripples into users of SoA.
2019-08-13 18:29:15 -07:00
Philip Rideout
a09c3b154a Fix paths in android glTF demo. 2019-08-13 12:47:08 -07:00
Philip Rideout
2460f9e721 Better Adreno workaround for #1096.
This is an improved workaround for a known limitation with Vulkan
drivers on Android P. The offending SPIR-V sequence was introduced
during shader optimization and can be avoided by using full precision
for certain variables.
2019-08-13 11:36:59 -07:00
Mathias Agopian
d30429e891 make getNativeObject() public
this allows mixed java/native apps to use filament objects on both
sides more easily
2019-08-12 21:56:49 -07:00
Ben Doherty
c23c3d48b2 Remove unusued function (#1508) 2019-08-12 15:17:05 -07:00
Philip Rideout
046809cee0 Use --quiet when invoking cmgen in build. 2019-08-12 14:59:46 -07:00
Philip Rideout
c9750dd633 Fix gradle bug that created junk folder. 2019-08-12 13:41:52 -07:00
Philip Rideout
18a0bd70fb Restore accidental removal of Adreno workaround. 2019-08-12 11:42:16 -07:00
Philip Rideout
38955a91e5 matinfo: fix ordering of analyze-spirv output. 2019-08-12 11:40:36 -07:00
Mathias Agopian
eac2ad7e05 fix some lint warnings in Hash.h 2019-08-12 11:09:24 -07:00
Philip Rideout
5df53f733e Add error message to matinfo. 2019-08-12 10:45:44 -07:00
Romain Guy
50abcf6bfa Don't check for NDK side-by-side if ndk bundle is found 2019-08-12 10:22:06 -07:00
Philip Rideout
4d41b83448 Minor fixups in TypeScript annotations. 2019-08-12 09:13:46 -07:00
Philip Rideout
d2324d253c filamat: when building debug, use verbose SPIR-V. 2019-08-12 09:12:59 -07:00
Philip Rideout
cf9e87a892 matinfo: add SPIR-V analysis functionality
This adds a new option to matinfo that does some very dumb regex-based
analysis on the disassembled SPIR-V, then dumps out transpiled GLSL
that has annotations added to the end of some codelines. For example:

```glsl
float luminance(vec3 linear) // POTENTIAL MIXED PRECISION %49 = OpDot %float %linear %48; relaxed = %49 %linear
{
    return dot(linear, vec3(0.2125999927520751953125, 0.715200006961822509765625, 0.072200000286102294921875));
}
```

The code currently tries to find potential mixed precision but does not
do the right thing yet for pointers and structs. This is just a starting
point to help diagnose problem areas in our generated SPIR-V.
2019-08-12 09:12:59 -07:00
Romain Guy
829db244f2 Add support for side-by-side NDK (#1505) 2019-08-11 17:36:49 -07:00
Gregory Popovitch
772af1e897 More fixes for building with vs2019/msvc (#1500)
* Update Froxelizer.h

Fix this error when building with msvc from vs2019
error C2926:  'filament::details::Froxelizer::FroxelEntry::<unnamed-tag>::offset': a default member initializer is not allowed for a member of an anonymous struct within a union

* Fix some compilation issues with vs2019/msvc

Program.cpp:
1>C:\greg\github\filament\filament\backend\src\Program.cpp(28,42): error C2610:  'filament::backend::Program::Program(void) noexcept': is not a special member function or comparison operator which can be defaulted
1>C:\greg\github\filament\filament\backend\src\Program.cpp(28,42): message :  exception specification does not match the implicitly declared specification.

GLUtils.h: __PRETTY_FUNCTION__ macro is clang specific. Use MSVC equivalent

Color.h: fix warning

* #1493 - inline constructor in definition as requested by @romainguy

* #1493  "move this #define inside the #else below" as requested

* #1493 revert last change which causes compilation failures on other platforms.

provide empty implementation of Program::Program() in Program.cpp

* More fixes for building with vs2019/msvc

* #1500 use consistent macro definition syntax (@bejado)

* #1500 simplify DEBUG_COMMAND macro as requested by @pixelflinger

* #1500 use `{ 0 }` which is accepted by Visual Studio  (` = 0 ` is not accepted)

* #1500 remove incorrect UTILS_RESTRICT alltogether
2019-08-09 16:38:31 -07:00
Romain Guy
52a8f50539 Fix backface issue in lit-cube sample 2019-08-09 16:10:12 -07:00
Mathias Agopian
9f1cadf77a remplace multimap by a vector for the framegraph texture cache
because we don't expect many items in the cache, using a linear
search is not a problem -- multimap generates tons of code 
by comparison.
2019-08-09 15:36:40 -07:00
Mathias Agopian
308935d706 fix framegraph test 2019-08-09 15:36:40 -07:00
Mathias Agopian
67f75f0ecf reformatting 2019-08-09 15:07:12 -07:00
Mathias Agopian
f728776714 better normal transforms
We use the cofactors to transform normals, which preserves its
direction, unlike of the inverse-transpose method.
2019-08-09 15:07:12 -07:00
Mathias Agopian
10259f80f4 Add support for det() and cof()
Respectively computing the determinant and cofactors of a matrix.
2019-08-09 15:07:12 -07:00
Mathias Agopian
c65239aec2 Implement a basic Texture cache for the framegraph
We're only caching textures (not render targets yet), and we're
evicting cache entries older than 30 allocations.

This should cut down on texture allocation / gl calls.

The cache should get in a stable state very quickly (less than half
second).
2019-08-09 15:01:04 -07:00
Philip Rideout
0bd9515b3d Add getWorldOffset() shader API, enhance docs.
This allows advanced shader authors like myself to get coordinates
in the API level world space.

Fixes #1485.
2019-08-09 08:28:28 -07:00
Ben Doherty
442315aaa8 Silence Metal shader compilation warnings (#1496) 2019-08-08 18:07:01 -07:00
Gregory Popovitch
614a7d6de8 Fix some compilation issues with vs2019/msvc (#1493)
* Update Froxelizer.h

Fix this error when building with msvc from vs2019
error C2926:  'filament::details::Froxelizer::FroxelEntry::<unnamed-tag>::offset': a default member initializer is not allowed for a member of an anonymous struct within a union

* Fix some compilation issues with vs2019/msvc

Program.cpp:
1>C:\greg\github\filament\filament\backend\src\Program.cpp(28,42): error C2610:  'filament::backend::Program::Program(void) noexcept': is not a special member function or comparison operator which can be defaulted
1>C:\greg\github\filament\filament\backend\src\Program.cpp(28,42): message :  exception specification does not match the implicitly declared specification.

GLUtils.h: __PRETTY_FUNCTION__ macro is clang specific. Use MSVC equivalent

Color.h: fix warning

* #1493 - inline constructor in definition as requested by @romainguy

* #1493  "move this #define inside the #else below" as requested

* #1493 revert last change which causes compilation failures on other platforms.

provide empty implementation of Program::Program() in Program.cpp
2019-08-08 17:03:26 -07:00
Philip Rideout
d28189c173 Repaired broken npm package. 2019-08-08 13:27:52 -07:00
Ben Doherty
dc75c10014 Update Xcode projects for KTX build step (#1495) 2019-08-08 11:39:13 -07:00
Philip Rideout
91ff1d87eb Replace prebuilt KTX with a build step.
This removes the samples/envs folder and replaces these KTX files with a
build step that is driven by CMake / gradle / bash, depending on
platform.

This makes it easier to use IBL files that are generated by the latest
and greatest version of cmake.
2019-08-08 10:41:13 -07:00
Ben Doherty
6b415273ba Add isTextureFormatMipmappable driver query (#1491) 2019-08-08 09:54:03 -07:00
Philip Rideout
4ce2a03f64 Update release notes before v1.3.1 2019-08-08 09:44:19 -07:00
Philip Rideout
f67a71d849 Fix web build, third attempt. 2019-08-08 09:22:05 -07:00
Gregory Popovitch
55d8d93be9 Update Froxelizer.h (#1489)
Fix this error when building with msvc from vs2019
error C2926:  'filament::details::Froxelizer::FroxelEntry::<unnamed-tag>::offset': a default member initializer is not allowed for a member of an anonymous struct within a union
2019-08-07 17:44:39 -07:00
Romain Guy
5d57dee18d Add API to enable/disable shadows on a light (#1492) 2019-08-07 17:39:33 -07:00
Philip Rideout
1d1a0c16ba Quick fix for web build, second attempt. 2019-08-07 16:11:40 -07:00
Philip Rideout
71e2434717 Fix web builds on Kokoro. 2019-08-07 15:11:00 -07:00
Benjamin Doherty
f876e6165f Assert that Metal textures are created 2019-08-07 09:51:50 -07:00
Benjamin Doherty
54e224e9fa Label Metal command queue 2019-08-07 09:51:50 -07:00
Philip Rideout
8e76259bac Fix web builds on Kokoro. 2019-08-07 07:40:19 -07:00
Mathias Agopian
13224d9c6e laying the foundations for a rendertarget cache
Some drivers have performance issues when repeatedly (once per frame)
allocating and destroying render targets, so we will
re-introduce a cache for that.

this just adds the hooks for the cache.
2019-08-06 18:17:08 -07:00
Philip Rideout
34ef2a871f Stop using compressed IBL's in more places.
We use R11F_G11F_B10F for HDR so we should stop checking for compressed
IBL files.

Also, make the glTF sample on web more consistent with the default
settings used by gltf_viewer on native and use venetian_crossroads
instead of syferfontein.
2019-08-06 16:18:51 -07:00
Philip Rideout
6f143b1b54 Fix wasm by avoiding the "&free" trick.
We should not use the address of a stdlib function for BufferDescriptor
callbacks. With emcc this compiles without warnings or errors, but
produces incorrect code that causes intermittent out-of-memory errors at
run time.
2019-08-06 15:03:48 -07:00
Philip Rideout
46e85804b1 Disable jsdocs to fix Kokoro. 2019-08-06 13:28:49 -07:00
Philip Rideout
0fe8035309 gltfio: allow names to be queried.
Fixes #1425.
2019-08-06 12:54:29 -07:00
Philip Rideout
b3feafe320 Enable shadows in helmet demo. 2019-08-06 11:28:00 -07:00
Philip Rideout
ec623e7c1b Add IndirectLight queries to JavaScript / TypeScript. 2019-08-06 09:14:28 -07:00
Mathias Agopian
a38f2754ce Add children iterators to TransformManager (C++ only) 2019-08-04 23:16:54 -07:00
Mathias Agopian
932d2746f3 fix typo 2019-08-04 23:16:34 -07:00
Mathias Agopian
e176dea383 Add API to extract the color/intensity of the IBL dominant light 2019-08-04 23:16:34 -07:00
Hendrik Wagenaar
8f15964ee6 Use GL_EXTENSION for GL_OES_EGL_image_external_essl3 (#1471)
* Use GL_EXTENSION for GL_OES_EGL_image_external_essl3

A prior change that reworked some code incorrectly attempted to
use the existing EGL extensions to set a GL extension boolean.

Added additional GL extension code.

* Fix typo

* Fix typo
2019-08-01 17:17:36 -07:00
Romain Guy
53a12c3f01 Add flower_road envmap with the sun removed 2019-08-01 16:37:06 -07:00
Romain Guy
2c953b9f08 Add the sun instead of blending it (#1470) 2019-08-01 15:19:18 -07:00
Mathias Agopian
b1cdd5452f API to query the direction of the IBL
Initialized the directional light direction to the
IBL direction in material_sandbox and gltf_viewer.
2019-08-01 12:49:40 -07:00
Hendrik Wagenaar
cb66324095 OpenGL: Avoid unresolves on render pass (#1469)
Avoid enabling scissors when the viewport is the same size as the
buffer. On Adreno devices, running clearWithGeometryPipe adds
three additional unresolves for each bin.
2019-08-01 10:26:27 -07:00
prideout
b16dc443ff Do not bind materials outside of a render pass. (affects GL) 2019-07-31 16:35:55 -07:00
Mathias Agopian
8798d367c5 fix some doxygen comments 2019-07-31 15:47:30 -07:00
prideout
c9921cac3d Vulkan: fix issue with mipmapped render targets.
VkFramebuffer requires its attachments to have only one miplevel each,
but our VulkanRenderTarget wrapper was sharing the VkImageView that
associated with the underlying texture object.

This fixes up VulkanRenderTarget so that it owns a unique VkImageView
that is pinned to a specific miplevel.
2019-07-31 15:18:04 -07:00
prideout
485711f7c6 gltfio now uses FADE when the asset is BLEND.
Fixes #1461
2019-07-31 12:36:11 -07:00
prideout
81df9dd705 Desktop samples should not link Embree.
We now build three gltfio libraries:

 - gltfio_core ....... lightweight library with ubershaders
 - gltfio ............ uses filamat to generate materials at runtime
 - gltfio_pipeline ... depends on path tracer functionality
2019-07-31 12:05:22 -07:00
@roxlu ☾
0faa391470 Copy GLXFBConfig from shared context. (#1456)
* Copy GLXFBConfig from shared context.

* Style fixes
2019-07-31 09:30:45 -07:00
prideout
cd59d6cd23 Fix VulkanDriver query for the DEPTH24 format.
This fixes one of the bugs seen with `gltf-bloom` on Android.

We already dynamically map Filament's DEPTH24 format to either
VK_FORMAT_D32_SFLOAT or VK_FORMAT_X8_D24_UNORM_PACK32, depending on
the platform. Therefore we should return `true` when asked if the
backend supports DEPTH24. Otherwise the client will not be able to
create a depth texture.
2019-07-30 14:32:37 -07:00
prideout
d46ba48293 Build tweaks for Android.
(1) Sometimes (but not always!) gltfio-android was failing to build due
to two missing ANativeWindow functions. Linking in "android" seems to
fix this, and is consistent with libfilament-jni.

(2) Improve our "build.sh -c" utility by clobbering some additional
Android build directories. This is especially useful after
adding "-Pextra_cmake_args=-DFILAMENT_SUPPORTS_VULKAN=ON", otherwise
Gradle will try to use a cached CMake configuration.
2019-07-30 10:53:17 -07:00
Romain Guy
7d84f97dc1 Add function to compute the Fresnel Lazanyi term 2019-07-30 10:38:42 -07:00
Philip Rideout
3263c46355 Add morphing support to gltfio.
Issue #1149, #1417
2019-07-30 10:20:50 -07:00
prideout
44c7d3ac34 Add workaround for Adreno Vulkan shader bug.
Fixes #1096.
2019-07-30 10:20:21 -07:00
prideout
7dad09dbc4 Fix VulkanRenderTarget attachment ref counts.
By design, VulkanRenderTarget has weak references to its attachments and
does not manage any hardware resources. Therefore, when we start
rendering to a particular render target, we need to inform
VulkanDisposer that the command buffer has acquired a reference to the
underlying textures. This prevents the possibility of the texture being
destroyed while still in use.

This fixes #1450 although we should also add a render target pool for
best performance.
2019-07-29 14:39:57 -07:00
prideout
401bc4b486 Fix warning. 2019-07-29 11:10:21 -07:00
Philip Rideout
2b1f9290a4 Fix skinning regression (uninitialized bytes in UBO).
Fix #1440.
2019-07-29 13:37:46 -04:00
Philip Rideout
90c17ccbad Filament now supports GPU vertex morphing.
This works by aliasing CUSTOM0 - CUSTOM7 to morphing attributes, and by
extending our existing skinning variant.

This PR was tested against some upcoming changes to gltfio.

Issue #1149, #1417
2019-07-26 17:53:46 -04:00
Ben Doherty
f8f947addb Handle missing vertex attributes in Metal backend (#1442) 2019-07-26 14:44:34 -07:00
Romain Guy
85449a08fb Give specular-color the ability to compute f82 (or other angles) (#1443) 2019-07-26 08:56:24 -10:00
Ben Doherty
115ce0cb42 Delete empty file 2019-07-25 17:56:56 -07:00
Romain Guy
edc2b49196 Add Mathematica notebook for an improved Fresnel term 2019-07-25 16:28:31 -07:00
Ben Doherty
a47b5c21cf Update SPIRV-Cross (#1439) 2019-07-24 16:26:24 -07:00
Ben Doherty
ada148b819 Add OpenGL scheme to hello-ar (#1437) 2019-07-24 15:49:31 -07:00
Romain Guy
5d5d9af4df Remove trailing semi-colon 2019-07-23 21:20:56 -07:00
Mathias Agopian
064441732e Add support for RGBA buffer formats in Texture::generatePrefilterMipmap 2019-07-23 16:01:57 -07:00
Romain Guy
7b80b31365 Remove unused parameter 2019-07-23 10:04:18 -07:00
Ben Doherty
b439ddc5f4 Implement external images for iOS / OpenGL (#1391) 2019-07-23 09:52:24 -07:00
Ben Doherty
5b9351354a Ensure structs used as Metal state keys have no compiler-generated padding (#1433) 2019-07-23 09:49:00 -07:00
Pixelflinger
9bcf10cf44 fix thread count initialization
if hw thread count was 1, we'd end-up with 32 threads
2019-07-22 13:01:53 -07:00
Ben Doherty
ff72598b7d Update Material class to handle both surface and post-process materials (#1410) 2019-07-19 12:24:18 -07:00
Pixelflinger
79aeaf3250 added an option to turn of pre-filtering in cmgen
When processing very high dynamic range environments, the importance
sampling code falls appart, it becomes a user choice to decide if
prefilter importance sampling is better or worse than just regular
importance sampling -- both are usually bad.

--ibl-no-prefilter gives the user this choice.
2019-07-19 10:57:48 -07:00
Pixelflinger
261dafa924 Fix a possible infinite loop
In the case where we have 2 cores, we would spawn only one thread in
the thread pool. If that thread got to try to steal() from another
thread before the main thread was adopted, it would end-up always
trying to steal from itself and enter an infinite loop.

This seems to happen during windows builds.
2019-07-19 10:56:41 -07:00
Philip Rideout
90792e7032 Fix upper limit on vertex attributes.
This combines two constants into one, and changes it into a value that
is actually correct.  :)

Technically the movement of the CUSTOM attributes will change the layout
qualifier and therefore merits a materials version bump, however custom
attributes were only recently introduced so this seems unnecessary.

Did some quick testing with 3 samples: gltf_viewer, lucy_bloom, and
point_sprites.
2019-07-18 17:10:16 -07:00
Mathias Agopian
6e375b1bba Automatic SH windowing
Clamping is now disabled by default in cmgen, there is a new option
to enable it "--clamp". 

Automatic SH windowing is also enabled by default and can be controled
with the "--sh-window" option. Accepted parameters are "no" to disable
windowing, "auto" for automatic windowing or a number to specify the
cutoff band.

auto windowing only works for 1, 2, and 3 bands.
2019-07-18 17:04:14 -07:00
Mathias Agopian
4d7ab6547c cmgen: tonemap images instead of clamping
Currently we're arbitrarily clamping environments to 16384 because both
the pre-filtering and SH algorithms can't handle very larger dynamic 
ranges.  Instead of clamping, we now tonemap, which is a little bit better.
2019-07-18 17:04:14 -07:00
Mathias Agopian
58b7084c8b make libmath much more constexpr friendly
It turns out that most of libmath couldn't be used in constexpr
expression due to our use of union{}. The C++ standard requires that
all accesses to a union{} in a constexpr expression be the same
element.

Also because libm and cmath are not constexpr some functions such
as length() or normalize() can't be constexpr. The same is true for
anything needing things like sqrt, cos, sin, ceil, floor.

This change mainly does the following:
- replace all accesses to vector elements by operator[]
  (this ensure all of libmath uses the same union element)

- avoid use of std::min / std::max / std::abs

- avoid uninitialized variables, which can't be constexpr

- remove 'constexpr' keyword on functions that can never be

It is now possible to write things like:

    constexpr mat4f I = inverse(
            transpose(mat4f::translation(float3{ 1, 2, 3 }) 
                 * mat4f::scaling(4)));
2019-07-18 16:48:37 -07:00
Philip Rideout
d313fe13fb Add deps to gltfio-android when Vulkan is enabled.
Note that these are SHARED rather than STATIC dependencies.

Issue #1414.
2019-07-17 12:57:55 -07:00
Ben Doherty
4d41c9bde3 Update MaterialBuilder to handle post-process materials correctly (#1408) 2019-07-15 10:56:00 -07:00
Philip Rideout
6c4157767f Restore shadows to helmet web demo. 2019-07-15 09:43:01 -07:00
Ben Doherty
5cceda4155 Pass material domain, variant to ShaderGenerator (#1402) 2019-07-12 13:20:00 -07:00
Philip Rideout
8f45f4ec35 gltfio: Fix skinning offset.
Thanks @iamjinge for the fix.

Fixes #1405.
2019-07-12 09:34:52 -07:00
Mathias Agopian
f3e5b46bf9 highlight negative values in SH debug files 2019-07-11 22:45:49 -07:00
Mathias Agopian
497c544f33 fix sh generation when -d is used
When -d was used, the radiance and irradiance ended-up being
swapped in the final file.

Also rename g_coefficients to g_sh_coefficients.
2019-07-11 22:45:49 -07:00
Mathias Agopian
2e4a825fec clamp correctly when converting to RGB_11_11_10
This avoids artifacts with unclipped HDR environments.
2019-07-11 22:45:49 -07:00
Philip Rideout
244c83a77c gltfio JavaScript: add basePath argument to loadResources.
Fixes #1392
2019-07-11 17:52:02 -07:00
Philip Rideout
41e5bb4f78 Add demo for point sprites and custom attribs. 2019-07-11 14:59:16 -07:00
Philip Rideout
2265eca82d Update cgltf. 2019-07-11 14:52:48 -07:00
Ben Doherty
82c7e4d988 Add new post-process functions (#1400) 2019-07-11 14:06:26 -07:00
Philip Rideout
793198f96a Expose setSampleCount to JavaScript. 2019-07-11 12:18:32 -07:00
Philip Rideout
f139589423 Update WebGL demos and docs on site. 2019-07-11 12:04:43 -07:00
Mathias Agopian
f929b6cee7 New experimental filtering options to cmgen
--sh-window=band, -w band : this low-pass-filters the environment
such that bands above 'band' are zero. This can be used to reduce ringing
when the source environment has high frequencies

--noclamp : turns off clamping before processing the cube map


This is still work in progress.
2019-07-11 11:55:59 -07:00
Pixelflinger
4d6f8c281a fix IndirectLight::radiance()
The conversion factors from radiance to irradiance where wrong.

The bug above was found while refactoring the code to be clearer. Now
the method that computes the coefficients for the shader calls the
regular SH code and applies all the appropriate factors on that.

With this change the options "--sh-shader" and "-sh=3 -i" won't
produce the same result because --sh-shader includes the lambertian
diffuse. "--sh" now always produces actual SH coefficients.
2019-07-11 11:52:33 -07:00
Ben Doherty
943af435aa Handle GL_PROGRAM_POINT_SIZE correctly (#1396) 2019-07-11 10:51:50 -07:00
Ben Doherty
f028af3186 Don't build all variants for Windows CI (#1394) 2019-07-11 10:49:51 -07:00
Ben Doherty
b15abe9e5e Rename post-process generator functions (#1395) 2019-07-11 10:44:46 -07:00
Philip Rideout
5281f2a511 Enumerate all 8 custom vertex attribs. 2019-07-11 09:00:10 -07:00
Philip Rideout
c2c546d671 Add support for custom vertex attributes.
This is a prep step for the upcoming morph feature and does not require
a bump to our material version number.

Stay tuned for a new sample app that demonstrates this feature.
2019-07-11 09:00:10 -07:00
Ben Doherty
6fc10c1dda Fix matc bug when compiling for multiple APIs (#1393) 2019-07-10 17:06:28 -07:00
Ben Doherty
80f3afaac6 Manually define PI to fix MSVC issue (#1388) 2019-07-10 16:23:26 -07:00
Ben Doherty
725c978545 Remove yOffset uniform (#1382) 2019-07-10 15:30:00 -07:00
Philip Rideout
a9091570b7 OpenGL driver: allow point sprites on desktop.
I noticed that point sprites were working on mobile and web but not
desktop.  This is why.  :)
2019-07-10 12:39:01 -07:00
Philip Rideout
4e8dac2680 Re-enable shadows in helmet demo. 2019-07-10 09:13:03 -07:00
Ben Doherty
da81e857a0 Correct spherical harmonics comments (#1375) 2019-07-09 16:16:30 -07:00
Mathias Agopian
111b3320c0 make sure we never execute a job smaller than requested 2019-07-09 16:12:15 -07:00
Mathias Agopian
665703dbd8 parallel_for now creates jobs in reverse order
this is because the JobSystem's queue works as a LIFO, by creating
jobs in reverse (memory) order, we attempt to help streaming to
the d-cache on that threads -- until the point where
jobs are stolen. 

we also execute the last job immediately instead of creating a job
for it -- since we're already in a job.
2019-07-09 16:12:15 -07:00
Pixelflinger
8170ca7cd1 improve JobSystem::parallel_for + minor optimizations
- parallel_for doesn't use recursion anymore to create the "leaf"
jobs, this is now done linearly on N thread (one thread per CPU).
This uses less stack space, and reduces miss-predicted branches.

- remove almost all SYSTRACE calls because they have a huge impact
on things like parallel_for() and are misleading. They can be
enabled again by setting HEAVY_SYSTRACE to true.
2019-07-09 16:12:15 -07:00
Mathias Agopian
2df639133b improvements to JobSystem
- we simplify the waiting code by using only a single
condition variable instead of two.

- wait() now behaves just like a looper, it will process jobs until
the one it's waiting for finishes -- before it could just sit there
(the idea was that the job would finish quickly, but that's not always
the case).

- we also make sure to never call notify_n() when it's not needed.
We track how many waiters we have and use that to decide if we need
to notify().

notify is pretty slow on all architectures, even on linux it's always
a syscall, so it's better to avoid it.

- don't use stand-alone fences, makes things ugly for no real benefit

- refactored the code a bit, hopefully it's more clear.
2019-07-09 16:12:15 -07:00
Mathias Agopian
fc1d39334f separate SpinLock out of Allocator.h 2019-07-09 16:12:15 -07:00
Mathias Agopian
af16e43830 add notify_n(int) to our condition variable
notify_n() wakes up n waiters, this is more fine grained than
notify_one() / notify_all(), and the implementation costs nothing.
2019-07-09 16:12:15 -07:00
Mathias Agopian
801c5b57a5 math::half is an arithmetic type even on msvc 2019-07-09 15:45:18 -07:00
Philip Rideout
19d7a3d21f Stop using DXT5 in web samples for the IBL.
Filament no longer decodes RGBM, so it's better to use a
floating-point format such as R11F_G11F_B10F.
2019-07-09 14:23:14 -07:00
Ben Doherty
6af77db79d Fix Android Toolchain issue on Windows (#1383) 2019-07-09 11:57:29 -07:00
Ben Doherty
efb2f9a1d8 Fix windows build (#1384) 2019-07-09 11:56:36 -07:00
Romain Guy
3b3f52f48c Add Engine::destroy(Engine*) to match other APIs (#1377) 2019-07-08 14:22:13 -07:00
Ben Doherty
ba5b9c733d Add shadow plane to hello-ar iOS sample (#1372) 2019-07-07 21:55:45 -07:00
Philip Rideout
e009dbbf96 Minor updates to the webpack sample. 2019-07-03 15:32:01 -07:00
prideout
073a6c7696 Prepare for a new npm release. 2019-07-03 11:26:49 -07:00
Philip Rideout
b30f6e5332 gltfio: JavaScript friendly error message for glb files. 2019-07-03 10:20:17 -07:00
Philip Rideout
384651e21a gltfio: fix JavaScript utility for glb files. 2019-07-03 10:20:17 -07:00
Philip Rideout
22dcdc770f gltfio: fix issue with bounding box computation.
If the client opts in to "recomputeBoundingBoxes", then we manually
compute a bounding box that ignores the glTF min / max annotations.

This computation was erroneously including the transform of the injected
root node, which is not part of the model.

This could cause a problem when creating the asset, then immediately
positioning it with its injected root node before the ResourceLoader
is done downloading vertex buffers.
2019-07-03 10:20:17 -07:00
Philip Rideout
fd4d6c0d44 Use std::move in MeshAssimp.
Tested this via material_sandbox, seems to be fine.

Fixes #1366.
2019-07-02 14:20:55 -07:00
Philip Rideout
ca5b52b2ce Add JavaScript / TypeScript support for RenderTarget. 2019-07-02 13:26:56 -07:00
Ben Doherty
cc4e9db81b Fix spherical harmonics parsing (#1370) 2019-07-02 12:54:52 -07:00
Ben Doherty
2bfea16459 Update usage of KtxUtility in iOS projects (#1371) 2019-07-02 12:33:55 -07:00
Philip Rideout
927662ea4d Add JNI for KTX, simplify the bloom Android demo. 2019-07-02 11:02:45 -07:00
Ben Doherty
5b2dc1d3de Link against IBL library in iOS projects, update README (#1369) 2019-07-02 10:43:54 -07:00
Ben Doherty
097feb0372 Delete accidentally committed file (#1368) 2019-07-02 09:58:48 -07:00
Romain Guy
9cd2971b65 Fix typo in documentation 2019-07-01 17:58:03 -07:00
Ben Doherty
fb16516480 Post-process materials: add post-process variant enum, split writeChunks function (#1365) 2019-07-01 12:57:41 -10:00
Mathias Agopian
76027cab85 fix a JobSystem bug in waitAndRelease()
We were not checking for jobs to execute during waitAndRelease(), so
this thread would essentially not participate to the work pool.
2019-07-01 14:25:26 -07:00
Mathias Agopian
64c95c615a Fix a theoretical wrapping around issue in WSDQ
The Work-stealing dequeue indices could wrap around after ~2 billion
calls to steal(). This could probably be achieved in a few hours.
By using 64-bits indices, we avoid the problem entirely.
2019-07-01 14:25:26 -07:00
Mathias Agopian
31745f6025 fix benchamrk JobSystem de-initialization
JobSystem's API requires to call emancipate() for each adopt() before
destroying the JobSystem.
2019-07-01 14:25:26 -07:00
Ben Doherty
2a8f04c791 Limit material compilation to supported backends (#1359) 2019-07-01 10:05:00 -10:00
Philip Rideout
3fdecfdefa gltf_viewer should not crash when there is no IBL. 2019-06-28 15:40:43 -07:00
Philip Rideout
26cbef7452 Fix intermittent cmgen crash. 2019-06-28 14:49:40 -07:00
Romain Guy
571a9b1ff3 Update README 2019-06-28 13:52:52 -07:00
Romain Guy
b84117eb92 Update READMEs 2019-06-28 13:51:57 -07:00
Romain Guy
6af0c72d0d Add missing getter in IndirectLight (#1356)
This change also factors a bunch of assert methods in a single place
which should slightly decrease binary size.
2019-06-28 13:38:51 -07:00
Mathias Agopian
12fde30f31 better comments and potential fix for work-stealing dequeue
It's better to use std::memory_order_seq_cst in pop() and
steal() because we rely on ordering of access to
mTop and mBottom members.
2019-06-28 13:08:56 -07:00
Philip Rideout
56c2d6338e Add spherical harmonics parser, reduce code duplication.
This uses strtof rather than stringstream and provides a common location
that can be leveraged by the upcoming JNI bindings.

Note that this new method lives in KtxBundle rather than KtxUtility. The
latter creates Filament textures and therefore does not get built into
libimage.
2019-06-28 11:10:04 -07:00
Romain Guy
10c8ff352d Try with clang 7.0.1 on Windows 2019-06-27 10:52:48 -07:00
Romain Guy
53ea1a00ec Fix warnings 2019-06-27 10:46:52 -07:00
Romain Guy
62a458099a Fix more warnings 2019-06-27 09:56:43 -07:00
Romain Guy
826d52bca2 Fix Windows build and warnings 2019-06-27 09:18:31 -07:00
Romain Guy
299a600377 Add CMake to PATH during install 2019-06-26 19:02:21 -07:00
Romain Guy
a4ebf23baa Update PATH 2019-06-26 18:53:05 -07:00
Romain Guy
d23a703ca5 Echo on again 2019-06-26 18:45:47 -07:00
Romain Guy
2beb9c5588 Don't update PATH 2019-06-26 18:40:43 -07:00
Romain Guy
a7fc4d8fbb Update PATH 2019-06-26 18:28:48 -07:00
Romain Guy
a5dc89b071 Don't use refreshenv 2019-06-26 18:18:16 -07:00
Philip Rideout
2bfec9f4af gltfio: Disable file formats that we do not need.
This only removes 40k but at least it is easy.
2019-06-26 18:15:02 -07:00
Romain Guy
1aa7fac8c2 Remove ci-common 2019-06-26 18:03:58 -07:00
Romain Guy
c01107fd52 Exit from the if statement to see what's going on 2019-06-26 17:55:43 -07:00
Romain Guy
5b27361ef0 Try with LLVM 6 2019-06-26 17:47:41 -07:00
Romain Guy
494ddc10e4 More logging 2019-06-26 17:36:24 -07:00
Mathias Agopian
6151f78d28 Update RELEASE_NOTES.md 2019-06-26 17:29:46 -07:00
Romain Guy
46c67632c7 Add logging to test Windows build 2019-06-26 17:28:33 -07:00
Philip Rideout
3f7cf2f971 Increase epsilon in test_cmgen. 2019-06-26 16:46:57 -07:00
Mathias Agopian
84cc8ff9c8 update release notes 2019-06-26 16:05:30 -07:00
Mathias Agopian
921c2bcd61 mitigate overhead of jobsystem
For jobs with that do very little work, the jobsystem can introduce
a lot of overhead, we mitigate this by:

- don't wake-up worker threads when scheduling several very small jobs,
like when scheduling the per-face jobs. 

- don't wait for per-face jobs to finish -- we only did that to avoid
a copy of the job's data.

- don't use multi-threading at all if the job has too little work. We
evaluate the work using the scanline length and number of samples.
2019-06-26 16:05:30 -07:00
Mathias Agopian
6ea8ed07ed a few libibl optimizations 2019-06-26 16:05:30 -07:00
Mathias Agopian
a5addd2257 convert libibl from double to float
since libibl is now used online, it makes more sense to do all the
math in float instead of double. It doesn't seem to impact quality.
2019-06-26 16:05:30 -07:00
Mathias Agopian
8b1d4ee06a a way to fold mirroring with prefiltering 2019-06-26 16:05:30 -07:00
Mathias Agopian
3e23d9742b fixup: remove code that wasn't supposed to be comited 2019-06-26 16:05:30 -07:00
Romain Guy
847d7dd71a Fix various errors discovered by clang-tidy (#1351)
- Move the static function declared in MaterialVariants.h to the .cpp
- Fix several use-after-move that were horribly wrong
2019-06-26 15:25:58 -07:00
Philip Rideout
10dc3a24e8 Add Kotlin sample for gltfio and custom render targets. 2019-06-26 13:55:23 -07:00
Romain Guy
c6c1cfef3c Small cleanups 2019-06-26 12:43:37 -07:00
Romain Guy
cc8a2f736b Fix progress bars display in cmgen 2019-06-26 12:43:37 -07:00
Philip Rideout
7fcd3e1a4f Java clients can now get material instances from renderables.
Discussed this feature with Mathias, we decided to create
MaterialInstance Java wrappers on the fly, and create Material Java
wrappers lazily. This is simple and avoids caching the wrapper objects,
which might otherwise lead to complexity and bugs.

Note that gltfio creates material instances behind the scenes, so this
feature is particularly useful for gltfio clients.
2019-06-25 19:47:49 -07:00
Philip Rideout
481fe5a087 Fix build break of gltfio-android. 2019-06-25 16:31:30 -07:00
Philip Rideout
2d690ac585 Add View::getRenderTarget to JNI. 2019-06-25 16:31:25 -07:00
Philip Rideout
a118299cfb Fix JNI for parameter arrays in MaterialInstance.
Previously we used the <T=float> template instantiation of setParameter
when the client specified FLOAT4. This resulted in the lower layer
adding needless padding, thus causing a buffer overflow.

Moreover the JNI code for this was somewhat cryptic because it casted an
enum value to an int, then added 1 to compute the size. We now use
a switch statement to improve readability.

This issue was discovered (and the fix was verified) with the upcoming
Android port of the bloom demo.
2019-06-25 15:32:30 -07:00
Mathias Agopian
bc01475920 optimize libibl for smaller workloads
We now never process mirroring or mipmaping with multithreading
it's just not worth it given the overhead of the jobsystem.

We also require 64 lines per job, below that, we only multithread per
face (6 threads). This should probably depends on the sample count,
but we don't have this facility yet.

Special case downsampling for mipmaping.

This alone improves performance by 2x for small cubemaps (e.g. 16x16).
2019-06-25 15:08:15 -07:00
Mathias Agopian
56e9d8eda5 Utility to prefilter an environment at runtime
This adds a utility function on IndirectLight populate the reflection
map from an environment at runtime. This performs some processing
similar to cmgen, albeit at a reduced quality.
2019-06-25 15:08:15 -07:00
Mathias Agopian
902e7021fd libibl doesn't use its own JobSystem instance 2019-06-25 15:08:15 -07:00
Adrian Perez
1773c42398 Comment fixes (#1346) 2019-06-25 13:42:52 -07:00
Philip Rideout
ae88536f0c Fix GL_INVALID_OPERATION in the default IBL.
In commit d955e73 we changed the default IBL from RGBM to RGB, but we
kept its internal format of RGBA8. Since the internal format is not
compatible with the data format, we see GL_INVALID_OPERATION during the
texture upload.

This is a single-pixel black texture, so the format does not really
matter, but this clears up a GL error seen on some platforms.
2019-06-24 13:22:34 -07:00
Philip Rideout
b4d6583901 Fix up WebGL bindings after RGBM removal. 2019-06-24 13:22:34 -07:00
Philip Rideout
b31e420064 Fix GL_INVALID_OPERATION in the default IBL.
In commit d955e73 we changed the default IBL from RGBM to RGB, but we
kept its internal format of RGBA8. Since the internal format is not
compatible with the data format, we see GL_INVALID_OPERATION during the
texture upload.

This is a single-pixel black texture, so the format does not really
matter, but this clears up a GL error seen on some platforms.
2019-06-24 13:21:45 -07:00
Philip Rideout
e4e439e2bf Fix build break. 2019-06-21 18:48:40 -07:00
Philip Rideout
a79a83d6da gltfio: gracefully error when mesh uses draco. 2019-06-21 16:12:59 -07:00
Philip Rideout
50d4dc6499 Update cgltf. 2019-06-21 14:51:41 -07:00
Philip Rideout
cbc662085e cgltf: expose extension lists 2019-06-21 14:51:41 -07:00
Philip Rideout
02a5541fed gltfio: minor improvements to error handling. 2019-06-21 10:09:57 -07:00
Romain Guy
14248621fe Workaround for a Mali driver bug (#1337)
Fixes #1320
2019-06-21 09:57:50 -07:00
Romain Guy
8c299d7b0b Update documentation to fix #1336 2019-06-21 09:29:49 -07:00
Ben Doherty
57d6bdff1b Allow mutliple API flags in matc (#1327) 2019-06-21 09:27:49 -07:00
Romain Guy
957ec9be60 Use R11G11B10F instead of RGBM in Android sample apps (#1333) 2019-06-20 16:31:17 -07:00
Philip Rideout
76147a7231 gltfio: fix bug with colliding TANGENT buffers.
ResourceLoader was mistakenly assuming that all primitives in the
entire model have TANGENTS in the same slot index.

Fixes #1326.
2019-06-20 16:29:22 -07:00
Philip Rideout
eff3d1a09b gltfio: show warning for missing normals. 2019-06-20 16:29:22 -07:00
Mathias Agopian
5f6d7a279c fix some warnings 2019-06-20 16:19:02 -07:00
Mathias Agopian
9bce361b3e Remove RGBM support entirely from filament.
⚠️ this break c++ and java source compatibility
2019-06-20 16:17:27 -07:00
Mathias Agopian
925e414e7b fix cmgen test 2019-06-20 15:19:59 -07:00
Mathias Agopian
aeec6f2df5 skygen handles rgb_11_11_10 2019-06-20 14:36:37 -07:00
Mathias Agopian
9358650bd4 remove generated test ibls
we're not using them in the build and they can easily get out of date.
2019-06-20 14:36:37 -07:00
Mathias Agopian
54d44a76a7 fix linux builds 2019-06-20 14:36:37 -07:00
Mathias Agopian
cc22183f20 update samples/envs 2019-06-20 14:36:37 -07:00
Mathias Agopian
2ded1c955f cmgen and filament now support RGB_10_11_11_REV
- RGB_11_11_10 is exported in a RGBA PNG file where the 4 channels are
  used as a uint32 storing a RGB_10_11_11_REV pixel.
  We use the .rgb32f extension, and those PNG files contain garbage 
  when seen in a PNG viewer.

- This is now the default for the -x option.

- compressed KTX files don't encode RGBM, which means they can't
  support HDR, unless an HDR compression scheme is used.
2019-06-20 14:36:37 -07:00
Mathias Agopian
d955e733bf remove RGBM support for skybox and ibl cubemap 2019-06-20 14:36:37 -07:00
Mathias Agopian
99a501f0c3 fix s3tc compression with HDR input
HDR input where producing garbage pixels, instead we saturate.
2019-06-20 14:36:37 -07:00
Ben Doherty
cdb2b47e0f Add material domains boilerplate (#1305) 2019-06-20 08:53:36 -07:00
joetoth
366e20cbe8 Compile gltfio with -fPIC 2019-06-19 19:34:25 -07:00
Philip Rideout
d5179bd9ed Fix JsonishParser to handle parameter arrays. 2019-06-19 15:32:40 -07:00
Philip Rideout
12506784da Expose texture usage flags to Java / Kotlin. 2019-06-19 15:32:26 -07:00
Romain Guy
4fee4d8da2 Don't use clear coat roughness as base roughness if clear coat is 0 (#1323)
This change finds the max of the clear coat and base layer roughness
then lerps the base layer roughness according to the amount of clear
coat.
2019-06-19 15:22:09 -07:00
Romain Guy
b1242163f7 Make CMake 3.10 the minimum version, add LTO option (#1316)
* Make CMake 3.10 the minimum version, add LTO option

* Install a newer CMake on Linux CI builds

* Update LLVM and Cmake on Windows CI

* Update build/windows/ci-common.bat

Co-Authored-By: Ben Doherty <benjdoherty15@gmail.com>

* Update formatting

* Apply suggestions from code review

* Update build/windows/ci-common.bat

* Update CMake

* Switch Android projects back to CMake 3.6
2019-06-19 12:53:03 -07:00
Mathias Agopian
8cd44fb2e8 rework math::half to be more generic
We introduce a templated fp<> class that can represent any float
format and convert to/from float32.
2019-06-19 12:22:01 -07:00
Romain Guy
33a8c9da7e Don't enable specularAO and multiBounceAO by default on mobile (#1319) 2019-06-19 11:04:40 -07:00
Pixelflinger
37facf7f7b fix build breakage on OpenGL ES targets 2019-06-19 01:25:37 -07:00
Mathias Agopian
1d20973363 IBL cubemaps can now be any size.
⚠️ breaks materials

There used to be a constraint that ibl cubemap needed to be
256x256. This constraint is now relaxed. IBL cubemaps can be any size.

We also add 16 float4 of padding to the frameUniform, which brings
its size to 1 KiB, the idea is to prevent more breakages in the
future.
2019-06-18 18:39:06 -07:00
Ben Doherty
0cb08cd114 Add mipmap level selection to Metal render targets (#1310) 2019-06-18 16:13:04 -07:00
Philip Rideout
c97ba45eed Fix several bugs in the gltfio JNI build. 2019-06-18 13:53:45 -07:00
Philip Rideout
74fcc456dc gltfio-android code review changes. 2019-06-18 13:53:45 -07:00
Philip Rideout
b17d606ed2 Introduce JNI bindings for gltfio.
For now this uses gltfio in the ubershader configuration in order
to avoid the filamat dependency. Note that we have not yet done a size
analysis of the `gltfio_core` library.

New Kotlin-based sample app is forthcoming.
2019-06-18 13:53:45 -07:00
Philip Rideout
3e97ac5268 Add Scene::getEntities to JNI. 2019-06-17 15:17:37 -07:00
1806 changed files with 106572 additions and 10865 deletions

57
.github/workflows/presubmit.yml vendored Normal file
View File

@@ -0,0 +1,57 @@
name: Presubmit
on: [pull_request]
jobs:
build-desktop:
name: build-desktop
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v1
- 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
build-android:
name: build-android
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Run build script
run: |
cd build/android && ./build.sh ${TARGET}
env:
TARGET: presubmit
build-ios:
name: build-iOS
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Run build script
run: |
cd build/ios && ./build.sh ${TARGET}
env:
TARGET: presubmit
build-web:
name: build-web
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Run build script
run: |
cd build/web && ./build.sh ${TARGET}
env:
TARGET: presubmit

4
.gitignore vendored
View File

@@ -3,7 +3,7 @@
imgui.ini
cmake-*
ImportExecutables-*.cmake
out
/out*
dist
dist-*
toolchains
@@ -11,3 +11,5 @@ filament/docs/html/**
.vscode
gltf_baker.ini
*tmp*.png
civetweb.txt
/TAGS

View File

@@ -1,7 +1,7 @@
# ==================================================================================================
# CMake
# ==================================================================================================
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.10)
# ==================================================================================================
# Project declaration
@@ -18,6 +18,8 @@ option(USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" O
option(GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
option(ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
# ==================================================================================================
# OS specific
# ==================================================================================================
@@ -25,6 +27,10 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
set(LINUX TRUE)
endif()
if (ANDROID OR WEBGL OR IOS)
set(IS_MOBILE_TARGET TRUE)
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
@@ -44,19 +50,22 @@ if (WIN32)
set(CRT_FLAGS_DEBUG "/MDd")
endif()
# TODO: Figure out why pdb generation messes with incremental compilaton.
# IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
# TODO: Figure out why pdb generation messes with incremental compilaton.
# IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
# In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
# Instead generate debug info directly inside obj files.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
endif()
# In RELEASE, also generate PDBs.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
# In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
# Instead generate debug info directly inside obj files.
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
endif()
# ==================================================================================================
@@ -65,7 +74,7 @@ endif()
# ==================================================================================================
find_package(embree 3.0 QUIET PATHS /usr/lib64/cmake)
if (embree_FOUND AND NOT ANDROID)
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)
@@ -101,13 +110,13 @@ set(TOOLS ${CMAKE_CURRENT_SOURCE_DIR}/tools)
# ==================================================================================================
# Compiler check
# ==================================================================================================
set(MIN_CLANG_VERSION "5.0")
set(MIN_CLANG_VERSION "6.0")
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
if (CMAKE_C_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
message(FATAL_ERROR "Detected C compiler Clang ${CMAKE_C_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
endif()
else()
elseif (NOT MSVC)
message(FATAL_ERROR "Detected C compiler ${CMAKE_C_COMPILER_ID} is unsupported")
endif()
@@ -115,13 +124,31 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
message(FATAL_ERROR "Detected CXX compiler Clang ${CMAKE_CXX_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
endif()
else()
elseif (NOT MSVC)
message(FATAL_ERROR "Detected CXX compiler ${CMAKE_CXX_COMPILER_ID} is unsupported")
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" AND "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
set(CLANG_CL true)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
if ("${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
set(CLANG_CL true)
endif()
elseif (MSVC)
set(MSVC_NATIVE true)
endif()
# ==================================================================================================
# Link time optimizations (LTO)
# ==================================================================================================
if (ENABLE_LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT IPO_SUPPORT)
if (IPO_SUPPORT)
message(STATUS "LTO support is enabled")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
endif()
# ==================================================================================================
@@ -132,7 +159,12 @@ if (WIN32)
set(CXX_STANDARD "/std:c++14")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function")
if (MSVC_NATIVE)
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)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
@@ -153,7 +185,7 @@ if (CYGWIN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
endif()
if (CLANG_CL)
if (CLANG_CL OR 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")
@@ -169,7 +201,7 @@ endif()
# ==================================================================================================
# Release compiler flags
# ==================================================================================================
if (NOT CLANG_CL)
if (NOT CLANG_CL AND NOT MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffunction-sections -fdata-sections")
endif()
@@ -187,7 +219,7 @@ endif()
# -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)
if (NOT CLANG_CL AND NOT MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
@@ -260,6 +292,36 @@ else()
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
endif()
# ==================================================================================================
# Material compilation flags
# ==================================================================================================
# Target system.
if (IS_MOBILE_TARGET)
set(MATC_TARGET mobile)
else()
set(MATC_TARGET desktop)
endif()
set(MATC_API_FLAGS )
# TODO: Add a flag to build Filament without support for OpenGL.
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
if (FILAMENT_SUPPORTS_VULKAN)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a vulkan)
endif()
if (FILAMENT_SUPPORTS_METAL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
endif()
# Only optimize materials in Release mode (so error message lines match the source code)
if (NOT CMAKE_BUILD_TYPE MATCHES Release)
set(MATC_OPT_FLAGS -g)
endif()
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
# ==================================================================================================
# Distribution
# ==================================================================================================
@@ -274,18 +336,23 @@ endif()
# ==================================================================================================
# Functions
# ==================================================================================================
## The MSVC compiler has a limitation on literal string length which is reached when all the
## licenses are concatenated together into a large string... so split them into multiple strings.
function(list_licenses OUTPUT MODULES)
file(WRITE ${OUTPUT} "R\"FILAMENT__(\n")
set(STR_OPENER "R\"FILAMENT__(")
set(STR_CLOSER ")FILAMENT__\"")
set(CONTENT)
set(_MODULES ${MODULES} ${ARGN})
foreach(module ${_MODULES})
set(license_path "../../third_party/${module}/LICENSE")
get_filename_component(fullname "${license_path}" ABSOLUTE)
file(APPEND ${OUTPUT} "License and copyrights for ${module}:\n\n")
file(READ ${license_path} license)
file(APPEND ${OUTPUT} ${license})
file(APPEND ${OUTPUT} "\n\n")
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
file(READ ${license_path} license_long)
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
string(APPEND CONTENT "\n\n")
endforeach()
file(APPEND ${OUTPUT} ")FILAMENT__\"\n")
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
endfunction(list_licenses)
# ==================================================================================================
@@ -373,6 +440,7 @@ add_subdirectory(${EXTERNAL}/meshoptimizer)
add_subdirectory(${EXTERNAL}/cgltf/tnt)
add_subdirectory(${EXTERNAL}/xatlas/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
if (FILAMENT_BUILD_FILAMAT)
# spirv-tools must come before filamat, as filamat relies on the presence of the
@@ -409,14 +477,15 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${LIBRARIES}/bluegl)
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}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
@@ -424,6 +493,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${EXTERNAL}/libz/tnt)
add_subdirectory(${EXTERNAL}/skylight/tnt)
add_subdirectory(${EXTERNAL}/tinyexr/tnt)
add_subdirectory(${TOOLS}/cmgen)
add_subdirectory(${TOOLS}/filamesh)
add_subdirectory(${TOOLS}/glslminifier)
@@ -435,10 +505,11 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/skygen)
add_subdirectory(${TOOLS}/specular-color)
endif()
if (DENOISE_LIBRARY)
add_subdirectory(${EXTERNAL}/OpenImageDenoise/tnt)
if (DENOISE_LIBRARY)
add_subdirectory(${EXTERNAL}/OpenImageDenoise/tnt)
endif()
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)

View File

@@ -43,13 +43,23 @@ 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)
![Chess set](docs/images/samples/chess1.jpg)
![Material 1](docs/images/samples/material_01.jpg)
![Material 2](docs/images/samples/material_02.jpg)
![Material 3](docs/images/samples/material_03.jpg)
![Material 6](docs/images/samples/material_06.jpg)
![Material 8](docs/images/samples/material_08.jpg)
## Applications
Here are a few screenshots of applications that use Filament in production:
### Google Maps AR Navigation
![Google Maps AR Navigation](docs/images/samples/app_gmm_ar_nav.jpg)
### Google Search 3D/AR Viewer on Android
![Google Search 3D/AR Viewer on Android](docs/images/samples/app_google_3d_viewer.jpg)
## Features
### APIs
@@ -86,7 +96,7 @@ Here are a few sample materials rendered with Filament:
- ACES-like tone-mapping
- Temporal dithering
- FXAA, MSAA and specular anti-aliasing
- Dynamic resolution (on Android)
- Dynamic resolution (on Android and iOS)
### Future
@@ -132,6 +142,7 @@ and tools.
- `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.)
@@ -179,9 +190,9 @@ Building the `rays` library (used for light baking) is optional and requires the
To build Filament for Android you must also install the following:
- Android Studio 3.3
- Android Studio 3.5
- Android SDK
- Android NDK 19 or higher
- Android NDK "side-by-side" 20 or higher
### Environment variables
@@ -706,8 +717,9 @@ filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
```
Most samples accept an IBL that must be generated using the `cmgen` tool (`./tools/filamesh/cmgen`
in your build directory). These sample apps expect a path to a directory containing the RGBM files
for the IBL. To generate an IBL simply use this command:
in your build directory). These sample apps expect a path to a directory containing the '.rgb32f'
files for the IBL (which are PNGs containing `R11F_G11F_B10F` data). To generate an IBL simply use
this command:
```
cmgen -x ./ibls/ my_ibl.exr
@@ -723,7 +735,7 @@ pre-filtered environment map (one file per cubemap face and per mip level), the
texture for the skybox and a text file containing the spherical harmonics for indirect diffuse
lighting.
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.5`. The numerical
If you prefer a blurred background, run `cmgen` with this flag: `--extract-blur=0.1`. The numerical
value is the desired roughness between 0 and 1.
## Rendering with Filament

View File

@@ -3,9 +3,62 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## v1.4.0
# Release notes
- API Breakage: Simplified public-facing Fence API.
- Minimum API level on Android is now API 19 instead of API 21.
- Filament can now be built with msvc 2019.
- Added the ability to modify clip space coordinates in the vertex shader.
- Added missing API documentation.
- Improved existing API documentation.
- Added `Camera::setExposure(float)` to directly control the camera's exposure.
- Backface culling can now be toggled on material instances.
- Face direction is now reversed when transforms have negative scale.
- Dielectrics now behave properly under a white furnace (energy preserving and conserving).
- Clear coat roughness now remains in the 0..1 (previously remapped to the 0..0.6 range).
- gltfio: Fixed several limitations with ubershader mode.
- gltfio: Fixed a transforms issue with non-uniform scale.
- webgl: Fixed an issue with JPEG textures.
- Windows: Fix link error in debug builds.
- matdbg: Web server must now be enabled with an environment variable.
- matdbg: Added support for editing GLSL and MSL code.
## v1.3.2
- Added optional web server for real-time inspection of shader code.
- Added basic #include support in material files.
- Fixed potential Metal memory leak.
- Fixed intermittent memory overflow in wasm builds.
- Fix bad normal mapping with skinning.
- Java clients can now call getNativeObject().
## v1.3.1
- Unified Filament Sceneform and npm releases.
- Improved cmgen SH with HDR images.
- IndirectLight can now be queried for dominant direction and color.
- Added support for vertex morphing.
- Introduced custom attributes, accessible from the vertex shader.
- Added Java / Kotlin bindings for KtxLoader.
- Added JavaScript / Typescript bindings for the new `RenderTarget` class.
- Added base path to glTF loadResources method for JavaScript.
- Added support for iOS `CVPixelBuffer` external images with the OpenGL backend.
## sceneform-1.9pr4
- Added `gltf_bloom` Android sample to show gltfio and the `RenderTarget` API.
- Added `getMaterialInstanceAt` to the Java version of RenderableManager.
- Fix JNI bindings for setting values in parameter arrays.
- Added JNI bindings for the gltfio library.
- Fix support for parameter arrays in `.mat` files.
- Added support for `RGB_11_11_10`
- Removed support for `RGBM` (**warning:** source compatibility breakage)
- IBL cubemap can now be of any size
- `Texture::generatePrefilterMipmap` can be used for runtime generation of a reflection cubemap
## sceneform-1.9pr3
- Added `Scene.addEntities()` to the Java / Kotlin bindings.
- Improved robustness in the tangents utility for meshes that have tangents *and* normals.
- Introduced `RenderTarget` API that allows View to reference an offscreen render target.
- Added `lucy_bloom` sample to demonstrate the new `RenderTarget` API.

View File

@@ -33,6 +33,7 @@ List<File> getBinaries(String name, File toolsPath) {
ext.matcFullPath = getBinaries('matc', filamentToolsPath)
ext.cmgenFullPath = getBinaries('cmgen', filamentToolsPath)
ext.filameshFullPath = getBinaries('filamesh', filamentToolsPath)
ext.resgenFullPath = getBinaries('resgen', filamentToolsPath)
class LogOutputStream extends ByteArrayOutputStream {
private final Logger logger;
@@ -115,6 +116,7 @@ class MaterialCompiler extends DefaultTask {
// This task handles incremental builds
class IblGenerator extends DefaultTask {
File cmgenPath
String cmgenArgs = null;
@SuppressWarnings("GroovyUnusedDeclaration")
@InputFile
@@ -154,9 +156,13 @@ class IblGenerator extends DefaultTask {
project.exec {
standardOutput out
if (!cmgenArgs) {
cmgenArgs = '--format=rgb32f --extract-blur=0.08 --extract=' + outputDir.absolutePath
}
cmgenArgs = cmgenArgs + " " + file
errorOutput err
executable "${cmgenPath}"
args('--format=rgbm', '--extract-blur=0.08', "--extract=${outputDir.absolutePath}", file)
args(cmgenArgs.split())
}
}

View File

@@ -9,3 +9,4 @@
/build
/captures
.externalNativeBuild
/.cxx

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.6)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})

View File

@@ -13,7 +13,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
@@ -25,7 +25,7 @@ allprojects {
}
group = "com.google.android.filament"
version = "0.1"
version = "1.3"
apply plugin: 'com.android.library'
@@ -35,10 +35,10 @@ if (project.hasProperty("filament_dist_dir")) {
}
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
@@ -47,7 +47,7 @@ android {
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-21")
arguments.add("-DANDROID_PLATFORM=android-19")
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
cppFlags.add("-std=c++14")

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -98,7 +98,16 @@ public class MaterialBuilder {
UV0, // texture coordinates (float2)
UV1, // texture coordinates (float2)
BONE_INDICES, // indices of 4 bones (uvec4)
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
UNUSED, // reserved for future use
CUSTOM0, // custom or MORPH_POSITION_0
CUSTOM1, // custom or MORPH_POSITION_1
CUSTOM2, // custom or MORPH_POSITION_2
CUSTOM3, // custom or MORPH_POSITION_3
CUSTOM4, // custom or MORPH_TANGENTS_0
CUSTOM5, // custom or MORPH_TANGENTS_1
CUSTOM6, // custom or MORPH_TANGENTS_2
CUSTOM7 // custom or MORPH_TANGENTS_3
}
public enum BlendingMode {
@@ -144,9 +153,16 @@ public class MaterialBuilder {
}
public enum TargetApi {
ALL,
OPENGL,
VULKAN,
OPENGL (0x1),
VULKAN (0x2),
METAL (0x4),
ALL (0x7);
final int number;
private TargetApi(int number) {
this.number = number;
}
}
public enum Optimization {
@@ -347,7 +363,7 @@ public class MaterialBuilder {
@NonNull
public MaterialBuilder targetApi(@NonNull TargetApi api) {
nMaterialBuilderTargetApi(mNativeObject, api.ordinal());
nMaterialBuilderTargetApi(mNativeObject, api.number);
return this;
}

View File

@@ -9,3 +9,4 @@
/build
/captures
.externalNativeBuild
/.cxx

View File

@@ -1,29 +1,113 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="XML">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Google Configuration Checker Style" />
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.6)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
@@ -14,6 +14,10 @@ add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(ibl STATIC IMPORTED)
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
@@ -86,6 +90,7 @@ target_link_libraries(filament-jni
filaflat
filabridge
geometry
ibl
utils
log
GLESv3

View File

@@ -13,7 +13,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
@@ -25,7 +25,7 @@ allprojects {
}
group = "com.google.android.filament"
version = "0.1"
version = "1.3"
apply plugin: 'com.android.library'
@@ -35,13 +35,13 @@ if (project.hasProperty("filament_dist_dir")) {
}
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
// Our minSdkVersion is actually 21, we lie and say 14 here so apps don't have
// 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 < 21.
// ensure they do not initialize Filament on API levels < 19.
minSdkVersion 14
targetSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
@@ -50,7 +50,7 @@ android {
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-21")
arguments.add("-DANDROID_PLATFORM=android-19")
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
cppFlags.add("-std=c++14")

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -154,9 +154,9 @@ Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass,
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateFence(JNIEnv*, jclass,
jlong nativeEngine, jint fenceType) {
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) engine->createFence((Fence::Type) fenceType);
return (jlong) engine->createFence();
}
extern "C" JNIEXPORT void JNICALL

View File

@@ -17,6 +17,9 @@
#include <jni.h>
#include <filament/IndirectLight.h>
#include <filament/Texture.h>
#include <common/NioUtils.h>
#include <common/CallbackUtils.h>
using namespace filament;
@@ -89,8 +92,6 @@ Java_com_google_android_filament_IndirectLight_nRotation(JNIEnv *, jclass, jlong
builder->rotation(filament::math::mat3f{v0, v1, v2, v3, v4, v5, v6, v7, v8});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nSetIntensity(JNIEnv*, jclass,
jlong nativeIndirectLight, jfloat intensity) {
@@ -106,9 +107,38 @@ Java_com_google_android_filament_IndirectLight_nGetIntensity(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nSetRotation(JNIEnv *env, jclass type,
jlong nativeIndirectLight, jfloat v0, jfloat v1, jfloat v2, jfloat v3, jfloat v4, jfloat v5,
jfloat v6, jfloat v7, jfloat v8) {
Java_com_google_android_filament_IndirectLight_nSetRotation(JNIEnv*, jclass,
jlong nativeIndirectLight, jfloat v0, jfloat v1, jfloat v2,
jfloat v3, jfloat v4, jfloat v5, jfloat v6, jfloat v7, jfloat v8) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
indirectLight->setRotation(filament::math::mat3f{v0, v1, v2, v3, v4, v5, v6, v7, v8});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetRotation(JNIEnv* env, jclass,
jlong nativeIndirectLight, jfloatArray outRotation_) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
jfloat *outRotation = env->GetFloatArrayElements(outRotation_, NULL);
*reinterpret_cast<filament::math::mat3f*>(outRotation) = indirectLight->getRotation();
env->ReleaseFloatArrayElements(outRotation_, outRotation, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetDirectionEstimate(JNIEnv* env, jclass,
jlong nativeIndirectLight, jfloatArray outDirection_) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
jfloat *outDirection = env->GetFloatArrayElements(outDirection_, NULL);
*reinterpret_cast<filament::math::float3*>(outDirection) = indirectLight->getDirectionEstimate();
env->ReleaseFloatArrayElements(outDirection_, outDirection, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_IndirectLight_nGetColorEstimate(JNIEnv* env, jclass,
jlong nativeIndirectLight, jfloatArray outColor_, float x, float y, float z) {
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
jfloat *outColor = env->GetFloatArrayElements(outColor_, NULL);
*reinterpret_cast<filament::math::float4*>(outColor) =
indirectLight->getColorEstimate(math::float3{x, y, z});
env->ReleaseFloatArrayElements(outColor_, outColor, 0);
}

View File

@@ -22,48 +22,47 @@ using namespace filament;
using namespace utils;
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nHasComponent(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nHasComponent(JNIEnv*, jclass,
jlong nativeLightManager, jint entity) {
LightManager *lm = (LightManager *) nativeLightManager;
return (jboolean) lm->hasComponent((Entity &) entity);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_LightManager_nGetInstance(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetInstance(JNIEnv*, jclass,
jlong nativeLightManager, jint entity) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getInstance((Entity &) entity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nDestroy(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nDestroy(JNIEnv*, jclass,
jlong nativeLightManager, jint entity) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->destroy((Entity &) entity);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_LightManager_nCreateBuilder(JNIEnv *env, jclass type,
jint lightType) {
Java_com_google_android_filament_LightManager_nCreateBuilder(JNIEnv*, jclass, jint lightType) {
return (jlong) new LightManager::Builder((LightManager::Type) lightType);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nDestroyBuilder(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nDestroyBuilder(JNIEnv*, jclass,
jlong nativeBuilder) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
delete builder;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderCastShadows(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderCastShadows(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enable) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->castShadows(enable);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv *env, jclass type,
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) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
@@ -78,84 +77,84 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv *env,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderCastLight(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderCastLight(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->castLight(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderPosition(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderPosition(JNIEnv*, jclass,
jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->position({x, y, z});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderDirection(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderDirection(JNIEnv*, jclass,
jlong nativeBuilder, jfloat x, jfloat y, jfloat z) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->direction({x, y, z});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderColor(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderColor(JNIEnv*, jclass,
jlong nativeBuilder, jfloat linearR, jfloat linearG, jfloat linearB) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->color({linearR, linearG, linearB});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderIntensity__JF(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderIntensity__JF(JNIEnv*, jclass,
jlong nativeBuilder, jfloat intensity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->intensity(intensity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderIntensity__JFF(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderIntensity__JFF(JNIEnv*, jclass,
jlong nativeBuilder, jfloat watts, jfloat efficiency) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->intensity(watts, efficiency);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderFalloff(JNIEnv*, jclass,
jlong nativeBuilder, jfloat radius) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->falloff(radius);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderSpotLightCone(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderSpotLightCone(JNIEnv*, jclass,
jlong nativeBuilder, jfloat inner, jfloat outer) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->spotLightCone(inner, outer);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderAngularRadius(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderAngularRadius(JNIEnv*, jclass,
jlong nativeBuilder, jfloat angularRadius) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->sunAngularRadius(angularRadius);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderHaloSize(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderHaloSize(JNIEnv*, jclass,
jlong nativeBuilder, jfloat haloSize) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->sunHaloSize(haloSize);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclass,
jlong nativeBuilder, jfloat haloFalloff) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
builder->sunHaloFalloff(haloFalloff);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeEngine, jint entity) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
Engine *engine = (Engine *) nativeEngine;
@@ -170,133 +169,147 @@ Java_com_google_android_filament_LightManager_nGetType(JNIEnv* env,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetPosition(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetPosition(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat x, jfloat y, jfloat z) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setPosition((LightManager::Instance) i, {x, y, z});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nGetPosition(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetPosition(JNIEnv* env, jclass,
jlong nativeLightManager, jint i, jfloatArray out_) {
LightManager *lm = (LightManager *) nativeLightManager;
jfloat *out = env->GetFloatArrayElements(out_, NULL);
jfloat *out = env->GetFloatArrayElements(out_, nullptr);
*reinterpret_cast<filament::math::float3 *>(out) = lm->getPosition((LightManager::Instance) i);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetDirection(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetDirection(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat x, jfloat y, jfloat z) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setDirection((LightManager::Instance) i, {x, y, z});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nGetDirection(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetDirection(JNIEnv *env, jclass,
jlong nativeLightManager, jint i, jfloatArray out_) {
LightManager *lm = (LightManager *) nativeLightManager;
jfloat *out = env->GetFloatArrayElements(out_, NULL);
jfloat *out = env->GetFloatArrayElements(out_, nullptr);
*reinterpret_cast<filament::math::float3 *>(out) = lm->getDirection((LightManager::Instance) i);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetColor(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetColor(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat linearR, jfloat linearG, jfloat linearB) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setColor((LightManager::Instance) i, {linearR, linearG, linearB});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nGetColor(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetColor(JNIEnv *env, jclass,
jlong nativeLightManager, jint i, jfloatArray out_) {
LightManager *lm = (LightManager *) nativeLightManager;
jfloat *out = env->GetFloatArrayElements(out_, NULL);
jfloat *out = env->GetFloatArrayElements(out_, nullptr);
*reinterpret_cast<filament::math::float3 *>(out) = lm->getColor((LightManager::Instance) i);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetIntensity__JIF(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetIntensity__JIF(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat intensity) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setIntensity((LightManager::Instance) i, intensity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetIntensity__JIFF(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetIntensity__JIFF(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat watts, jfloat efficiency) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setIntensity((LightManager::Instance) i, watts, efficiency);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetIntensity(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetIntensity(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getIntensity((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetFalloff(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat falloff) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setFalloff((LightManager::Instance) i, falloff);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetFalloff(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getFalloff((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetSpotLightCone(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetSpotLightCone(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat inner, jfloat outer) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setSpotLightCone((LightManager::Instance) i, inner, outer);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetSunAngularRadius(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetSunAngularRadius(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat angularRadius) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setSunAngularRadius((LightManager::Instance) i, angularRadius);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetSunAngularRadius(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetSunAngularRadius(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getSunAngularRadius((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetSunHaloSize(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetSunHaloSize(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat haloSize) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setSunHaloSize((LightManager::Instance) i, haloSize);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetHaloSize(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetHaloSize(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getSunHaloSize((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetSunHaloFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nSetSunHaloFalloff(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat haloFalloff) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setSunHaloFalloff((LightManager::Instance) i, haloFalloff);
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_LightManager_nGetHaloFalloff(JNIEnv *env, jclass type,
Java_com_google_android_filament_LightManager_nGetHaloFalloff(JNIEnv*, jclass,
jlong nativeLightManager, jint i) {
LightManager *lm = (LightManager *) nativeLightManager;
return lm->getSunHaloFalloff((LightManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nSetShadowCaster(JNIEnv*, jclass,
jlong nativeLightManager, jint i, jfloat shadowCaster) {
LightManager *lm = (LightManager *) nativeLightManager;
lm->setShadowCaster((LightManager::Instance) i, shadowCaster);
}
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);
}

View File

@@ -27,6 +27,30 @@
#include <math/vec4.h>
using namespace filament;
using namespace filament::math;
enum BooleanElement {
BOOL,
BOOL2,
BOOL3,
BOOL4
};
enum IntElement {
INT,
INT2,
INT3,
INT4
};
enum FloatElement {
FLOAT,
FLOAT2,
FLOAT3,
FLOAT4,
MAT3,
MAT4
};
template<typename T>
static void setParameter(JNIEnv* env, jlong nativeMaterialInstance, jstring name_, T v) {
@@ -47,14 +71,14 @@ extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterBool2(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jboolean x, jboolean y) {
setParameter(env, nativeMaterialInstance, name_, filament::math::bool2{x, y});
setParameter(env, nativeMaterialInstance, name_, bool2{x, y});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterBool3(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jboolean x, jboolean y, jboolean z) {
setParameter(env, nativeMaterialInstance, name_, filament::math::bool3{x, y, z});
setParameter(env, nativeMaterialInstance, name_, bool3{x, y, z});
}
extern "C"
@@ -62,7 +86,7 @@ JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterBool4(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_,
jboolean x, jboolean y, jboolean z, jboolean w) {
setParameter(env, nativeMaterialInstance, name_, filament::math::bool4{x, y, z, w});
setParameter(env, nativeMaterialInstance, name_, bool4{x, y, z, w});
}
extern "C"
@@ -76,14 +100,14 @@ extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterInt2(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jint x, jint y) {
setParameter(env, nativeMaterialInstance, name_, filament::math::int2{x, y});
setParameter(env, nativeMaterialInstance, name_, int2{x, y});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterInt3(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jint x, jint y, jint z) {
setParameter(env, nativeMaterialInstance, name_, filament::math::int3{x, y, z});
setParameter(env, nativeMaterialInstance, name_, int3{x, y, z});
}
extern "C"
@@ -91,7 +115,7 @@ JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterInt4(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_,
jint x, jint y, jint z, jint w) {
setParameter(env, nativeMaterialInstance, name_, filament::math::int4{x, y, z, w});
setParameter(env, nativeMaterialInstance, name_, int4{x, y, z, w});
}
extern "C"
@@ -105,14 +129,14 @@ extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterFloat2(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jfloat x, jfloat y) {
setParameter(env, nativeMaterialInstance, name_, filament::math::float2{x, y});
setParameter(env, nativeMaterialInstance, name_, float2{x, y});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterFloat3(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_, jfloat x, jfloat y, jfloat z) {
setParameter(env, nativeMaterialInstance, name_, filament::math::float3{x, y, z});
setParameter(env, nativeMaterialInstance, name_, float3{x, y, z});
}
extern "C"
@@ -120,7 +144,7 @@ JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterFloat4(JNIEnv *env, jclass,
jlong nativeMaterialInstance, jstring name_,
jfloat x, jfloat y, jfloat z, jfloat w) {
setParameter(env, nativeMaterialInstance, name_, filament::math::float4{x, y, z, w});
setParameter(env, nativeMaterialInstance, name_, float4{x, y, z, w});
}
extern "C"
@@ -131,9 +155,26 @@ Java_com_google_android_filament_MaterialInstance_nSetBooleanParameterArray(JNIE
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
const char* name = env->GetStringUTFChars(name_, 0);
size_t size = (size_t) element + 1;
jboolean* v = env->GetBooleanArrayElements(v_, NULL);
instance->setParameter(name, (bool*) (v + offset * size), (size_t) (count * size));
// NOTE: In C++, bool has an implementation-defined size. Here we assume
// it has the same size as jboolean, which is 1 byte.
switch ((BooleanElement) element) {
case BOOL:
instance->setParameter(name, ((const bool*) v) + offset, count);
break;
case BOOL2:
instance->setParameter(name, ((const bool2*) v) + offset, count);
break;
case BOOL3:
instance->setParameter(name, ((const bool3*) v) + offset, count);
break;
case BOOL4:
instance->setParameter(name, ((const bool4*) v) + offset, count);
break;
}
env->ReleaseBooleanArrayElements(v_, v, 0);
env->ReleaseStringUTFChars(name_, name);
@@ -147,10 +188,23 @@ Java_com_google_android_filament_MaterialInstance_nSetIntParameterArray(JNIEnv *
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
const char* name = env->GetStringUTFChars(name_, 0);
size_t size = (size_t) element + 1;
jint* v = env->GetIntArrayElements(v_, NULL);
instance->setParameter(name, reinterpret_cast<int32_t*>(v + offset * size),
(size_t) (count * size));
switch ((IntElement) element) {
case INT:
instance->setParameter(name, ((const int32_t*) v) + offset, count);
break;
case INT2:
instance->setParameter(name, ((const int2*) v) + offset, count);
break;
case INT3:
instance->setParameter(name, ((const int3*) v) + offset, count);
break;
case INT4:
instance->setParameter(name, ((const int4*) v) + offset, count);
break;
}
env->ReleaseIntArrayElements(v_, v, 0);
env->ReleaseStringUTFChars(name_, name);
@@ -164,16 +218,29 @@ Java_com_google_android_filament_MaterialInstance_nSetFloatParameterArray(JNIEnv
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
const char* name = env->GetStringUTFChars(name_, 0);
size_t size = (size_t) element + 1;
if (size == 5) {
// mat3
size = 9;
} else if (size == 6) {
// mat4
size = 16;
}
jfloat* v = env->GetFloatArrayElements(v_, NULL);
instance->setParameter(name, v + offset * size, (size_t) (count * size));
switch ((FloatElement) element) {
case FLOAT:
instance->setParameter(name, ((const float*) v) + offset, count);
break;
case FLOAT2:
instance->setParameter(name, ((const float2*) v) + offset, count);
break;
case FLOAT3:
instance->setParameter(name, ((const float3*) v) + offset, count);
break;
case FLOAT4:
instance->setParameter(name, ((const float4*) v) + offset, count);
break;
case MAT3:
instance->setParameter(name, ((const mat3f*) v) + offset, count);
break;
case MAT4:
instance->setParameter(name, ((const mat4f*) v) + offset, count);
break;
}
env->ReleaseFloatArrayElements(v_, v, 0);
env->ReleaseStringUTFChars(name_, name);
@@ -249,3 +316,11 @@ Java_com_google_android_filament_MaterialInstance_nSetDoubleSided(JNIEnv*,
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDoubleSided(doubleSided);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetCullingMode(JNIEnv*,
jclass, jlong nativeMaterialInstance, jlong cullingMode) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setCullingMode((MaterialInstance::CullingMode) cullingMode);
}

View File

@@ -182,6 +182,12 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv*
return 0;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->morphing(enabled);
}
extern "C" JNIEXPORT jint JNICALL
@@ -218,6 +224,16 @@ Java_com_google_android_filament_RenderableManager_nSetBonesAsQuaternions(JNIEnv
return 0;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetMorphWeights(JNIEnv* env, jclass,
jlong nativeRenderableManager, jint instance, jfloatArray weights) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
jfloat* vec = env->GetFloatArrayElements(weights, NULL);
math::float4 floatvec(vec[0], vec[1], vec[2], vec[3]);
env->ReleaseFloatArrayElements(weights, vec, JNI_ABORT);
rm->setMorphWeights((RenderableManager::Instance)instance, floatvec);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetAxisAlignedBoundingBox(JNIEnv*,
jclass, jlong nativeRenderableManager, jint i, jfloat cx, jfloat cy, jfloat cz,
@@ -299,6 +315,21 @@ Java_com_google_android_filament_RenderableManager_nSetMaterialInstanceAt(JNIEnv
materialInstance);
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_RenderableManager_nGetMaterialInstanceAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (long) rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_RenderableManager_nGetMaterialAt(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
MaterialInstance *mi = rm->getMaterialInstanceAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
return (long) mi->getMaterial();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIJJII(JNIEnv*,
jclass, jlong nativeRenderableManager, jint i, jint primitiveIndex, jint primitiveType,

View File

@@ -44,6 +44,15 @@ Java_com_google_android_filament_Scene_nAddEntity(JNIEnv *env, jclass type, jlon
scene->addEntity((Entity&) entity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Scene_nAddEntities(JNIEnv *env, jclass type, jlong nativeScene,
jintArray entities) {
Scene* scene = (Scene*) nativeScene;
Entity* nativeEntities = (Entity*) env->GetIntArrayElements(entities, nullptr);
scene->addEntities(nativeEntities, env->GetArrayLength(entities));
env->ReleaseIntArrayElements(entities, (jint*) nativeEntities, JNI_ABORT);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Scene_nRemove(JNIEnv *env, jclass type, jlong nativeScene,
jint entity) {

View File

@@ -107,10 +107,10 @@ Java_com_google_android_filament_Texture_nBuilderFormat(JNIEnv*, jclass,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nBuilderRgbm(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enable) {
Java_com_google_android_filament_Texture_nBuilderUsage(JNIEnv*, jclass,
jlong nativeBuilder, jint flags) {
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
builder->rgbm(enable);
builder->usage((Texture::Usage) flags);
}
extern "C" JNIEXPORT jlong JNICALL
@@ -163,12 +163,6 @@ Java_com_google_android_filament_Texture_nGetInternalFormat(JNIEnv*, jclass,
return (jint) texture->getFormat();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nGetRgbm(JNIEnv*, jclass, jlong nativeTexture) {
Texture *texture = (Texture *) nativeTexture;
return static_cast<jboolean>(texture->isRgbm());
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong nativeTexture,
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
@@ -183,7 +177,7 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong na
(Texture::Type) type, (size_t) stride, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
@@ -205,8 +199,7 @@ extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
jint width, jint height, jobject storage, jint remaining,
jint left, jint bottom, jint type, jint alignment,
jint compressedSizeInBytes, jint compressedFormat,
jint, jint, jint, jint, jint compressedSizeInBytes, jint compressedFormat,
jobject handler, jobject runnable) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
@@ -214,7 +207,7 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
size_t sizeInBytes = (size_t) compressedSizeInBytes;
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
@@ -241,7 +234,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, NULL);
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
Texture::FaceOffsets faceOffsets;
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
@@ -250,7 +243,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
(Texture::Type) type, (size_t) stride, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
@@ -277,7 +270,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, NULL);
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
Texture::FaceOffsets faceOffsets;
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
@@ -285,7 +278,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
size_t sizeInBytes = 6 * (size_t) compressedSizeInBytes;
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
@@ -335,6 +328,49 @@ Java_com_google_android_filament_Texture_nIsStreamValidForTexture(JNIEnv*, jclas
return (jboolean) (texture->getTarget() == SamplerType::SAMPLER_EXTERNAL);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint width, jint height,
jobject storage, jint remaining, jint left,
jint top, jint type, jint alignment, jint stride, jint format,
jintArray faceOffsetsInBytes_, jobject handler, jobject runnable, jint sampleCount,
jboolean mirror) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
jint *faceOffsetsInBytes = env->GetIntArrayElements(faceOffsetsInBytes_, nullptr);
Texture::FaceOffsets faceOffsets;
std::copy_n(faceOffsetsInBytes, 6, faceOffsets.offsets);
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
stride = stride ? stride : width;
size_t sizeInBytes = 6 *
Texture::computeTextureDataSize((Texture::Format) format, (Texture::Type) type,
(size_t) stride, (size_t) height, (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) top, (uint32_t) stride,
&JniBufferCallback::invoke, callback);
Texture::PrefilterOptions options;
options.sampleCount = sampleCount;
options.mirror = mirror;
texture->generatePrefilterMipmap(*engine, std::move(desc), faceOffsets, &options);
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// ANDROID SPECIFIC BITS
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -19,8 +19,10 @@ package com.google.android.filament;
import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.opengl.EGLContext;
import android.os.Build;
import android.util.Log;
import android.view.Surface;
import java.lang.reflect.Method;
final class AndroidPlatform extends Platform {
private static final String LOG_TAG = "Filament";
@@ -59,6 +61,20 @@ final class AndroidPlatform extends Platform {
@Override
long getSharedContextNativeHandle(Object sharedContext) {
return ((EGLContext) sharedContext).getNativeHandle();
if (Build.VERSION.SDK_INT >= 21) {
return AndroidPlatform21.getSharedContextNativeHandle(sharedContext);
} else {
try {
//noinspection JavaReflectionMemberAccess
Method method = EGLContext.class.getDeclaredMethod("getHandle");
Integer handle = (Integer) method.invoke(sharedContext);
//noinspection ConstantConditions
return handle.longValue();
} catch (Exception e) {
Log.d(LOG_TAG, "Could not access shared context's native handle", e);
}
// Should not happen
return 0;
}
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament;
import android.opengl.EGLContext;
final class AndroidPlatform21 {
static long getSharedContextNativeHandle(Object sharedContext) {
return ((EGLContext) sharedContext).getNativeHandle();
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;
final class Asserts {
private Asserts() {
}
@NonNull @Size(min = 9)
static float[] assertMat3f(@Nullable float[] out) {
if (out == null) out = new float[9];
else if (out.length < 9) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 9");
}
return out;
}
static void assertMat3fIn(@NonNull @Size(min = 9) float[] in) {
if (in.length < 9) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 9");
}
}
@NonNull @Size(min = 16)
static double[] assertMat4d(@Nullable double[] out) {
if (out == null) out = new double[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
}
static void assertMat4dIn(@NonNull @Size(min = 16) double[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
@NonNull @Size(min = 16)
static float[] assertMat4f(@Nullable float[] out) {
if (out == null) out = new float[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
}
static void assertMat4fIn(@NonNull @Size(min = 16) float[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
@NonNull @Size(min = 3)
static float[] assertFloat3(@Nullable float[] out) {
if (out == null) out = new float[3];
else if (out.length < 3) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 3");
}
return out;
}
@NonNull @Size(min = 4)
static float[] assertFloat4(@Nullable float[] out) {
if (out == null) out = new float[4];
else if (out.length < 4) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
return out;
}
}

View File

@@ -157,26 +157,30 @@ public class Camera {
* @param projection type of projection to use
*
* @param left distance in world units from the camera to the left plane,
* at the near plane. Precondition: left != right.
* at the near plane. Precondition: <code>left</code> != <code>right</code>
*
* @param right distance in world units from the camera to the right plane,
* at the near plane. Precondition: left != right.
* at the near plane. Precondition: <code>left</code> != <code>right</code>
*
* @param bottom distance in world units from the camera to the bottom plane,
* at the near plane. Precondition: bottom != top.
* at the near plane. Precondition: <code>bottom</code> != <code>top</code>
*
* @param top distance in world units from the camera to the top plane,
* at the near plane. Precondition: left != right.
* at the near plane. Precondition: <code>bottom</code> != <code>top</code>
*
* @param near distance in world units from the camera to the near plane.
* The near plane's position in view space is z = -near.
* Precondition: near > 0 for {@link Projection#PERSPECTIVE} or
* near != far for {@link Projection#ORTHO}.
* The near plane's position in view space is z = -<code>near</code>.
* Precondition:
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
*
* @param far distance in world units from the camera to the far plane.
* The far plane's position in view space is z = -far.
* Precondition: far > near for {@link Projection#PERSPECTIVE} or
* far != near for {@link Projection#ORTHO}.
* The far plane's position in view space is z = -<code>far</code>.
* Precondition:
* <code>far</code> > <code>near</code>
* for {@link Projection#PERSPECTIVE} or
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*
* <p>
* These parameters are silently modified to meet the preconditions above.
@@ -189,12 +193,32 @@ public class Camera {
}
/**
* Sets the projection matrix from the field-of-view.
*
* @param fovInDegrees
* @param aspect
* @param near
* @param far
* @param direction
* @param fovInDegrees field-of-view in degrees from the camera center axis.
* 0 < <code>fovInDegrees</code> < 180
*
* @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>.
* Precondition:
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
*
* @param far distance in world units from the camera to the far plane.
* The far plane's position in view space is z = -<code>far</code>.
* Precondition:
* <code>far</code> > <code>near</code>
* for {@link Projection#PERSPECTIVE} or
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*
* @param direction direction of the field-of-view parameter.
* <p>
* These parameters are silently modified to meet the preconditions above.
*
* @see Fov
*/
public void setProjection(double fovInDegrees, double aspect, double near, double far,
@NonNull Fov direction) {
@@ -202,47 +226,86 @@ public class Camera {
}
/**
* Sets the projection matrix from the focal length
*
* @param focalLength lense's focal length in millimeters. <code>focalLength</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>.
* Precondition:
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
*
* @param far distance in world units from the camera to the far plane.
* The far plane's position in view space is z = -<code>far</code>.
* Precondition:
* <code>far</code> > <code>near</code>
* for {@link Projection#PERSPECTIVE} or
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*
* @param focalLength
* @param near
* @param far
*/
public void setLensProjection(double focalLength, double near, double far) {
nSetLensProjection(getNativeObject(), focalLength, near, far);
}
/**
* Sets the projection matrix.
*
* @param inMatrix
* @param near
* @param far
* @param inMatrix custom projection matrix.
*
* @param near distance in world units from the camera to the near plane.
* The near plane's position in view space is z = -<code>near</code>.
* Precondition:
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
*
* @param far distance in world units from the camera to the far plane.
* The far plane's position in view space is z = -<code>far</code>.
* Precondition:
* <code>far</code> > <code>near</code>
* for {@link Projection#PERSPECTIVE} or
* <code>far</code> != <code>near</code>
* for {@link Projection#ORTHO}.
*/
public void setCustomProjection(@NonNull @Size(min = 16) double inMatrix[],
public void setCustomProjection(@NonNull @Size(min = 16) double[] inMatrix,
double near, double far) {
assertMat4dIn(inMatrix);
Asserts.assertMat4dIn(inMatrix);
nSetCustomProjection(getNativeObject(), inMatrix, near, far);
}
/**
* Sets the camera's view matrix.
* <p>
* Helper method to set the camera's entity transform component.
* Remember that the Camera "looks" towards its -z axis.
* <p>
* This has the same effect as calling:
*
* @param in
* <pre>
* engine.getTransformManager().setTransform(
* engine.getTransformManager().getInstance(camera->getEntity()), viewMatrix);
* </pre>
*
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
*/
public void setModelMatrix(@NonNull @Size(min = 16) float in[]) {
assertMat4fIn(in);
nSetModelMatrix(getNativeObject(), in);
public void setModelMatrix(@NonNull @Size(min = 16) float[] viewMatrix) {
Asserts.assertMat4fIn(viewMatrix);
nSetModelMatrix(getNativeObject(), viewMatrix);
}
/**
* Sets the camera's view matrix.
*
* @param eyeX
* @param eyeY
* @param eyeZ
* @param centerX
* @param centerY
* @param centerZ
* @param upX
* @param upY
* @param upZ
* @param eyeX x-axis position of the camera in world space
* @param eyeY y-axis position of the camera in world space
* @param eyeZ z-axis position of the camera in world space
* @param centerX x-axis position of the point in world space the camera is looking at
* @param centerY y-axis position of the point in world space the camera is looking at
* @param centerZ z-axis position of the point in world space the camera is looking at
* @param upX x-axis coordinate of a unit vector denoting the camera's "up" direction
* @param upY y-axis coordinate of a unit vector denoting the camera's "up" direction
* @param upZ z-axis coordinate of a unit vector denoting the camera's "up" direction
*/
public void lookAt(double eyeX, double eyeY, double eyeZ,
double centerX, double centerY, double centerZ, double upX, double upY, double upZ) {
@@ -250,16 +313,14 @@ public class Camera {
}
/**
*
* @return Distance to the near plane.
* @return Distance to the near plane
*/
public float getNear() {
return nGetNear(getNativeObject());
}
/**
*
* @return Distance to the far plane.
* @return Distance to the far plane
*/
public float getCullingFar() {
return nGetCullingFar(getNativeObject());
@@ -267,13 +328,15 @@ public class Camera {
/**
* Retrieves the camera's projection matrix.
*
* @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[] getProjectionMatrix(@Nullable @Size(min = 16) double out[]) {
out = assertMat4d(out);
public double[] getProjectionMatrix(@Nullable @Size(min = 16) double[] out) {
out = Asserts.assertMat4d(out);
nGetProjectionMatrix(getNativeObject(), out);
return out;
}
@@ -281,13 +344,15 @@ public class Camera {
/**
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
* orientation, or pose.
*
* @param out A 16-float array where the model matrix will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-float array containing the camera's pose as a column-major matrix.
*/
@NonNull @Size(min = 16)
public float[] getModelMatrix(@Nullable @Size(min = 16) float out[]) {
out = assertMat4f(out);
public float[] getModelMatrix(@Nullable @Size(min = 16) float[] out) {
out = Asserts.assertMat4f(out);
nGetModelMatrix(getNativeObject(), out);
return out;
}
@@ -297,24 +362,27 @@ public class Camera {
*
* @param out A 16-float array where the model view will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-float array containing the camera's view as a column-major matrix.
*/
@NonNull @Size(min = 16)
public float[] getViewMatrix(@Nullable @Size(min = 16) float out[]) {
out = assertMat4f(out);
public float[] getViewMatrix(@Nullable @Size(min = 16) float[] out) {
out = Asserts.assertMat4f(out);
nGetViewMatrix(getNativeObject(), out);
return out;
}
/**
* Retrieves the camera position in world space.
*
* @param out A 3-float array where the position will be stored, or null in which case a new
* array is allocated.
*
* @return A 3-float array containing the camera's position in world units.
*/
@NonNull @Size(min = 3)
public float[] getPosition(@Nullable @Size(min = 3) float out[]) {
out = assertFloat3(out);
public float[] getPosition(@Nullable @Size(min = 3) float[] out) {
out = Asserts.assertFloat3(out);
nGetPosition(getNativeObject(), out);
return out;
}
@@ -322,13 +390,15 @@ public class Camera {
/**
* Retrieves the camera left unit vector in world space, that is a unit vector that points to
* the left of the camera.
*
* @param out A 3-float array where the left vector will be stored, or null in which case a new
* array is allocated.
*
* @return A 3-float array containing the camera's left vector in world units.
*/
@NonNull @Size(min = 3)
public float[] getLeftVector(@Nullable @Size(min = 3) float out[]) {
out = assertFloat3(out);
public float[] getLeftVector(@Nullable @Size(min = 3) float[] out) {
out = Asserts.assertFloat3(out);
nGetLeftVector(getNativeObject(), out);
return out;
}
@@ -336,13 +406,15 @@ public class Camera {
/**
* Retrieves the camera up unit vector in world space, that is a unit vector that points up with
* respect to the camera.
*
* @param out A 3-float array where the up vector will be stored, or null in which case a new
* array is allocated.
*
* @return A 3-float array containing the camera's up vector in world units.
*/
@NonNull @Size(min = 3)
public float[] getUpVector(@Nullable @Size(min = 3) float out[]) {
out = assertFloat3(out);
public float[] getUpVector(@Nullable @Size(min = 3) float[] out) {
out = Asserts.assertFloat3(out);
nGetUpVector(getNativeObject(), out);
return out;
}
@@ -350,52 +422,91 @@ public class Camera {
/**
* Retrieves the camera forward unit vector in world space, that is a unit vector that points
* in the direction the camera is looking at.
*
* @param out A 3-float array where the forward vector will be stored, or null in which case a
* new array is allocated.
*
* @return A 3-float array containing the camera's forward vector in world units.
*/
@NonNull @Size(min = 3)
public float[] getForwardVector(@Nullable @Size(min = 3) float out[]) {
out = assertFloat3(out);
public float[] getForwardVector(@Nullable @Size(min = 3) float[] out) {
out = Asserts.assertFloat3(out);
nGetForwardVector(getNativeObject(), out);
return out;
}
/**
* Sets this camera's exposure (default is f/16, 1/125s, 100 ISO)
*
* @param aperture
* @param shutterSpeed
* @param sensitivity
* The exposure ultimately controls the scene's brightness, just like with a real camera.
* The default values provide adequate exposure for a camera placed outdoors on a sunny day
* with the sun at the zenith.
*
* With the default parameters, the scene must contain at least one Light of intensity
* similar to the sun (e.g.: a 100,000 lux directional light) and/or an indirect light
* of appropriate intensity (30,000).
*
* @param aperture Aperture in f-stops, clamped between 0.5 and 64.
* A lower aperture value increases the exposure, leading to
* a brighter scene. Realistic values are between 0.95 and 32.
*
* @param shutterSpeed Shutter speed in seconds, clamped between 1/25,000 and 60.
* A lower shutter speed increases the exposure. Realistic values are
* between 1/8000 and 30.
*
* @param sensitivity Sensitivity in ISO, clamped between 10 and 204,800.
* A higher sensitivity increases the exposure. Realistic values are
* between 50 and 25600.
*
* @see LightManager
* @see Exposure
* @see #setExposure(float)
*/
public void setExposure(float aperture, float shutterSpeed, float sensitivity) {
nSetExposure(getNativeObject(), aperture, shutterSpeed, sensitivity);
}
/**
* Sets this camera's exposure directly. Calling this method will set the aperture
* to 1.0, the shutter speed to 1.2 and the sensitivity will be computed to match
* the requested exposure (for a desired exposure of 1.0, the sensitivity will be
* set to 100 ISO).
*
* @return
* This method is useful when trying to match the lighting of other engines or tools.
* Many engines/tools use unit-less light intensities, which can be matched by setting
* the exposure manually. This can be typically achieved by setting the exposure to
* 1.0.
*
* @see Light
* @see Exposure
* @see #setExposure(float, float, float)
*/
public void setExposure(float exposure) {
setExposure(1.0f, 1.2f, 100.0f * (1.0f / exposure));
}
/**
* @return Aperture in f-stops
*/
public float getAperture() {
return nGetAperture(getNativeObject());
}
/**
*
* @return
* @return Shutter speed in seconds
*/
public float getShutterSpeed() {
return nGetShutterSpeed(getNativeObject());
}
/**
*
* @return
* @return Sensitivity in ISO
*/
public float getSensitivity() {
return nGetSensitivity(getNativeObject());
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Camera");
}
@@ -406,45 +517,6 @@ public class Camera {
mNativeObject = 0;
}
@NonNull @Size(min = 16)
private static double[] assertMat4d(@Nullable double[] out) {
if (out == null) out = new double[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
}
@NonNull @Size(min = 16)
private static float[] assertMat4f(@Nullable float[] out) {
if (out == null) out = new float[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
}
private static void assertMat4dIn(@NonNull @Size(min = 16) double[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
private static void assertMat4fIn(@NonNull @Size(min = 16) float[] in) {
if (in.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
}
@NonNull @Size(min = 3)
private static float[] assertFloat3(@Nullable float[] out) {
if (out == null) out = new float[3];
else if (out.length < 3) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 3");
}
return out;
}
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);

View File

@@ -16,21 +16,120 @@
package com.google.android.filament;
import com.google.android.filament.proguard.UsedByReflection;
import android.support.annotation.NonNull;
import com.google.android.filament.proguard.UsedByReflection;
/**
* Engine is filament's main entry-point.
* <p>
* An Engine instance main function is to keep track of all resources created by the user and
* manage the rendering thread as well as the hardware renderer.
* <p>
* To use filament, an Engine instance must be created first:
*
* <pre>
* import com.google.android.filament.*
*
* Engine engine = Engine.create();
* </pre>
* <p>
* Engine essentially represents (or is associated to) a hardware context
* (e.g. an OpenGL ES context).
* <p>
* Rendering typically happens in an operating system's window (which can be full screen), such
* window is managed by a {@link Renderer}.
* <p>
* A typical filament render loop looks like this:
*
*
* <pre>
* import com.google.android.filament.*
*
* Engin engine = Engine.create();
* SwapChain swapChain = engine.createSwapChain(nativeWindow);
* Renderer renderer = engine.createRenderer();
* Scene scene = engine.createScene();
* View view = engine.createView();
*
* view.setScene(scene);
*
* do {
* // typically we wait for VSYNC and user input events
* if (renderer.beginFrame(swapChain)) {
* renderer.render(view);
* renderer.endFrame();
* }
* } while (!quit);
*
* engine.destroyView(view);
* engine.destroyScene(scene);
* engine.destroyRenderer(renderer);
* engine.destroySwapChain(swapChain);
* engine.destroy();
* </pre>
*
* <h1><u>Resource Tracking</u></h1>
* <p>
* Each <code>Engine</code> instance keeps track of all objects created by the user, such as vertex
* and index buffers, lights, cameras, etc...
* The user is expected to free those resources, however, leaked resources are freed when the
* engine instance is destroyed and a warning is emitted in the console.
*
* <h1><u>Thread safety</u></h1>
* <p>
* An <code>Engine</code> instance is not thread-safe. The implementation makes no attempt to
* synchronize calls to an <code>Engine</code> instance methods.
* If multi-threading is needed, synchronization must be external.
*
* <h1><u>Multi-threading</u></h1>
* <p>
* When created, the <code>Engine</code> instance starts a render thread as well as multiple worker
* threads, these threads have an elevated priority appropriate for rendering, based on the
* platform's best practices. The number of worker threads depends on the platform and is
* automatically chosen for best performance.
* <p>
* On platforms with asymmetric cores (e.g. ARM's Big.Little), <code>Engine</code> makes some
* educated guesses as to which cores to use for the render thread and worker threads. For example,
* it'll try to keep an OpenGL ES thread on a Big core.
*
* <h1><u>Swap Chains</u></h1>
* <p>
* A swap chain represents an Operating System's <b>native</b> renderable surface.
* Typically it's a window or a view. Because a {@link SwapChain} is initialized from a native
* object, it is given to filament as an <code>Object</code>, which must be of the proper type for
* each platform filament is running on.
* <p>
*
* @see SwapChain
* @see Renderer
*/
public class Engine {
private long mNativeObject;
@NonNull private final TransformManager mTransformManager;
@NonNull private final LightManager mLightManager;
@NonNull private final RenderableManager mRenderableManager;
/**
* Denotes a backend
*/
public enum Backend {
DEFAULT, // Automatically selects an appropriate driver for the platform.
OPENGL, // Selects the OpenGL ES driver.
VULKAN, // Selects the experimental Vulkan driver.
NOOP, // Selects the no-op driver for testing purposes.
/**
* Automatically selects an appropriate driver for the platform.
*/
DEFAULT,
/**
* Selects the OpenGL ES driver.
*/
OPENGL,
/**
* Selects the experimental Vulkan driver.
*/
VULKAN,
/**
* Selects the no-op driver for testing purposes.
*/
NOOP,
}
private Engine(long nativeEngine) {
@@ -40,6 +139,19 @@ public class Engine {
mRenderableManager = new RenderableManager(nGetRenderableManager(nativeEngine));
}
/**
* Creates an instance of Engine using the default {@link Backend}
* <p>
* This method is one of the few thread-safe methods.
*
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
* be initialized, for instance if it doesn't support the right version of OpenGL or
* OpenGL ES.
*
* @exception IllegalStateException can be thrown if there isn't enough memory to
* allocate the command buffer.
*
*/
@NonNull
public static Engine create() {
long nativeEngine = nCreateEngine(0, 0);
@@ -47,6 +159,21 @@ public class Engine {
return new Engine(nativeEngine);
}
/**
* Creates an instance of Engine using the specified {@link Backend}
* <p>
* This method is one of the few thread-safe methods.
*
* @param backend driver backend to use
*
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
* be initialized, for instance if it doesn't support the right version of OpenGL or
* OpenGL ES.
*
* @exception IllegalStateException can be thrown if there isn't enough memory to
* allocate the command buffer.
*
*/
@NonNull
public static Engine create(@NonNull Backend backend) {
long nativeEngine = nCreateEngine(backend.ordinal(), 0);
@@ -55,9 +182,21 @@ public class Engine {
}
/**
* Valid shared context:
* - Android: EGLContext
* - Other: none
* Creates an instance of Engine using the {@link Backend#OPENGL} and a shared OpenGL context.
* <p>
* This method is one of the few thread-safe methods.
*
* @param sharedContext A platform-dependant OpenGL context used as a shared context
* when creating filament's internal context. On Android this parameter
* <b>must be</b> an instance of {@link android.opengl.EGLContext}.
*
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
* be initialized, for instance if it doesn't support the right version of OpenGL or
* OpenGL ES.
*
* @exception IllegalStateException can be thrown if there isn't enough memory to
* allocate the command buffer.
*
*/
@NonNull
public static Engine create(@NonNull Object sharedContext) {
@@ -70,15 +209,41 @@ public class Engine {
throw new IllegalArgumentException("Invalid shared context " + sharedContext);
}
/**
* @return <code>true</code> if this <code>Engine</code> is initialized properly.
*/
public boolean isValid() {
return mNativeObject != 0;
}
/**
* Destroy the <code>Engine</code> instance and all associated resources.
* <p>
* This method is one of the few thread-safe methods.
* <p>
* {@link Engine#destroy()} should be called last and after all other resources have been
* destroyed, it ensures all filament resources are freed.
* <p>
* <code>Destroy</code> performs the following tasks:
* <li>Destroy all internal software and hardware resources.</li>
* <li>Free all user allocated resources that are not already destroyed and logs a warning.
* <p>This indicates a "leak" in the user's code.</li>
* <li>Terminate the rendering engine's thread.</li>
*
* <pre>
* Engine engine = Engine.create();
* engine.destroy();
* </pre>
*/
public void destroy() {
nDestroyEngine(getNativeObject());
clearNativeObject();
}
/**
* @return the backend used by this <code>Engine</code>
*/
@NonNull
public Backend getBackend() {
return Backend.values()[(int) nGetBackend(getNativeObject())];
}
@@ -86,25 +251,36 @@ public class Engine {
// SwapChain
/**
* Valid surface types:
* - Android: Surface
* - Other: none
* Creates an opaque {@link SwapChain} from the given OS native window handle.
*
* @param surface on Android, <b>must be</b> an instance of {@link android.view.Surface}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
*/
@NonNull
public SwapChain createSwapChain(@NonNull Object surface) {
return createSwapChain(surface, SwapChain.CONFIG_DEFAULT);
}
/**
* Valid surface types:
* - Android: Surface
* - Other: none
* Creates a {@link SwapChain} from the given OS native window handle.
*
* Flags: see CONFIG flags in SwapChain.
* @param surface on Android, <b>must be</b> an instance of {@link android.view.Surface}
*
* @param flags configuration flags, see {@link SwapChain}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
*
* @see SwapChain#CONFIG_DEFAULT
* @see SwapChain#CONFIG_TRANSPARENT
* @see SwapChain#CONFIG_READABLE
*
*/
@NonNull
public SwapChain createSwapChain(@NonNull Object surface, long flags) {
if (Platform.get().validateSurface(surface)) {
long nativeSwapChain = nCreateSwapChain(getNativeObject(), surface, flags);
@@ -114,6 +290,18 @@ public class Engine {
throw new IllegalArgumentException("Invalid surface " + surface);
}
/**
* Creates a {@link SwapChain} from a {@link NativeSurface}.
*
* @param surface a properly initialized {@link NativeSurface}
*
* @param flags configuration flags, see {@link SwapChain}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the {@link SwapChain} couldn't be created
*/
@NonNull
public SwapChain createSwapChainFromNativeSurface(@NonNull NativeSurface surface, long flags) {
long nativeSwapChain =
nCreateSwapChainFromRawPointer(getNativeObject(), surface.getNativeObject(), flags);
@@ -121,6 +309,10 @@ public class Engine {
return new SwapChain(nativeSwapChain, surface);
}
/**
* Destroys a {@link SwapChain} and frees all its associated resources.
* @param swapChain the {@link SwapChain} to destroy
*/
public void destroySwapChain(@NonNull SwapChain swapChain) {
nDestroySwapChain(getNativeObject(), swapChain.getNativeObject());
swapChain.clearNativeObject();
@@ -128,6 +320,11 @@ public class Engine {
// View
/**
* Creates a {@link View}.
* @return a newly created {@link View}
* @exception IllegalStateException can be thrown if the {@link View} couldn't be created
*/
@NonNull
public View createView() {
long nativeView = nCreateView(getNativeObject());
@@ -135,6 +332,10 @@ public class Engine {
return new View(nativeView);
}
/**
* Destroys a {@link View} and frees all its associated resources.
* @param view the {@link View} to destroy
*/
public void destroyView(@NonNull View view) {
nDestroyView(getNativeObject(), view.getNativeObject());
view.clearNativeObject();
@@ -142,6 +343,11 @@ public class Engine {
// Renderer
/**
* Creates a {@link Renderer}.
* @return a newly created {@link Renderer}
* @exception IllegalStateException can be thrown if the {@link Renderer} couldn't be created
*/
@NonNull
public Renderer createRenderer() {
long nativeRenderer = nCreateRenderer(getNativeObject());
@@ -149,6 +355,10 @@ public class Engine {
return new Renderer(this, nativeRenderer);
}
/**
* Destroys a {@link Renderer} and frees all its associated resources.
* @param renderer the {@link Renderer} to destroy
*/
public void destroyRenderer(@NonNull Renderer renderer) {
nDestroyRenderer(getNativeObject(), renderer.getNativeObject());
renderer.clearNativeObject();
@@ -156,6 +366,12 @@ public class Engine {
// Camera
/**
* Creates a new <code>entity</code> and adds a {@link Camera} component to it.
*
* @return A newly created {@link Camera}
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
*/
@NonNull
public Camera createCamera() {
long nativeCamera = nCreateCamera(getNativeObject());
@@ -163,6 +379,13 @@ public class Engine {
return new Camera(nativeCamera);
}
/**
* Creates and adds a {@link Camera} component to a given <code>entity</code>.
*
* @param entity <code>entity</code> to add the camera component to
* @return A newly created {@link Camera}
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
*/
@NonNull
public Camera createCamera(@Entity int entity) {
long nativeCamera = nCreateCameraWithEntity(getNativeObject(), entity);
@@ -170,6 +393,10 @@ public class Engine {
return new Camera(nativeCamera);
}
/**
* Destroys a {@link Camera} component and frees all its associated resources.
* @param camera the {@link Camera} to destroy
*/
public void destroyCamera(@NonNull Camera camera) {
nDestroyCamera(getNativeObject(), camera.getNativeObject());
camera.clearNativeObject();
@@ -177,6 +404,11 @@ public class Engine {
// Scene
/**
* Creates a {@link Scene}.
* @return a newly created {@link Scene}
* @exception IllegalStateException can be thrown if the {@link Scene} couldn't be created
*/
@NonNull
public Scene createScene() {
long nativeScene = nCreateScene(getNativeObject());
@@ -184,6 +416,10 @@ public class Engine {
return new Scene(nativeScene);
}
/**
* Destroys a {@link Scene} and frees all its associated resources.
* @param scene the {@link Scene} to destroy
*/
public void destroyScene(@NonNull Scene scene) {
nDestroyScene(getNativeObject(), scene.getNativeObject());
scene.clearNativeObject();
@@ -191,6 +427,10 @@ public class Engine {
// Stream
/**
* Destroys a {@link Stream} and frees all its associated resources.
* @param stream the {@link Stream} to destroy
*/
public void destroyStream(@NonNull Stream stream) {
nDestroyStream(getNativeObject(), stream.getNativeObject());
stream.clearNativeObject();
@@ -198,13 +438,22 @@ public class Engine {
// Fence
/**
* Creates a {@link Fence}.
* @return a newly created {@link Fence}
* @exception IllegalStateException can be thrown if the {@link Fence} couldn't be created
*/
@NonNull
public Fence createFence(@NonNull Fence.Type type) {
long nativeFence = nCreateFence(getNativeObject(), type.ordinal());
public Fence createFence() {
long nativeFence = nCreateFence(getNativeObject());
if (nativeFence == 0) throw new IllegalStateException("Couldn't create Fence");
return new Fence(nativeFence);
}
/**
* Destroys a {@link Fence} and frees all its associated resources.
* @param fence the {@link Fence} to destroy
*/
public void destroyFence(@NonNull Fence fence) {
nDestroyFence(getNativeObject(), fence.getNativeObject());
fence.clearNativeObject();
@@ -212,73 +461,134 @@ public class Engine {
// others...
/**
* Destroys a {@link IndexBuffer} and frees all its associated resources.
* @param indexBuffer the {@link IndexBuffer} to destroy
*/
public void destroyIndexBuffer(@NonNull IndexBuffer indexBuffer) {
nDestroyIndexBuffer(getNativeObject(), indexBuffer.getNativeObject());
indexBuffer.clearNativeObject();
}
/**
* Destroys a {@link VertexBuffer} and frees all its associated resources.
* @param vertexBuffer the {@link VertexBuffer} to destroy
*/
public void destroyVertexBuffer(@NonNull VertexBuffer vertexBuffer) {
nDestroyVertexBuffer(getNativeObject(), vertexBuffer.getNativeObject());
vertexBuffer.clearNativeObject();
}
/**
* Destroys a {@link IndirectLight} and frees all its associated resources.
* @param ibl the {@link IndirectLight} to destroy
*/
public void destroyIndirectLight(@NonNull IndirectLight ibl) {
nDestroyIndirectLight(getNativeObject(), ibl.getNativeObject());
ibl.clearNativeObject();
}
/**
* Destroys a {@link Material} and frees all its associated resources.
* <p>
* All {@link MaterialInstance} of the specified {@link Material} must be destroyed before
* destroying it; if some {@link MaterialInstance} remain, this method fails silently.
*
* @param material the {@link Material} to destroy
*/
public void destroyMaterial(@NonNull Material material) {
nDestroyMaterial(getNativeObject(), material.getNativeObject());
material.clearNativeObject();
}
/**
* Destroys a {@link MaterialInstance} and frees all its associated resources.
* @param materialInstance the {@link MaterialInstance} to destroy
*/
public void destroyMaterialInstance(@NonNull MaterialInstance materialInstance) {
nDestroyMaterialInstance(getNativeObject(), materialInstance.getNativeObject());
materialInstance.clearNativeObject();
}
/**
* Destroys a {@link Skybox} and frees all its associated resources.
* @param skybox the {@link Skybox} to destroy
*/
public void destroySkybox(@NonNull Skybox skybox) {
nDestroySkybox(getNativeObject(), skybox.getNativeObject());
skybox.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());
texture.clearNativeObject();
}
/**
* Destroys a {@link RenderTarget} and frees all its associated resources.
* @param target the {@link RenderTarget} to destroy
*/
public void destroyRenderTarget(@NonNull RenderTarget target) {
nDestroyRenderTarget(getNativeObject(), target.getNativeObject());
target.clearNativeObject();
}
/**
* Destroys an <code>entity</code> and all its components.
* <p>
* It is recommended to destroy components individually before destroying their
* <code>entity</code>, this gives more control as to when the destruction really happens.
* Otherwise, orphaned components are garbage collected, which can happen at a later time.
* Even when component are garbage collected, the destruction of their <code>entity</code>
* terminates their participation immediately.
*
* @param entity the <code>entity</code> to destroy
*/
public void destroyEntity(@Entity int entity) {
nDestroyEntity(getNativeObject(), entity);
}
// Managers
/**
* @return the {@link TransformManager} used by this {@link Engine}
*/
@NonNull
public TransformManager getTransformManager() {
return mTransformManager;
}
/**
* @return the {@link LightManager} used by this {@link Engine}
*/
@NonNull
public LightManager getLightManager() {
return mLightManager;
}
/**
* @return the {@link RenderableManager} used by this {@link Engine}
*/
@NonNull
public RenderableManager getRenderableManager() {
return mRenderableManager;
}
/**
* Kicks the hardware thread (e.g.: the OpenGL, Vulkan or Metal thread) and blocks until
* all commands to this point are executed. Note that this doesn't guarantee that the
* hardware is actually finished.
*/
public void flushAndWait() {
Fence.waitAndDestroy(createFence(Fence.Type.HARD), Fence.Mode.FLUSH);
Fence.waitAndDestroy(createFence(), Fence.Mode.FLUSH);
}
@UsedByReflection("TextureHelper.java")
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Engine");
}
@@ -304,7 +614,7 @@ public class Engine {
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 long nCreateFence(long nativeEngine, int fenceType);
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);

View File

@@ -19,6 +19,8 @@ package com.google.android.filament;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import com.google.android.filament.proguard.UsedByReflection;
public class EntityManager {
private long mNativeObject = nGetEntityManager();
@@ -66,6 +68,11 @@ public class EntityManager {
return nIsAlive(mNativeObject, entity);
}
@UsedByReflection("AssetLoader.java")
public long getNativeObject() {
return mNativeObject;
}
private static native long nGetEntityManager();
private static native void nCreateArray(long nativeEntityManager, int n, int[] entities);
private static native int nCreate(long nativeEntityManager);

View File

@@ -26,11 +26,6 @@ public class Fence {
public static final long WAIT_FOR_EVER = -1;
public enum Type {
SOFT,
HARD
}
public enum Mode {
FLUSH,
DONT_FLUSH
@@ -70,7 +65,7 @@ public class Fence {
}
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Fence");
}

View File

@@ -30,13 +30,6 @@ public class IndexBuffer {
mNativeObject = nativeIndexBuffer;
}
long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IndexBuffer");
}
return mNativeObject;
}
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
@@ -121,6 +114,13 @@ public class IndexBuffer {
}
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IndexBuffer");
}
return mNativeObject;
}
void clearNativeObject() {
mNativeObject = 0;
}

View File

@@ -18,12 +18,16 @@ package com.google.android.filament;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;
import com.google.android.filament.proguard.UsedByReflection;
public class IndirectLight {
long mNativeObject;
private IndirectLight(long indirectLight) {
@UsedByReflection("KtxLoader.java")
IndirectLight(long indirectLight) {
mNativeObject = indirectLight;
}
@@ -92,7 +96,7 @@ public class IndirectLight {
}
@NonNull
public Builder rotation(@NonNull @Size(min = 9) float rotation[]) {
public Builder rotation(@NonNull @Size(min = 9) float[] rotation) {
nRotation(mNativeBuilder,
rotation[0], rotation[1], rotation[2],
rotation[3], rotation[4], rotation[5],
@@ -132,14 +136,36 @@ public class IndirectLight {
return nGetIntensity(getNativeObject());
}
public void setRotation(@NonNull @Size(min = 9) float rotation[]) {
public void setRotation(@NonNull @Size(min = 9) float[] rotation) {
Asserts.assertMat3fIn(rotation);
nSetRotation(getNativeObject(),
rotation[0], rotation[1], rotation[2],
rotation[3], rotation[4], rotation[5],
rotation[6], rotation[7], rotation[8]);
}
long getNativeObject() {
@NonNull @Size(min = 9)
public float[] getRotation(@Nullable @Size(min = 9) float[] rotation) {
rotation = Asserts.assertMat3f(rotation);
nGetRotation(getNativeObject(), rotation);
return rotation;
}
@NonNull @Size(min = 3)
public float[] getDirectionEstimate(@Nullable @Size(min = 3) float[] direction) {
direction = Asserts.assertFloat3(direction);
nGetDirectionEstimate(getNativeObject(), direction);
return direction;
}
@NonNull @Size(min = 4)
public float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, float x, float y, float z) {
colorIntensity = Asserts.assertFloat4(colorIntensity);
nGetColorEstimate(getNativeObject(), colorIntensity, x, y, z);
return colorIntensity;
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed IndirectLight");
}
@@ -164,5 +190,7 @@ public class IndirectLight {
private static native void nSetIntensity(long nativeIndirectLight, float intensity);
private static native float nGetIntensity(long nativeIndirectLight);
private static native void nSetRotation(long nativeIndirectLight, float v0, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8);
private static native void nGetRotation(long nativeIndirectLight, float[] outRotation);
private static native void nGetDirectionEstimate(long nativeIndirectLight, float[] outDirection);
private static native void nGetColorEstimate(long nativeIndirectLight, float[] outColor, float x, float y, float z);
}

View File

@@ -187,7 +187,7 @@ public class LightManager {
@NonNull
public float[] getPosition(@EntityInstance int i, @Nullable @Size(min = 3) float[] out) {
out = assertFloat3(out);
out = Asserts.assertFloat3(out);
nGetPosition(mNativeObject, i, out);
return out;
}
@@ -198,7 +198,7 @@ public class LightManager {
@NonNull
public float[] getDirection(@EntityInstance int i, @Nullable @Size(min = 3) float[] out) {
out = assertFloat3(out);
out = Asserts.assertFloat3(out);
nGetDirection(mNativeObject, i, out);
return out;
}
@@ -209,7 +209,7 @@ public class LightManager {
@NonNull
public float[] getColor(@EntityInstance int i, @Nullable @Size(min = 3) float[] out) {
out = assertFloat3(out);
out = Asserts.assertFloat3(out);
nGetColor(mNativeObject, i, out);
return out;
}
@@ -262,13 +262,16 @@ public class LightManager {
return nGetSunHaloFalloff(mNativeObject, i);
}
@NonNull @Size(min = 3)
private static float[] assertFloat3(@Nullable float[] out) {
if (out == null) out = new float[3];
else if (out.length < 3) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 3");
}
return out;
public void setShadowCaster(@EntityInstance int i, boolean shadowCaster) {
nSetShadowCaster(mNativeObject, i, shadowCaster);
}
public boolean isShadowCaster(@EntityInstance int i) {
return nIsShadowCaster(mNativeObject, i);
}
public long getNativeObject() {
return mNativeObject;
}
private static native boolean nHasComponent(long nativeLightManager, int entity);
@@ -292,7 +295,6 @@ public class LightManager {
private static native void nBuilderHaloSize(long nativeBuilder, float haloSize);
private static native void nBuilderHaloFalloff(long nativeBuilder, float haloFalloff);
private static native int nGetType(long nativeLightManager, int i);
private static native void nSetPosition(long nativeLightManager, int i, float x, float y, float z);
private static native void nGetPosition(long nativeLightManager, int i, float[] out);
@@ -312,4 +314,6 @@ public class LightManager {
private static native float nGetSunHaloSize(long nativeLightManager, int i);
private static native void nSetSunHaloFalloff(long nativeLightManager, int i, float haloFalloff);
private static native float nGetSunHaloFalloff(long nativeLightManager, int i);
private static native void nSetShadowCaster(long nativeLightManager, int i, boolean shadowCaster);
private static native boolean nIsShadowCaster(long nativeLightManager, int i);
}

View File

@@ -19,6 +19,7 @@ package com.google.android.filament;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Size;
import com.google.android.filament.proguard.UsedByNative;
import java.nio.Buffer;
@@ -134,8 +135,9 @@ public class Material {
}
}
private Material(long nativeMaterial, long nativeDefaultInstance) {
Material(long nativeMaterial) {
mNativeObject = nativeMaterial;
long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial);
mDefaultInstance = new MaterialInstance(this, nativeDefaultInstance);
}
@@ -154,8 +156,7 @@ public class Material {
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(), mBuffer, mSize);
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
long nativeDefaultInstance = nGetDefaultInstance(nativeMaterial);
return new Material(nativeMaterial, nativeDefaultInstance);
return new Material(nativeMaterial);
}
}
@@ -338,7 +339,7 @@ public class Material {
mDefaultInstance.setParameter(name, texture, sampler);
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Material");
}

View File

@@ -21,8 +21,9 @@ import android.support.annotation.NonNull;
import android.support.annotation.Size;
public class MaterialInstance {
private final Material mMaterial;
private Material mMaterial;
private long mNativeObject;
private long mNativeMaterial;
public enum BooleanElement {
BOOL,
@@ -52,8 +53,16 @@ public class MaterialInstance {
mNativeObject = nativeMaterialInstance;
}
MaterialInstance(long nativeMaterial, long nativeMaterialInstance) {
mNativeMaterial = nativeMaterial;
mNativeObject = nativeMaterialInstance;
}
@NonNull
public Material getMaterial() {
if (mMaterial == null) {
mMaterial = new Material(mNativeMaterial);
}
return mMaterial;
}
@@ -169,7 +178,11 @@ public class MaterialInstance {
nSetDoubleSided(getNativeObject(), doubleSided);
}
long getNativeObject() {
public void setCullingMode(Material.CullingMode mode) {
nSetCullingMode(getNativeObject(), mode.ordinal());
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
}
@@ -238,4 +251,6 @@ public class MaterialInstance {
float threshold);
private static native void nSetDoubleSided(long nativeMaterialInstance, boolean doubleSided);
private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
}

View File

@@ -17,6 +17,7 @@
package com.google.android.filament;
import android.support.annotation.NonNull;
import com.google.android.filament.proguard.UsedByNative;
import java.nio.Buffer;

View File

@@ -20,9 +20,6 @@ import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.nio.Buffer;
import java.nio.BufferOverflowException;
public class RenderTarget {
private long mNativeObject;
private final Texture[] mTextures = new Texture[2];
@@ -33,7 +30,7 @@ public class RenderTarget {
mTextures[1] = builder.mTextures[1];
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed RenderTarget");
}

View File

@@ -169,6 +169,12 @@ public class RenderableManager {
return this;
}
@NonNull
public Builder morphing(boolean enabled) {
nBuilderMorphing(mNativeBuilder, enabled);
return this;
}
public void build(@NonNull Engine engine, @Entity int entity) {
if (!nBuilderBuild(mNativeBuilder, engine.getNativeObject(), entity)) {
throw new IllegalStateException(
@@ -225,6 +231,10 @@ public class RenderableManager {
}
}
public void setMorphWeights(@EntityInstance int i, float[] weights) {
nSetMorphWeights(mNativeObject, i, weights);
}
public void setAxisAlignedBoundingBox(@EntityInstance int i, @NonNull Box aabb) {
nSetAxisAlignedBoundingBox(mNativeObject, i,
aabb.getCenter()[0], aabb.getCenter()[1], aabb.getCenter()[2],
@@ -282,6 +292,14 @@ public class RenderableManager {
nSetMaterialInstanceAt(mNativeObject, i, primitiveIndex, materialInstance.getNativeObject());
}
// creates a MaterialInstance Java wrapper object for a particular material instance
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);
}
// set/change the geometry (vertex/index buffers) of a given primitive
public void setGeometryAt(@EntityInstance int i, @IntRange(from = 0) int primitiveIndex,
@NonNull PrimitiveType type, @NonNull VertexBuffer vertices,
@@ -322,6 +340,10 @@ public class RenderableManager {
return requiredAttributes;
}
public long getNativeObject() {
return mNativeObject;
}
private static native boolean nHasComponent(long nativeRenderableManager, int entity);
private static native int nGetInstance(long nativeRenderableManager, int entity);
private static native void nDestroy(long nativeRenderableManager, int entity);
@@ -343,9 +365,11 @@ public class RenderableManager {
private static native void nBuilderReceiveShadows(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);
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights);
private static native void 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);
@@ -356,6 +380,8 @@ public class RenderableManager {
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
private static native int nGetPrimitiveCount(long nativeRenderableManager, int i);
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native long nGetMaterialAt(long nativeRenderableManager, int i, int primitiveIndex);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, int offset, int count);
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);

View File

@@ -65,7 +65,7 @@ public class Renderer {
flags);
}
/** @deprecated */
@Deprecated
public void mirrorFrame(
@NonNull SwapChain dstSwapChain, @NonNull Viewport dstViewport,
@NonNull Viewport srcViewport, int flags) {
@@ -104,7 +104,7 @@ public class Renderer {
nResetUserTime(getNativeObject());
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Renderer");
}

View File

@@ -52,6 +52,10 @@ public class Scene {
nAddEntity(getNativeObject(), entity);
}
public void addEntities(@Entity int[] entities) {
nAddEntities(getNativeObject(), entities);
}
public void removeEntity(@Entity int entity) {
nRemove(getNativeObject(), entity);
}
@@ -71,7 +75,7 @@ public class Scene {
return nGetLightCount(getNativeObject());
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Scene");
}
@@ -85,6 +89,7 @@ public class Scene {
private static native void nSetSkybox(long nativeScene, long nativeSkybox);
private static native void nSetIndirectLight(long nativeScene, long nativeIndirectLight);
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 int nGetRenderableCount(long nativeScene);
private static native int nGetLightCount(long nativeScene);

View File

@@ -19,10 +19,13 @@ package com.google.android.filament;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import com.google.android.filament.proguard.UsedByReflection;
public class Skybox {
private long mNativeObject;
private Skybox(long nativeSkybox) {
@UsedByReflection("KtxLoader.java")
Skybox(long nativeSkybox) {
mNativeObject = nativeSkybox;
}
@@ -80,7 +83,7 @@ public class Skybox {
return nGetLayerMask(getNativeObject());
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Skybox");
}

View File

@@ -132,7 +132,7 @@ public class Stream {
return nGetTimestamp(getNativeObject());
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Stream");
}

View File

@@ -36,7 +36,7 @@ public class SwapChain {
return mSurface;
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SwapChain");
}

View File

@@ -16,13 +16,13 @@
package com.google.android.filament;
import com.google.android.filament.proguard.UsedByReflection;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;
import com.google.android.filament.proguard.UsedByReflection;
import java.nio.Buffer;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
@@ -32,6 +32,7 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
public class Texture {
private long mNativeObject;
@UsedByReflection("KtxLoader.java")
Texture(long nativeTexture) {
mNativeObject = nativeTexture;
}
@@ -62,7 +63,7 @@ public class Texture {
RG16F, RG16UI, RG16I,
R11F_G11F_B10F,
RGBA8, SRGB8_A8, RGBA8_SNORM,
UNUSED, // The RGBM InternalFormat has been replaced with a flag (Texture.Builder.rgbm)
UNUSED, // used to be rgbm
RGB10_A2, RGBA8UI, RGBA8I,
DEPTH32F, DEPTH24_STENCIL8, DEPTH32F_STENCIL8,
@@ -120,7 +121,7 @@ public class Texture {
RGB_INTEGER,
RGBA,
RGBA_INTEGER,
RGBM,
UNUSED,
DEPTH_COMPONENT,
DEPTH_STENCIL,
STENCIL_INDEX,
@@ -136,7 +137,8 @@ public class Texture {
INT,
HALF,
FLOAT,
COMPRESSED
COMPRESSED,
UINT_10F_11F_11F_REV
}
public static class PixelBufferDescriptor {
@@ -254,7 +256,6 @@ public class Texture {
break;
case RGBA:
case RGBA_INTEGER:
case RGBM:
n = 4;
break;
}
@@ -275,6 +276,10 @@ public class Texture {
case FLOAT:
bpp *= 4;
break;
case UINT_10F_11F_11F_REV:
// Special case, format must be RGB and uses 4 bytes
bpp = 4;
break;
}
int bpr = bpp * stride;
@@ -283,6 +288,11 @@ public class Texture {
}
}
public static class PrefilterOptions {
public int sampleCount = 8;
public boolean mirror = true;
}
public static boolean isTextureFormatSupported(@NonNull Engine engine,
@NonNull InternalFormat format) {
return nIsTextureFormatSupported(engine.getNativeObject(), format.ordinal());
@@ -335,9 +345,14 @@ public class Texture {
return this;
}
/**
* Sets the usage flags, which is necessary when attaching to {@link RenderTarget}.
*
* The flags argument much be a combination of {@link Usage} flags.
*/
@NonNull
public Builder rgbm(boolean enabled) {
nBuilderRgbm(mNativeBuilder, enabled);
public Builder usage(int flags) {
nBuilderUsage(mNativeBuilder, flags);
return this;
}
@@ -367,6 +382,15 @@ public class Texture {
}
}
public static class Usage {
public static final int COLOR_ATTACHMENT = 0x1;
public static final int DEPTH_ATTACHMENT = 0x2;
public static final int STENCIL_ATTACHMENT = 0x4;
public static final int UPLOADABLE = 0x8;
public static final int SAMPLEABLE = 0x10;
public static final int DEFAULT = UPLOADABLE | SAMPLEABLE;
}
public static final int BASE_LEVEL = 0;
public int getWidth(@IntRange(from = 0) int level) {
@@ -472,8 +496,35 @@ public class Texture {
nGenerateMipmaps(getNativeObject(), engine.getNativeObject());
}
public void generatePrefilterMipmap(@NonNull Engine engine,
@NonNull PixelBufferDescriptor buffer, @NonNull @Size(min = 6) int[] faceOffsetsInBytes,
PrefilterOptions options) {
int width = getWidth(0);
int height= getHeight(0);
int sampleCount = 8;
boolean mirror = true;
if (options != null) {
sampleCount = options.sampleCount;
mirror = options.mirror;
}
int result = nGeneratePrefilterMipmap(getNativeObject(), engine.getNativeObject(),
width, height,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.stride, buffer.format.ordinal(), faceOffsetsInBytes,
buffer.handler, buffer.callback,
sampleCount, mirror);
if (result < 0) {
throw new BufferOverflowException();
}
}
@UsedByReflection("TextureHelper.java")
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Texture");
}
@@ -495,7 +546,7 @@ public class Texture {
private static native void nBuilderLevels(long nativeBuilder, int levels);
private static native void nBuilderSampler(long nativeBuilder, int sampler);
private static native void nBuilderFormat(long nativeBuilder, int format);
private static native void nBuilderRgbm(long nativeBuilder, boolean enabled);
private static native void nBuilderUsage(long nativeBuilder, int flags);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetWidth(long nativeTexture, int level);
@@ -536,4 +587,9 @@ public class Texture {
private static native void nGenerateMipmaps(long nativeTexture, long nativeEngine);
private static native boolean nIsStreamValidForTexture(long nativeTexture, long nativeStream);
private static native int nGeneratePrefilterMipmap(long nativeIndirectLight, long nativeEngine,
int width, int height, Buffer storage, int remaining, int left, int top,
int type, int alignment, int stride, int format, int[] faceOffsetsInBytes,
Object handler, Runnable callback, int sampleCount, boolean mirror);
}

View File

@@ -57,9 +57,7 @@ public class TransformManager {
public void setTransform(@EntityInstance int i,
@NonNull @Size(min = 16) float[] localTransform) {
if (localTransform.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
Asserts.assertMat4fIn(localTransform);
nSetTransform(mNativeObject, i, localTransform);
}
@@ -67,7 +65,7 @@ public class TransformManager {
@Size(min = 16)
public float[] getTransform(@EntityInstance int i,
@Nullable @Size(min = 16) float[] outLocalTransform) {
outLocalTransform = assertMat4f(outLocalTransform);
outLocalTransform = Asserts.assertMat4f(outLocalTransform);
nGetTransform(mNativeObject, i, outLocalTransform);
return outLocalTransform;
}
@@ -76,7 +74,7 @@ public class TransformManager {
@Size(min = 16)
public float[] getWorldTransform(@EntityInstance int i,
@Nullable @Size(min = 16) float[] outWorldTransform) {
outWorldTransform = assertMat4f(outWorldTransform);
outWorldTransform = Asserts.assertMat4f(outWorldTransform);
nGetWorldTransform(mNativeObject, i, outWorldTransform);
return outWorldTransform;
}
@@ -89,13 +87,8 @@ public class TransformManager {
nCommitLocalTransformTransaction(mNativeObject);
}
@NonNull @Size(min = 16)
private static float[] assertMat4f(@Nullable float[] out) {
if (out == null) out = new float[16];
else if (out.length < 16) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
}
return out;
public long getNativeObject() {
return mNativeObject;
}
private static native boolean nHasComponent(long nativeTransformManager, int entity);

View File

@@ -31,13 +31,22 @@ public class VertexBuffer {
}
public enum VertexAttribute {
POSITION, // XYZ position (float3)
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
COLOR, // vertex color (float4)
UV0, // texture coordinates (float2)
UV1, // texture coordinates (float2)
POSITION, // XYZ position (float3)
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
COLOR, // vertex color (float4)
UV0, // texture coordinates (float2)
UV1, // texture coordinates (float2)
BONE_INDICES, // indices of 4 bones (uvec4)
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
BONE_WEIGHTS, // weights of the 4 bones (normalized float4)
UNUSED, // reserved for future use
CUSTOM0, // custom or MORPH_POSITION_0
CUSTOM1, // custom or MORPH_POSITION_1
CUSTOM2, // custom or MORPH_POSITION_2
CUSTOM3, // custom or MORPH_POSITION_3
CUSTOM4, // custom or MORPH_TANGENTS_0
CUSTOM5, // custom or MORPH_TANGENTS_1
CUSTOM6, // custom or MORPH_TANGENTS_2
CUSTOM7 // custom or MORPH_TANGENTS_3
}
public enum AttributeType {
@@ -197,7 +206,7 @@ public class VertexBuffer {
context.tangentsStride);
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed VertexBuffer");
}

View File

@@ -21,7 +21,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.Size;
import static com.google.android.filament.Colors.*;
import static com.google.android.filament.Colors.LinearColor;
public class View {
private long mNativeObject;
@@ -33,6 +33,7 @@ public class View {
private RenderQuality mRenderQuality;
private DepthPrepass mDepthPrepass = DepthPrepass.DEFAULT;
private AmbientOcclusionOptions mAmbientOcclusionOptions;
private RenderTarget mRenderTarget;
public static class DynamicResolutionOptions {
public boolean enabled = false;
@@ -147,7 +148,7 @@ public class View {
@NonNull @Size(min = 4)
public float[] getClearColor(@NonNull @Size(min = 4) float[] out) {
out = assertFloat4(out);
out = Asserts.assertFloat4(out);
nGetClearColor(getNativeObject(), out);
return out;
}
@@ -167,9 +168,15 @@ public class View {
}
public void setRenderTarget(@Nullable RenderTarget target) {
mRenderTarget = target;
nSetRenderTarget(getNativeObject(), target != null ? target.getNativeObject() : 0);
}
@Nullable
public RenderTarget getRenderTarget() {
return mRenderTarget;
}
public void setSampleCount(int count) {
nSetSampleCount(getNativeObject(), count);
}
@@ -291,7 +298,7 @@ public class View {
return mAmbientOcclusionOptions;
}
long getNativeObject() {
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed View");
}
@@ -302,15 +309,6 @@ public class View {
mNativeObject = 0;
}
@NonNull @Size(min = 4)
private static float[] assertFloat4(@Nullable float[] out) {
if (out == null) out = new float[4];
else if (out.length < 4) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
}
return out;
}
private static native void nSetName(long nativeView, String name);
private static native void nSetScene(long nativeView, long nativeScene);
private static native void nSetCamera(long nativeView, long nativeCamera);

View File

@@ -18,7 +18,6 @@ package com.google.android.filament.android;
import android.graphics.PixelFormat;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -27,6 +26,7 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import com.google.android.filament.SwapChain;
/**
@@ -58,7 +58,7 @@ import com.google.android.filament.SwapChain;
* mUiHelper = new UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK);
*
* // Attach the SurfaceView to the helper, you could do the same with a TextureView
* mUiHelper.attachTo(surfaceView)
* mUiHelper.attachTo(mSurfaceView);
*
* // Set a rendering callback that we will use to invoke Filament
* mUiHelper.setRenderCallback(new UiHelper.RendererCallback() {
@@ -95,15 +95,15 @@ import com.google.android.filament.SwapChain;
* }
*
* public void onDestroy() {
* super.onDestroy()
* super.onDestroy();
* // Always detach the surface before destroying the engine
* mUiHelper.detach()
* mUiHelper.detach();
*
* // This ensures that all the commands we've sent to Filament have
* // been processed before we attempt to destroy anything
* Fence.waitAndDestroy(mEngine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH);
*
* mEngine.destroy()
* mEngine.destroy();
* }
*
* // This is an example of a render function. You will most likely invoke this from
@@ -113,8 +113,8 @@ import com.google.android.filament.SwapChain;
* // If beginFrame() returns false you should skip the frame
* // This means you are sending frames too quickly to the GPU
* if (mRenderer.beginFrame(swapChain)) {
* mRenderer.render(mView)
* mRenderer.endFrame()
* mRenderer.render(mView);
* mRenderer.endFrame();
* }
* }
* }

12
android/gltfio-android/.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
.externalNativeBuild
/.cxx

View File

@@ -0,0 +1,102 @@
cmake_minimum_required(VERSION 3.6)
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
add_library(filament SHARED IMPORTED)
set_target_properties(filament PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament.a)
add_library(backend SHARED IMPORTED)
set_target_properties(backend PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbackend.a)
add_library(utils SHARED IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(filaflat SHARED 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 SHARED IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
add_library(filabridge SHARED IMPORTED)
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
add_library(gltfio SHARED IMPORTED)
set_target_properties(gltfio PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_core.a)
add_library(gltfio_resources SHARED IMPORTED)
set_target_properties(gltfio_resources PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources.a)
add_library(bluevk SHARED IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(smol-v SHARED 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)
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}/libgltfio-jni.map")
add_library(gltfio-jni SHARED
src/main/cpp/AssetLoader.cpp
src/main/cpp/FilamentAsset.cpp
src/main/cpp/KtxLoader.cpp
src/main/cpp/MaterialProvider.cpp
src/main/cpp/ResourceLoader.cpp
../common/CallbackUtils.cpp
../common/NioUtils.cpp
)
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
android
gltfio
gltfio_resources
filament
filabridge
backend
filaflat
geometry
image
ibl
utils
GLESv3
EGL
m
log
)
if (FILAMENT_SUPPORTS_VULKAN)
target_link_libraries(gltfio-jni bluevk smol-v)
endif()

View File

@@ -0,0 +1,90 @@
// This script accepts the following parameters:
//
// filament_dist_dir
// Path to the Filament distribution/install directory for Android
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
//
// Example:
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
group = "com.google.android.filament"
version = "1.3"
apply plugin: 'com.android.library'
def filament_path = file("../../out/android-release/filament").absolutePath
if (project.hasProperty("filament_dist_dir")) {
filament_path = file("$filament_dist_dir").absolutePath
}
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 14
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-19")
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
cppFlags.add("-std=c++14")
if (project.hasProperty('extra_cmake_args')) {
arguments.add(extra_cmake_args)
}
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jni.srcDirs "src/main/cpp"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:support-annotations:28.0.0'
implementation 'com.google.android.filament:filament-android'
}

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
android/gltfio-android/gradlew vendored Executable file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
android/gltfio-android/gradlew.bat vendored Normal file
View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

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

View File

@@ -0,0 +1 @@
_Java_com_google_android_filament_*

View File

@@ -0,0 +1,12 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user guide at https://docs.gradle.org/4.6/userguide/multi_project_builds.html
*/
includeBuild '../filament-android'
rootProject.name = 'gltfio-android'

View File

@@ -0,0 +1,18 @@
<!--
Copyright (C) 2019 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.gltfio" />

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <filament/Engine.h>
#include <utils/EntityManager.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/MaterialProvider.h>
#include "common/NioUtils.h"
using namespace filament;
using namespace gltfio;
using namespace utils;
extern void registerCallbackUtils(JNIEnv*);
extern void registerNioUtils(JNIEnv*);
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);
registerNioUtils(env);
return JNI_VERSION_1_6;
}
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});
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*, jclass,
jlong nativeLoader) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AssetLoader::destroy(&loader);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetFromBinary(JNIEnv* env, jclass,
jlong nativeLoader, jobject javaBuffer, jint remaining) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AutoBuffer buffer(env, javaBuffer, remaining);
return (jlong) loader->createAssetFromBinary((const uint8_t *) buffer.getData(),
buffer.getSize());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nEnableDiagnostics(JNIEnv*, jclass,
jlong nativeLoader, jboolean enable) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
loader->enableDiagnostics(enable);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAsset(JNIEnv*, jclass,
jlong nativeLoader, jlong nativeAsset) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
loader->destroyAsset(asset);
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <gltfio/FilamentAsset.h>
using namespace filament;
using namespace filament::math;
using namespace gltfio;
using namespace utils;
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetRoot(JNIEnv*, jclass, jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getRoot().getId();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntityCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getEntityCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetEntities(JNIEnv* env, jclass,
jlong nativeAsset, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getEntities(), asset->getEntityCount(), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetBoundingBox(JNIEnv* env, jclass,
jlong nativeAsset, jfloatArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
float* values = (float*) env->GetFloatArrayElements(result, nullptr);
const filament::Aabb box = asset->getBoundingBox();
const float3 center = box.center();
const float3 extent = box.extent();
values[0] = center.x;
values[1] = center.y;
values[2] = center.z;
values[3] = extent.x;
values[4] = extent.y;
values[5] = extent.z;
env->ReleaseFloatArrayElements(result, (jfloat*) values, 0);
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetName(JNIEnv* env, jclass,
jlong nativeAsset, jint entityId) {
uint32_t id = entityId;
Entity* entity = (Entity*) &id;
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* val = asset->getName(*entity);
return val ? env->NewStringUTF(val) : nullptr;
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <filament/Engine.h>
#include <filament/IndirectLight.h>
#include <filament/Skybox.h>
#include <image/KtxUtility.h>
#include "common/NioUtils.h"
using namespace filament;
using namespace filament::math;
using namespace image;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_KtxLoader_nCreateTexture(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
return (jlong) ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
delete bundle;
}, bundle);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_KtxLoader_nCreateIndirectLight(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
delete bundle;
}, bundle);
float3 harmonics[9];
bundle->getSphericalHarmonics(harmonics);
IndirectLight* indirectLight = IndirectLight::Builder()
.reflections(cubemap)
.irradiance(3, harmonics)
.intensity(30000)
.build(*engine);
return (jlong) indirectLight;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_KtxLoader_nCreateSkybox(JNIEnv* env, jclass,
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, javaBuffer, remaining);
KtxBundle* bundle = new KtxBundle((const uint8_t*) buffer.getData(), buffer.getSize());
Texture* cubemap = ktx::createTexture(engine, *bundle, srgb, [](void* userdata) {
KtxBundle* bundle = (KtxBundle*) userdata;
delete bundle;
}, bundle);
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
}

View File

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

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <filament/Engine.h>
#include <gltfio/ResourceLoader.h>
#include <utils/Log.h>
#include "common/NioUtils.h"
using namespace filament;
using namespace gltfio;
using namespace utils;
static void destroy(void* data, size_t size, void *userData) {
AutoBuffer* buffer = (AutoBuffer*) userData;
delete buffer;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateResourceLoader(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) new ResourceLoader({ engine, utils::Path(), true, true });
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyResourceLoader(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
delete loader;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAddResourceData(JNIEnv* env, jclass,
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,
ResourceLoader::BufferDescriptor(buffer->getData(), buffer->getSize(), &destroy,
buffer));
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nLoadResources(JNIEnv*, jclass,
jlong nativeLoader, jlong nativeAsset) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
loader->loadResources(asset);
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.filament.Engine;
import com.google.android.filament.EntityManager;
import com.google.android.filament.IndirectLight;
import com.google.android.filament.Skybox;
import com.google.android.filament.Texture;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.Buffer;
/**
* Consumes a blob of glTF 2.0 content (either JSON or GLB) and produces {@link FilamentAsset}
* objects, which are bundles of Filament entities, material instances, textures, vertex buffers,
* and index buffers.
*
* <p>AssetLoader does not fetch external buffer data or create textures on its own. Clients can use
* the provided {@link ResourceLoader} class for this, which obtains the URI list from the asset.
* This is demonstrated in the Kotlin snippet below.</p>
*
* <pre>
*
* companion object {
* init {
* Filament.init()
* AssetLoader.init()
* }
* }
*
* override fun onCreate(savedInstanceState: Bundle?) {
*
* ...
*
* assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
*
* filamentAsset = assets.open("models/lucy.glb").use { input ->
* val bytes = ByteArray(input.available())
* input.read(bytes)
* assetLoader.createAssetFromBinary(ByteBuffer.wrap(bytes))!!
* }
*
* ResourceLoader(engine).loadResources(filamentAsset).destroy()
* scene.addEntities(filamentAsset.entities)
* }
* </pre>
*
* @see FilamentAsset
* @see ResourceLoader
*/
public class AssetLoader {
private long mNativeObject;
static Method sEngineGetNativeObject;
static Method sEntityManagerGetNativeObject;
static Constructor<Texture> sTextureConstructor;
static Constructor<IndirectLight> sIndirectLightConstructor;
static Constructor<Skybox> sSkyboxConstructor;
/**
* Initializes the gltfio JNI layer. Must be called before using any gltfio functionality.
*/
public static void init() {
System.loadLibrary("gltfio-jni");
try {
sEngineGetNativeObject = Engine.class.getDeclaredMethod("getNativeObject");
sEngineGetNativeObject.setAccessible(true);
sEntityManagerGetNativeObject = EntityManager.class.getDeclaredMethod("getNativeObject");
sEntityManagerGetNativeObject.setAccessible(true);
sTextureConstructor = Texture.class.getDeclaredConstructor(long.class);
sTextureConstructor.setAccessible(true);
sIndirectLightConstructor = IndirectLight.class.getDeclaredConstructor(long.class);
sIndirectLightConstructor.setAccessible(true);
sSkyboxConstructor = Skybox.class.getDeclaredConstructor(long.class);
sSkyboxConstructor.setAccessible(true);
} catch (NoSuchMethodException e) {
// Cannot happen
}
}
/**
* Constructs an <code>AssetLoader </code>that can be used to create and destroy instances of
* {@link FilamentAsset}.
*
* @param engine the engine that the loader should pass to builder objects
* @param generator specifies if materials should be generated or loaded from a pre-built set
* @param entities the EntityManager that should be used to create entities
*/
public AssetLoader(@NonNull Engine engine, @NonNull MaterialProvider generator,
@NonNull EntityManager entities) {
try {
long nativeEngine = (long) sEngineGetNativeObject.invoke(engine);
long nativeMaterials = generator.getNativeObject();
long nativeEntities = (long) sEntityManagerGetNativeObject.invoke(entities);
mNativeObject = nCreateAssetLoader(nativeEngine, nativeMaterials, nativeEntities);
} catch (Exception e) {
// Ignored
}
if (mNativeObject == 0) {
throw new IllegalStateException("Unable to parse glTF asset.");
}
}
/**
* Frees all memory consumed by the native <code>AssetLoader</code> and its material cache.
*/
public void destroy() {
nDestroyAssetLoader(mNativeObject);
mNativeObject = 0;
}
/**
* Creates a {@link FilamentAsset} from the contents of a GLB file.
*/
@Nullable
public FilamentAsset createAssetFromBinary(@NonNull Buffer buffer) {
long nativeAsset = nCreateAssetFromBinary(mNativeObject, buffer, buffer.remaining());
return new FilamentAsset(nativeAsset);
}
/**
* Allows clients to enable diagnostic shading on newly-loaded assets.
*/
public void enableDiagnostics(boolean enable) {
nEnableDiagnostics(mNativeObject, enable);
}
/**
* Frees all memory associated with the given {@link FilamentAsset}.
*/
public void destroyAsset(@Nullable FilamentAsset asset) {
nDestroyAsset(mNativeObject, asset.getNativeObject());
asset.clearNativeObject();
}
private static native long nCreateAssetLoader(long nativeEngine, long nativeGenerator,
long nativeEntities);
private static native void nDestroyAssetLoader(long nativeLoader);
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);
private static native void nEnableDiagnostics(long nativeLoader, boolean enable);
private static native void nDestroyAsset(long nativeLoader, long nativeAsset);
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import android.support.annotation.NonNull;
import com.google.android.filament.Box;
import com.google.android.filament.Entity;
/**
* Owns a bundle of Filament objects that have been created by <code>AssetLoader</code>.
*
* <p>For usage instructions, see the documentation for {@link AssetLoader}.</p>
*
* <p>This class owns a hierarchy of entities that have been loaded from a glTF asset. Every entity has
* a <code>TransformManager</code> component, and some entities also have
* <code>NameComponentManager</code> and/or <code>RenderableManager</code> components.</p>
*
* <p>In addition to the aforementioned entities, an asset has strong ownership over a list of
* <code>VertexBuffer</code>, <code>IndexBuffer</code>, <code>MaterialInstance</code>, and
* <code>Texture</code>.</p>
*
* <p>Clients can use {@link ResourceLoader} to create textures, compute tangent quaternions, and
* upload data into vertex buffers and index buffers.</p>
*
* <p>TODO: <code>Animator</code> is not yet exposed to Java / Kotlin clients.</p>
*
* @see ResourceLoader
* @see AssetLoader
*/
public class FilamentAsset {
private long mNativeObject;
FilamentAsset(long nativeObject) {
mNativeObject = nativeObject;
}
long getNativeObject() {
return mNativeObject;
}
/**
* Gets the transform root for the asset, which has no matching glTF node.
*/
public @Entity int getRoot() {
return nGetRoot(mNativeObject);
}
/**
* 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>
*/
public @Entity int[] getEntities() {
int[] result = new int[nGetEntityCount(mNativeObject)];
nGetEntities(mNativeObject, result);
return result;
}
/**
* Gets the bounding box computed from the supplied min / max values in glTF accessors.
*/
public @NonNull Box getBoundingBox() {
float[] box = new float[6];
nGetBoundingBox(mNativeObject, box);
return new Box(box[0], box[1], box[2], box[3], box[4], box[5]);
}
/**
* Gets the <code>NameComponentManager<?code> label for the given entity, if it exists.
*/
public String getName(@Entity int entity) {
return nGetName(getNativeObject(), entity);
}
void clearNativeObject() {
mNativeObject = 0;
}
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 void nGetBoundingBox(long nativeAsset, float[] box);
private static native String nGetName(long nativeAsset, int entity);
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.google.android.filament.Engine;
import com.google.android.filament.IndirectLight;
import com.google.android.filament.Skybox;
import com.google.android.filament.Texture;
import java.nio.Buffer;
/**
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
*
* <p>KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
* into a single file.</p>
*/
public class KtxLoader {
public static class Options {
public boolean srgb;
}
/**
* Consumes the content of a KTX file and produces a {@link Texture} object.
*
* @param engine Gets passed to the builder.
* @param buffer The content of the KTX File.
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
@Nullable
public static Texture createTexture(@NonNull Engine engine, @NonNull Buffer buffer, @NonNull Options options) {
try {
long nativeEngine = (long) AssetLoader.sEngineGetNativeObject.invoke(engine);
long nativeTexture = nCreateTexture(nativeEngine, buffer, buffer.remaining(), options.srgb);
return AssetLoader.sTextureConstructor.newInstance(nativeTexture);
} catch (Exception e) {
return null;
}
}
/**
* Consumes the content of a KTX file and produces an {@link IndirectLight} object.
*
* @param engine Gets passed to the builder.
* @param buffer The content of the KTX File.
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
@Nullable
public static IndirectLight createIndirectLight(@NonNull Engine engine, @NonNull Buffer buffer, @NonNull Options options) {
try {
long nativeEngine = (long) AssetLoader.sEngineGetNativeObject.invoke(engine);
long nativeIndirectLight = nCreateIndirectLight(nativeEngine, buffer, buffer.remaining(), options.srgb);
return AssetLoader.sIndirectLightConstructor.newInstance(nativeIndirectLight);
} catch (Exception e) {
return null;
}
}
/**
* Consumes the content of a KTX file and produces a {@link Skybox} object.
*
* @param engine Gets passed to the builder.
* @param buffer The content of the KTX File.
* @param options Loader options.
* @return The resulting Filament texture, or null on failure.
*/
@Nullable
public static Skybox createSkybox(@NonNull Engine engine, @NonNull Buffer buffer, @NonNull Options options) {
try {
long nativeEngine = (long) AssetLoader.sEngineGetNativeObject.invoke(engine);
long nativeSkybox = nCreateSkybox(nativeEngine, buffer, buffer.remaining(), options.srgb);
return AssetLoader.sSkyboxConstructor.newInstance(nativeSkybox);
} catch (Exception e) {
return null;
}
}
private static native long nCreateTexture(long nativeEngine, Buffer buffer, int remaining, boolean srgb);
private static native long nCreateIndirectLight(long nativeEngine, Buffer buffer, int remaining, boolean srgb);
private static native long nCreateSkybox(long nativeEngine, Buffer buffer, int remaining, boolean srgb);
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import com.google.android.filament.Engine;
import java.lang.reflect.Method;
/**
* Loads pre-generated ubershader materials that fulfill glTF requirements.
*
* <p>This class is used by {@link AssetLoader} to create Filament materials.
* Client applications do not need to call methods on it.</p>
*/
public class MaterialProvider {
private long mNativeObject;
private static Method sEngineGetNativeObject;
static {
try {
sEngineGetNativeObject = Engine.class.getDeclaredMethod("getNativeObject");
sEngineGetNativeObject.setAccessible(true);
} catch (NoSuchMethodException e) {
// Cannot happen
}
}
/**
* Constructs an ubershader loader using the supplied {@link Engine}.
*
* @param engine the engine used to create materials
*/
public MaterialProvider(Engine engine) {
try {
long nativeEngine = (long) sEngineGetNativeObject.invoke(engine);
mNativeObject = nCreateMaterialProvider(nativeEngine);
} catch (Exception e) {
// Ignored
}
}
/**
* Frees memory associated with the native material provider.
* */
public void destroy() {
nDestroyMaterialProvider(mNativeObject);
mNativeObject = 0;
}
long getNativeObject() {
return mNativeObject;
}
private static native long nCreateMaterialProvider(long nativeEngine);
private static native void nDestroyMaterialProvider(long nativeProvider);
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltfio;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.filament.Engine;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.Buffer;
/**
* Uploads vertex buffers and textures to the GPU and computes tangents.
*
* <p>For a usage example, see the documentation for {@link AssetLoader}.</p>
*
* @see AssetLoader
* @see FilamentAsset
*/
public class ResourceLoader {
private final long mNativeObject;
private static Method sEngineGetNativeObject;
static {
try {
sEngineGetNativeObject = Engine.class.getDeclaredMethod("getNativeObject");
sEngineGetNativeObject.setAccessible(true);
} catch (NoSuchMethodException e) {
// Cannot happen
}
}
/**
* Constructs a resource loader tied to the given Filament engine.
*
* @param engine the engine that gets passed to all builder methods
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public ResourceLoader(@NonNull Engine engine) throws IllegalAccessException, InvocationTargetException {
long nativeEngine = (long) sEngineGetNativeObject.invoke(engine);
mNativeObject = nCreateResourceLoader(nativeEngine);
}
/**
* Frees all memory associated with the native resource loader.
*/
public void destroy() {
nDestroyResourceLoader(mNativeObject);
}
/**
* 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>
*
* <p>When loading GLB files (as opposed to JSON-based glTF files), clients typically do not
* need to call this method.</p>
*
* @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
* @return self (for daisy chaining)
*/
@NonNull
public ResourceLoader addResourceData(@NonNull String uri, @NonNull Buffer buffer) {
nAddResourceData(mNativeObject, uri, buffer, buffer.remaining());
return this;
}
/**
* 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>
*
* @param asset the Filament asset that contains URI-based resources
* @return self (for daisy chaining)
*/
@NonNull
public ResourceLoader loadResources(@NonNull FilamentAsset asset) {
nLoadResources(mNativeObject, asset.getNativeObject());
return this;
}
private static native long nCreateResourceLoader(long nativeEngine);
private static native void nDestroyResourceLoader(long nativeLoader);
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
int remaining);
private static native void nLoadResources(long nativeLoader, long nativeAsset);
}

View File

@@ -46,6 +46,12 @@ host machine:
![Material Builder](../../docs/images/samples/sample_image_based_lighting.jpg)
### `gltf-bloom`
Demonstrates how to load glTF models and render to an offscreen buffer:
![glTF Bloom](../../docs/images/samples/sample_gltf_bloom.jpg)
## Prerequisites
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to

12
android/samples/gltf-bloom/.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
/app/src/main/assets
.externalNativeBuild

View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,68 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply from: '../../../build/filament-tasks.gradle'
compileMaterials {
group 'Filament'
description 'Compile materials'
inputDir = file("src/main/materials")
outputDir = file("src/main/assets/materials")
}
task copyMesh(type: Copy) {
from file("../../../../third_party/models/lucy/lucy.glb")
into file("src/main/assets/models")
}
generateIbl {
group 'Filament'
description 'Generate IBL'
cmgenArgs = "--format=ktx --size=256 --extract-blur=0.1 --deploy=src/main/assets/envs"
inputFile = file("../../../../third_party/environments/venetian_crossroads_2k.hdr")
outputDir = file("src/main/assets/envs")
}
preBuild.dependsOn compileMaterials
preBuild.dependsOn copyMesh
preBuild.dependsOn generateIbl
clean.doFirst {
delete "src/main/assets"
}
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.google.android.filament.gltf"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Depend on Filament
implementation 'com.google.android.filament:filament-android'
implementation 'com.google.android.filament:gltfio-android'
}

View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.gltf">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name="com.google.android.filament.gltf.MainActivity" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltf
import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
fun readIntLE(input: InputStream): Int {
return input.read() and 0xff or (
input.read() and 0xff shl 8) or (
input.read() and 0xff shl 16) or (
input.read() and 0xff shl 24)
}
fun readFloat32LE(input: InputStream): Float {
val bytes = ByteArray(4)
input.read(bytes, 0, 4)
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).float
}
fun readUIntLE(input: InputStream): Long {
return readIntLE(input).toLong() and 0xFFFFFFFFL
}

View File

@@ -0,0 +1,580 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.gltf
import android.animation.ValueAnimator
import android.app.Activity
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.*
data class Framebuffer(
val camera: Camera,
val view: View,
val scene: Scene,
var color: Texture? = null,
var depth: Texture? = null,
var target: RenderTarget? = null)
class MainActivity : Activity() {
// Be sure to initialize not only Filament, but also gltfio (via AssetLoader)
companion object {
init {
Filament.init()
AssetLoader.init()
}
}
private lateinit var surfaceView: SurfaceView
private lateinit var uiHelper: UiHelper
private lateinit var choreographer: Choreographer
private lateinit var engine: Engine
private lateinit var renderer: Renderer
private lateinit var assetLoader: AssetLoader
private lateinit var filamentAsset: FilamentAsset
private lateinit var finalScene: Scene
private lateinit var finalView: View
private lateinit var finalCamera: Camera
private val kGaussianSampleCount = 9
private val kGaussianFilterSize = 1 + 2 * (kGaussianSampleCount - 1)
private val kGaussianWeights = FloatArray(kGaussianSampleCount * 4 * 2)
@Entity private var finalQuad = 0
@Entity private var hblurQuad = 0
@Entity private var vblurQuad = 0
private lateinit var primary: Framebuffer
private lateinit var hblur: Framebuffer
private lateinit var vblur: Framebuffer
private var quadVertBufferGpu: VertexBuffer? = null
private var quadIndxBufferGpu: IndexBuffer? = null
enum class ImageOp { MIX, HBLUR, VBLUR}
private lateinit var mixMaterial: Material
private lateinit var blurMaterial: Material
@Entity private var light = 0
private var swapChain: SwapChain? = null
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, (2.0 * PI).toFloat())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
computeGaussianWeights()
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.setDesiredSize(720, 1280)
uiHelper.attachTo(surfaceView)
engine = Engine.create()
renderer = engine.createRenderer()
primary = Framebuffer(engine.createCamera(), engine.createView(), engine.createScene())
primary.view.setName("primary")
primary.view.scene = primary.scene
primary.view.camera = primary.camera
primary.view.dithering = View.Dithering.NONE
primary.view.toneMapping = View.ToneMapping.LINEAR
hblur = Framebuffer(engine.createCamera(), engine.createView(), engine.createScene())
hblur.view.setName("hblur")
hblur.view.scene = hblur.scene
hblur.view.camera = hblur.camera
hblur.view.sampleCount = 1
hblur.view.isPostProcessingEnabled = false
vblur = Framebuffer(engine.createCamera(), engine.createView(), engine.createScene())
vblur.view.setName("vblur")
vblur.view.scene = vblur.scene
vblur.view.camera = vblur.camera
vblur.view.sampleCount = 1
vblur.view.isPostProcessingEnabled = false
finalScene = engine.createScene()
finalView = engine.createView()
finalView.setName("final")
finalCamera = engine.createCamera()
finalCamera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
finalView.scene = finalScene
finalView.camera = finalCamera
finalView.sampleCount = 1
// Materials
// ---------
readUncompressedAsset("materials/blur.filamat").let {
blurMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
readUncompressedAsset("materials/mix.filamat").let {
mixMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
// IndirectLight and SkyBox
// ------------------------
val ibl = "venetian_crossroads_2k";
readUncompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
primary.scene.indirectLight = KtxLoader.createIndirectLight(engine, it, KtxLoader.Options())
primary.scene.indirectLight!!.intensity = 50_000.0f
}
readUncompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
primary.scene.skybox = KtxLoader.createSkybox(engine, it, KtxLoader.Options())
}
val theta = PI * 2.7
val distance = 5.0
primary.camera.lookAt(
cos(theta) * distance , 0.0, sin(theta) * distance ,
0.0, -0.1, 0.0,
0.0, 1.0, 0.0)
// glTF Entities, Textures, and Materials
// --------------------------------------
assetLoader = AssetLoader(engine, MaterialProvider(engine), EntityManager.get())
filamentAsset = assets.open("models/lucy.glb").use { input ->
val bytes = ByteArray(input.available())
input.read(bytes)
assetLoader.createAssetFromBinary(ByteBuffer.wrap(bytes))!!
}
// Since this is a GLB file, the ResourceLoader does not need any additional files, and
// we can destroy it immediately.
ResourceLoader(engine).loadResources(filamentAsset).destroy()
primary.scene.addEntities(filamentAsset.entities)
val tm = engine.transformManager
tm.setTransform(tm.getInstance(filamentAsset.root),
floatArrayOf(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, -1.7f, 0.0f, 1.0f
))
val rm = engine.renderableManager
for (entity in filamentAsset.entities) {
val instance = rm.getInstance(entity)
val primCount = rm.getPrimitiveCount(instance)
for (primIndex in 0 until primCount) {
val mi = rm.getMaterialInstanceAt(instance, primIndex)
mi.setParameter("roughnessFactor", 0.1f)
mi.setParameter("baseColorFactor", 0.5f, 0.5f, 0.0f, 1.0f)
}
}
// Punctual Light Sources
// ----------------------
light = EntityManager.get().create()
val (r, g, b) = Colors.cct(6_500.0f)
LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(r, g, b)
.intensity(300_000.0f)
.direction(0.0f, -1.0f, 0.0f)
.castShadows(true)
.build(engine, light)
primary.scene.addEntity(light)
// Start Animation
// ---------------
animator.interpolator = LinearInterpolator()
animator.duration = 1_000_000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val v = 5.0f * PI.toFloat() * (a.animatedValue as Float)
tm.setTransform(tm.getInstance(filamentAsset.root),
floatArrayOf(
cos(v), 0.0f, -sin(v), 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
sin(v), 0.0f, cos(v), 0.0f,
0.0f, -1.7f, 0.0f, 1.0f
))
}
animator.start()
}
private fun initRenderTargets() {
val width = surfaceView.width
val height = surfaceView.height
android.util.Log.i("gltf-bloom", "RenderTarget objects are $width x $height.")
primary.color = Texture.Builder()
.width(width).height(height).levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA16F)
.build(engine)
primary.depth = Texture.Builder()
.width(width).height(height).levels(1)
.usage(Texture.Usage.DEPTH_ATTACHMENT)
.format(Texture.InternalFormat.DEPTH24)
.build(engine)
primary.target = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, primary.color)
.texture(RenderTarget.AttachmentPoint.DEPTH, primary.depth)
.build(engine)
hblur.color = Texture.Builder()
.width(width).height(height).levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA16F)
.build(engine)
hblur.target = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, hblur.color)
.build(engine)
vblur.color = Texture.Builder()
.width(width).height(height).levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA16F)
.build(engine)
vblur.target = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, vblur.color)
.build(engine)
hblurQuad = createQuad(engine, ImageOp.HBLUR, primary.color!!)
vblurQuad = createQuad(engine, ImageOp.VBLUR, hblur.color!!)
finalQuad = createQuad(engine, ImageOp.MIX, primary.color!!, vblur.color)
hblur.scene.addEntity(hblurQuad)
vblur.scene.addEntity(vblurQuad)
finalScene.addEntity(finalQuad)
primary.view.viewport = Viewport(0, 0, width, height)
primary.view.renderTarget = primary.target
hblur.view.viewport = Viewport(0, 0, width, height)
hblur.view.renderTarget = hblur.target
hblur.camera.setProjection(Camera.Projection.ORTHO, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0)
vblur.view.viewport = Viewport(0, 0, width, height)
vblur.view.renderTarget = vblur.target
vblur.camera.setProjection(Camera.Projection.ORTHO, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0)
finalView.viewport = Viewport(0, 0, width, height)
finalCamera.setProjection(Camera.Projection.ORTHO, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0)
}
@Entity private fun createQuad(engine: Engine, op: ImageOp, primary: Texture, secondary: Texture? = null): Int {
if (quadVertBufferGpu == null) {
val vb = VertexBuffer.Builder()
.vertexCount(4)
.bufferCount(1)
.attribute(VertexBuffer.VertexAttribute.POSITION, 0, VertexBuffer.AttributeType.FLOAT2, 0, 16)
.attribute(VertexBuffer.VertexAttribute.UV0, 0, VertexBuffer.AttributeType.FLOAT2, 8, 16)
.build(engine)
data class Vertex(val x: Float, val y: Float, val u: Float, val v: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.u)
putFloat(v.v)
return this
}
val quadVertexBuffer = ByteBuffer.allocateDirect(16 * 4)
.order(ByteOrder.nativeOrder())
.put(Vertex(0f, 0f, 0f, 0f))
.put(Vertex(1f, 0f, 1f, 0f))
.put(Vertex(0f, 1f, 0f, 1f))
.put(Vertex(1f, 1f, 1f, 1f))
.flip()
vb.setBufferAt(engine, 0, quadVertexBuffer)
quadVertBufferGpu = vb
}
val vb = quadVertBufferGpu!!
////////////////////////////////////////////////////////////////////
if (quadIndxBufferGpu == null) {
val ib = IndexBuffer.Builder()
.indexCount(6)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
data class Triangle(val x: Short, val y: Short, val z: Short)
fun ByteBuffer.put(t: Triangle): ByteBuffer {
putShort(t.x)
putShort(t.y)
putShort(t.z)
return this
}
val buf = ByteBuffer.allocateDirect(6 * 2)
.order(ByteOrder.LITTLE_ENDIAN)
.put(Triangle(2, 1, 0))
.put(Triangle(1, 2, 3))
.flip()
ib.setBuffer(engine, buf)
quadIndxBufferGpu = ib
}
val ib = quadIndxBufferGpu!!
////////////////////////////////////////////////////////////////////
val sampler = TextureSampler(TextureSampler.MinFilter.LINEAR, TextureSampler.MagFilter.LINEAR, TextureSampler.WrapMode.CLAMP_TO_EDGE)
val material = when (op) {
ImageOp.HBLUR -> {
// Extract the first half of the weights array for the horizontal pass.
this.blurMaterial.createInstance().apply {
setParameter("weights", MaterialInstance.FloatElement.FLOAT4, kGaussianWeights, 0, kGaussianSampleCount)
setParameter("passIndex", 0)
}
}
ImageOp.VBLUR -> {
// Extract the second half of the weights array for the vertical pass.
this.blurMaterial.createInstance().apply {
setParameter("weights", MaterialInstance.FloatElement.FLOAT4, kGaussianWeights, kGaussianSampleCount, kGaussianSampleCount)
setParameter("passIndex", 1)
}
}
ImageOp.MIX -> {
this.mixMaterial.createInstance().apply {
setParameter("secondary", secondary!!, sampler)
}
}
}
material.setParameter("color", primary, sampler)
val entity = EntityManager.get().create()
RenderableManager.Builder(1)
.boundingBox(Box(0.0f, 0.0f, 0.0f, 9000.0f, 9000.0f, 9000.0f))
.geometry(0, RenderableManager.PrimitiveType.TRIANGLES, vb, ib)
.material(0, material)
.build(engine, entity)
return entity
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
// Stop the animation and any pending frame
choreographer.removeFrameCallback(frameScheduler)
animator.cancel();
// Always detach the surface before destroying the engine
uiHelper.detach()
// This ensures that all the commands we've sent to Filament have
// been processed before we attempt to destroy anything
engine.flushAndWait()
assetLoader.destroyAsset(filamentAsset)
assetLoader.destroy()
engine.destroyEntity(light)
engine.destroyRenderer(renderer)
engine.destroyView(finalView)
engine.destroyScene(finalScene)
engine.destroyCamera(finalCamera)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
if (uiHelper.isReadyToRender) {
if (renderer.beginFrame(swapChain!!)) {
renderer.render(primary.view)
renderer.render(hblur.view)
renderer.render(vblur.view)
renderer.render(finalView)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
}
override fun onDetachedFromSurface() {
swapChain?.let {
engine.destroySwapChain(it)
// Required to ensure we don't return before Filament is done executing the
// destroySwapChain command, otherwise Android might destroy the Surface
// too early
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
// Lazily create RenderTarget objects, now that we know the size of the view.
if (primary.color == null) {
initRenderTargets()
}
val aspect = width.toDouble() / height.toDouble()
primary.camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
primary.view.viewport = Viewport(0, 0, width, height)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
private fun computeGaussianWeights() {
val filter = fun(t0: Float): Float {
val t = t0 / 2.0f
if (t >= 1.0) return 0.0f
val scale = 1.0f / sqrt(0.5f * PI.toFloat())
return exp(-2.0f * t * t) * scale
}
val pixelWidth = 2.0f / kGaussianFilterSize.toFloat()
var sum = 0.0f
repeat (kGaussianSampleCount) { s ->
// Determine which two texels to sample from.
val i: Int
val j: Int
when {
s < kGaussianSampleCount/ 2 -> {
i = s * 2
j = i + 1
}
s == kGaussianSampleCount/ 2 -> {
j = s * 2
i = j
}
else -> {
j = s * 2
i = j - 1
}
}
// Determine the normalized (x,y) along the Gaussian curve for each of the two samples.
val weighti = filter(abs(-1.0f + pixelWidth / 2.0f + pixelWidth * i))
val weightj = filter(abs(-1.0f + pixelWidth / 2.0f + pixelWidth * j))
val offseti = i - (kGaussianFilterSize - 1) / 2
// Leverage hardware interpolation by sampling between the texel centers.
// Nudge the left sample rightward by an amount proportional to its weight.
val offset = offseti + weightj / (weighti + weightj)
val weight = weighti + weightj
kGaussianWeights[s * 4 + 0] = weight
kGaussianWeights[s * 4 + 1] = offset
kGaussianWeights[s * 4 + 2] = 0.0f
kGaussianWeights[s * 4 + kGaussianSampleCount * 4 + 0] = weight
kGaussianWeights[s * 4 + kGaussianSampleCount * 4 + 2] = offset
kGaussianWeights[s * 4 + kGaussianSampleCount * 4 + 1] = 0.0f
sum += kGaussianWeights[s * 4]
}
repeat (kGaussianSampleCount) { s ->
kGaussianWeights[s * 4 + 0] /= sum
kGaussianWeights[s * 4 + kGaussianSampleCount * 4 + 0] /= sum
}
}
}

View File

@@ -0,0 +1,22 @@
material {
name : blit,
shadingModel : unlit,
depthWrite: false,
depthCulling: false,
parameters : [
{
type : sampler2d,
name : color
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_color, getUV0());
}
}

View File

@@ -0,0 +1,49 @@
material {
name : blur,
shadingModel : unlit,
depthWrite: false,
depthCulling: false,
parameters : [
{
type : sampler2d,
name : color
},
{
type : float4[9],
name : weights
},
{
type : int,
name : passIndex
}
],
requires: [
uv0
]
}
fragment {
const int kGaussianSampleCount = 9;
const float kReinhardWeight = 5.0;
vec3 Tonemap_ReinhardWeighted(const vec3 x, float weight) {
// Weighted Reinhard tone-mapping operator designed for post-processing
// This tone-mapping operator is invertible
return x * (weight / (max3(x) + 1.0));
}
void material(inout MaterialInputs material) {
prepareMaterial(material);
vec3 c = vec3(0);
for (int i = 0; i < kGaussianSampleCount; i++) {
float2 st = getUV0() + materialParams.weights[i].yz * getResolution().zw;
vec3 color = texture(materialParams_color, st).rgb;
if (materialParams.passIndex == 0) {
color = Tonemap_ReinhardWeighted(color, kReinhardWeight);
}
c += color * materialParams.weights[i].x;
}
material.baseColor.rgb = c;
}
}

View File

@@ -0,0 +1,50 @@
material {
name : mix,
shadingModel : unlit,
depthWrite: false,
depthCulling: false,
parameters : [
{
type : sampler2d,
name : color
},
{
type : sampler2d,
name : secondary
}
],
requires: [
uv0
]
}
fragment {
const float kReinhardWeight = 5.0;
vec3 Tonemap_ReinhardWeighted(const vec3 x, float weight) {
// Weighted Reinhard tone-mapping operator designed for post-processing
// This tone-mapping operator is invertible
return x * (weight / (max3(x) + 1.0));
}
vec3 Tonemap_ReinhardWeighted_Invert(const vec3 x) {
// Inverse Reinhard tone-mapping operator, designed to be used in conjunction
// with the weighted Reinhard tone-mapping operator
return x / (1.0 - max3(x));
}
void material(inout MaterialInputs material) {
prepareMaterial(material);
vec3 primary = texture(materialParams_color, getUV0()).rgb;
primary = Tonemap_ReinhardWeighted(primary, kReinhardWeight);
vec3 blurred = texture(materialParams_secondary, getUV0()).rgb;
// HACK: this is a crude bloom effect
float brightness = max(blurred.r, max(blurred.g, blurred.b));
float soft_mask = smoothstep(1.5, 2.0, brightness);
material.baseColor.rgb = mix(primary, blurred, soft_mask);
material.baseColor.rgb = Tonemap_ReinhardWeighted_Invert(material.baseColor.rgb / kReinhardWeight);
}
}

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">gltf bloom</string>
</resources>

View File

@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -0,0 +1,13 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

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