Compare commits

..

149 Commits

Author SHA1 Message Date
Mathias Agopian
ae6ab66af4 fix #755: a race condition cousing a deadlock
This reverts a JobSystem optimization that attempted to avoid signaling
a condition when there was no waiters. Unfortunately, there was a
race that caused the the signaling thread to miss that the waiter flag
was set, thus not signaling.
2019-01-29 15:40:25 -08:00
Ben Doherty
7be3994c96 Add Metal shading language compilation to matc (#752) 2019-01-29 12:44:58 -07:00
Ben Doherty
836b641bff Add filamat-jni to CMake and build.sh (#740) 2019-01-29 12:34:04 -07:00
Tim van Scherpenzeel
44bfac85e9 added quiet flag 2019-01-29 11:04:58 -08:00
Romain Guy
a141abd212 Fix Kotlin compilation error 2019-01-29 09:39:00 -08:00
Romain Guy
12aba0f1b7 Code cleanup 2019-01-29 09:36:18 -08:00
Philip Rideout
40666bdd23 HwTexture now remembers the format.
We were stashing the GL format but not the Filament format.

This simplifies VulkanTexture and will allow us to implement a very
simple mipmap generator in DriverBase.

Motivated by #749.
2019-01-29 08:59:36 -08:00
Romain Guy
66d71be300 Fix HDR ImageDecoder for width < 8 or > 32767 2019-01-28 15:16:53 -08:00
Romain Guy
614a832be0 Code cleanup in ImageDecoder.cpp 2019-01-28 15:16:53 -08:00
Ben Doherty
92de93bfb8 Add Metal skeleton code (#714) 2019-01-28 15:29:37 -07:00
Romain Guy
c1b7f2ac27 Property write small .hdr files (#750)
* Cleanup ImageEncoder code

* Properly write HDR files when width < 8 or > 32767

A little oddity in the original Radiance file format encoding.
2019-01-28 14:02:28 -08:00
Philip Rideout
6110809d23 JNI fix for badly-sized PixelBufferDescriptors. (!)
Amazingly, the size field in PixelBufferDescriptor was often totally
incorrect for Java-based clients. The reason we did not notice: OpenGL
often consumes a pointer to image data without consuming a byte count
(e.g. glTexImage2D).

OpenGL infers size from dimensions + format, but Vulkan does not. This
caused texture corruption with Vulkan on Android.

This fix follows a pattern used in other places such as
FRenderer::readPixels.
2019-01-26 09:59:06 -08:00
Romain Guy
81a52411ed Clarify Fresnel term for IBL implementation of clear coat 2019-01-25 13:49:44 -08:00
cubeleo
6956154d62 mipgen: Disambiguated string with std:: prefix. (#741) 2019-01-25 09:02:11 -08:00
prideout
9940a68165 Stipulate clang 7 in README to align with Kokoro. 2019-01-24 12:06:00 -08:00
Philip Rideout
c3d957671d Work around FXAA issue with Vulkan Adreno drivers.
Fixes #732.
2019-01-24 11:48:02 -08:00
Mathias Agopian
fbb7e1f2ef Use a linear allocator for all our std::vector<> 2019-01-23 19:14:28 -08:00
Mathias Agopian
6e90d73e24 fix PassNode move ctor 2019-01-23 19:14:28 -08:00
Mathias Agopian
07c1dbb5f4 fix typo causing a memory corruption in STLAllocator<>
We were allocating n*sizeof(n) instead of n*sizeof(T). Thankfully, 
we were not using STLAllocator anywhere.
2019-01-23 19:14:28 -08:00
Philip Rideout
4e0749f0ae Add another folder to the build's "clean" task.
Gradle creates a hidden .externalNativeBuild folder when issuing CMake
for the first time. This folder contains cached command line parameters
that get passed to CMake, and these can become stale when switching
between "normal" Android builds and Vulkan-enabled Android builds, which
leads to frustrating build errors.
2019-01-23 17:12:56 -08:00
Ben Doherty
f5bd28b7df Update linux README with CXXFLAGS (#736) 2019-01-23 16:39:34 -08:00
Ben Doherty
ad4c4148f4 Add filamat-jni Gradle project (#733) 2019-01-23 13:58:43 -08:00
Mathias Agopian
a35762bdf2 compute discard flags for all attachments 2019-01-22 10:49:22 -08:00
Mathias Agopian
1ca2b1b642 calculate rendertarget's discard flags properly 2019-01-22 10:49:22 -08:00
Mathias Agopian
373e519292 slog.* << io::hex now prefixes values with 0x 2019-01-22 10:49:22 -08:00
Mathias Agopian
acea32aae8 more validation in the framegraph
- validate that a pass actually uses a resource when requesting the
  concrete (Driver) handle.

- introduce a "blit" usage for a resource, which indicates that a 
  resource will be used as the source of a blit operation. This is
  unfortunatelly needed because blit operations work on rendertargets,
  not textures for the source.
2019-01-22 10:49:22 -08:00
Mathias Agopian
150fd321bc FrameGraph API improvements
- de-dup read/writes to the same resource from the same pass

- also, when reading & writing into the same resource from the same pass,
  always order the read before the write, i.e.:
     out = builder.write(r);
     in  = builder.read(out);
  is equivalent to:
     in  = builder.read(r);
     out = builder.write(in);

  note that the following is still not allowed:
     out = builder.write(r);
     in  = builder.read(r);
  
  this is never valid, since it's reading from a resource that has
  been written to. 


- Make FrameGraphResource class attributes private and add
  comparison operators (so they could be sorted and compared).
2019-01-22 10:49:22 -08:00
prideout
1bbe203a15 Add RGB support to VulkanDriver. 2019-01-22 09:56:27 -08:00
prideout
37201e742f Add missing locks to VulkanDriver. 2019-01-18 16:50:52 -08:00
prideout
ba8adc2d49 Fix test filter syntax. 2019-01-18 16:21:26 -08:00
Ben Doherty
d3efbd810e Add Android build instructions on Windows (#726) 2019-01-18 14:47:23 -08:00
prideout
91c946cfbd Add workaround for depth invariance on NVIDIA.
Fixes #645.
2019-01-18 13:59:22 -08:00
prideout
98d39b7e7e Revert "Fix depth prepass (#722)"
This reverts commit 896c85c324.
2019-01-18 13:59:22 -08:00
Mathias Agopian
e7169cb889 fix CI build 2019-01-18 13:55:19 -08:00
Mathias Agopian
8f70f8f879 fix a few typos 2019-01-18 13:07:54 -08:00
Mathias Agopian
8c6ac11c2d Optionally use the framegraph for post-processing
There is still a lot of work to do on the frame-graph, which is why
this is off by default for now.
2019-01-18 13:07:54 -08:00
Mathias Agopian
d9bebaa8e7 framegraph now supports imported resources 2019-01-18 13:07:54 -08:00
Mathias Agopian
5baa699c7c Add support for creating concrete resources
- Tweak the API a bit.
- We can now create concrete textures and render-targets
2019-01-18 13:07:54 -08:00
Mathias Agopian
8c8cfb6528 Frame graph API
This is only the guts of the frame graph implementation. It supports
culling of passes, but doesn't create real resources yet.

API still in flux.
2019-01-18 13:07:54 -08:00
Mathias Agopian
f1c6acafff Tweak to PostProcessManager::setSource()
setSource() is a bit more generic now.
2019-01-18 13:07:54 -08:00
Philip Rideout
03161226f2 Update MoltenVK and tweak queue selection strategy.
These changes are sufficient to resurrect Vulkan-on-macOS, at least for
the vk_hellopbr sample.
2019-01-18 12:21:50 -08:00
Ben Doherty
4d0859b266 Update Android toolchains for building on Windows (#723) 2019-01-18 09:31:03 -08:00
Romain Guy
896c85c324 Fix depth prepass (#722)
The engine tries to be smart by using a single vertex shader when
rendering unskinned, non-alpha masked, non-customized materials.
This leads to a lot of issues when laying down the depth prepass.
This change simply gets rid of this optimization (which wasn't
properly profiled anyway). Correctness is more important.

Fixes #645
2019-01-17 17:57:43 -08:00
Philip Rideout
49f1464016 Fix diabolical VAO state management bug.
When clients deleted renderables that referred to index buffers that
were still active, it was possible for our shadow ELEMENT_ARRAY_BUFFER
binding to get out of sync with the actual binding.

It is somewhat amazing that this has never caused issues before. Perhaps
it is rare for clients to "recycle" index buffers across multiple
renderable lifetimes.

This fixes #718.
2019-01-17 14:44:34 -08:00
Romain Guy
c8b3544a36 Update README 2019-01-17 12:13:43 -08:00
Romain Guy
321845d04a Update README 2019-01-17 12:11:20 -08:00
Romain Guy
a31928600e Update README 2019-01-17 12:10:39 -08:00
Romain Guy
f3752a42c8 Document UV flipping behavior and add control attribute (#720)
Materials can disbale this behavior by setting flipUV: false
in the header section of the material definition.

Fixes #672
2019-01-17 11:12:16 -08:00
Philip Rideout
2f35f26148 VertexBuffer builder normalized now accepts "false". 2019-01-17 06:09:17 -08:00
Philip Rideout
d47e6f9456 Remove presubmit test. 2019-01-16 16:28:30 -08:00
Philip Rideout
6bb385f354 Repair web builds, second attempt. 2019-01-16 16:26:57 -08:00
Philip Rideout
dd7af66516 Repair kokoro web builds. 2019-01-16 15:56:37 -08:00
Philip Rideout
04f3268961 Introduce test to ensure buildability of TypeScript declarations. 2019-01-16 14:31:42 -08:00
Philip Rideout
a3c939894c Add more JavaScript bindings and TypeScript annotations.
The following type bindings are now complete:

 - RenderableManager
 - RenderableManager$Builder
 - RenderableManager$Bone
 - TransformManager
 - Box, Camera, Frustum
2019-01-16 14:31:42 -08:00
Ben Doherty
b460d2f547 Fix resizing metal layer crash with OpenGL (#713) 2019-01-16 11:55:51 -08:00
Ben Doherty
9ea81bc2fd Resize Metal layer (#710) 2019-01-15 16:51:09 -08:00
Romain Guy
cebc83e8fa Fix the Android filamesh file loader (#709)
* Fix the Android filamesh file loader

The loader was not updated to support the SNORM16 format now sometimes
used to encode UV sets in filamesh files.

Fixes #708

* Update android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/MeshLoader.kt
2019-01-15 16:11:34 -08:00
Ben Doherty
b3cd6a7f59 Add initial MaterialBuilder JNI (#707)
* Add initial MaterialBuilder JNI

* Move into android/filamat-android
2019-01-15 16:07:42 -08:00
Romain Guy
c8f5190099 Fix Windows build 2019-01-15 15:13:13 -08:00
Romain Guy
28ab087f79 Revert doubleSided hack in glTF loading 2019-01-15 14:17:22 -08:00
Romain Guy
e66aeb0c94 Fix a couple of glTF issues: (#706)
- baseColorFactor.a was not taken into account
- Some glTF files do not set `doubleSided` properly, so here we assume
  that non-opaque materials are double-sided. We may need to revisit
  this decision later...
2019-01-15 10:26:20 -08:00
Philip Rideout
749817b64b Add the official TypeScript annotations for gl-matrix to third_party.
Filament supports (but does not require) gl-matrix, and our TypeScript
annotations will need to use this file to support clients that use
gl-matrix.
2019-01-15 23:22:06 +05:30
Philip Rideout
1b18724b6b Add TypeScript to Kokoro for web for testing.
This preps for an upcoming regression test that ensures our TypeScript
annotations are valid.
2019-01-15 23:21:57 +05:30
Romain Guy
ff5a2a7a99 Peek the right dimensions for the IBL in Android samples (#704)
Fixes #701
2019-01-15 09:47:41 -08:00
Philip Rideout
125f79e5e0 Allow Java / Kotlin to enable the experimental Vulkan backend.
We still do not compile the Vulkan backend for Android by default, this
simply makes it possible to use the samples on Vulkan with a one-line
change, which is useful for testing purposes.

This change also makes it so that the materials used for the samples
include SPIR-V. This makes them fatter but they are merely samples.

I still consider Vulkan on Android to be experimental, there are some
features that need to be implemented.
2019-01-15 23:00:18 +05:30
Romain Guy
fac084dfdf Update Markdeep to latest version (2018/12) 2019-01-14 15:53:14 -08:00
Romain Guy
f8ebc047e0 Fix the build 2019-01-14 15:31:17 -08:00
Romain Guy
00f6fa24f7 Code cleanup 2019-01-14 14:57:23 -08:00
Romain Guy
0394aeb23b Add specular anti-aliasing properties to materials (#697)
* Add specular anti-aliasing properties to materials

curvatureToRoughness
limitOverInterpolation

These techiques were supposed to be enabled by default on
desktop but it turns out they were broken. They must now
be enabled manually on each material instead (and work on
mobile).

* Update docs/Materials.md.html
2019-01-14 12:25:51 -08:00
Romain Guy
c4989da047 Upgrade sample projects to Android Studio 3.3 (#700) 2019-01-14 11:50:44 -08:00
Ben Doherty
60363e518d Remove Metal layer hack for MoltenVK (#693)
* Remove Metal layer hack for MoltenVK

* Remove define

* Remove call to displaySyncEnabled
2019-01-14 10:35:26 -08:00
Damianno19
2a74397101 Incorrect order of arguments in glBlendFuncSeparate function call (#698) 2019-01-12 11:56:30 -08:00
Ben Doherty
0cccbda9b9 Move call to endFrame after commit (#696) 2019-01-11 15:42:34 -08:00
Ben Doherty
0c1fdc88ec Fix iOS hello-triangle sample (#694) 2019-01-11 13:48:00 -08:00
Philip Rideout
8228deb209 Add a multi-material model and JS demo.
This is a more complex test than suzanne because it has multiple
materials and exercises the named materials functionality in
loadFilamesh.

This also exercises our glTF-to-Filamesh pipeline at build time.

See issue #663
2019-01-11 09:18:41 +05:30
Romain Guy
8029ad5cc3 Add missing getWorldFromClip() API (#692)
Fixes #671
2019-01-10 16:35:00 -08:00
Ben Doherty
045274bbdb Use glslminifier to minifiy shaders for Release builds (#690) 2019-01-10 10:23:23 -08:00
Pixelflinger
206512add0 this fix clean builds when using make 2019-01-10 09:04:58 -08:00
Philip Rideout
f876171239 filamesh tool now generates dummy UV's if necessary.
filamesh requires UV's but some glTF test models, like CesiumMilkTruck,
do not provide UV's on nonlit parts (e.g. the truck windows). This makes
it so that these assets can be converted to filamesh somewhat more
gracefully.
2019-01-10 10:27:29 +05:30
Philip Rideout
f96501215b Reduce number of texture lookups in gltf_viewer. 2019-01-10 08:17:30 +05:30
Philip Rideout
0158e7e858 JS API: loadFilamesh can now return material names.
See issue #663
2019-01-10 07:48:19 +05:30
Ben Doherty
c6444fb502 Move sampler bindings outside of material blobs (#682) 2019-01-09 11:25:51 -08:00
Ben Doherty
60d304a83b Add glslminifier tool (#683) 2019-01-09 10:59:39 -08:00
Philip Rideout
422bf8631b Small assimp fixups for glTF => filamesh conversion.
This fixes some crashes when trying to convert CesiumMilkTruck.
2019-01-09 07:57:41 +05:30
Ben Doherty
013d735242 Destroy engine's default material (#681) 2019-01-08 13:40:02 -08:00
Romain Guy
3be10d816a Cleanup recent change to ImageOps (#678)
* Cleanup recent change to ImageOps

* Add missing sign
2019-01-08 07:20:20 -08:00
Romain Guy
9ce88e6e23 Improve skygen (#679)
Bring back the normalization and gamma correction command line flags,
render the ground in the lower half of the image.
2019-01-08 07:19:50 -08:00
nicebyte
83c40e6664 Make 4-channel versions of certain image operations. (#676)
Background: with the Vulkan backend, RGB8 textures do
not work (at least not on my hadrware). This makes me unable to run some
examples, because they use normal maps in RGB8 format.

It appears that the following commit addresses the problem by adding a
special command line option to mipgen:
8dda07bf2c

However, processing normal maps with this option does not work: certain
assertions in the image library fail.

This PR changes these functions in the image library to handle 4-channel
images instead of failing.
2019-01-07 15:16:00 -08:00
gstanlo
28f2806beb Improves linear to srgb conversion functions (#675)
* Improves linear to s/rgb

Adds rounding to nearest whole integer, supports copying over an alpha channel for linear to srgb conversion. Code would previously incorrectly apply sRGB conversion to alpha.

* reformatting previous change
2019-01-04 10:46:20 -08:00
shartte
d37e21f4ea Use different capacities for lights and renderables since there's always gonna be a light, even if there are no entities (#666) 2019-01-04 08:11:37 -08:00
Ben Doherty
d113af8afb Add return 0 to main functions to avoid crashes on Windows (#674) 2019-01-03 16:59:34 -08:00
shartte
f676d3d3ea Add constexpr constructor to StaticString (#659)
Fixes a header usage problem for MSVC, which complains about StaticString not having a constexpr constructor thus making the "make" method not constexpr.
2018-12-24 08:51:18 +01:00
shartte
cd2786a2ef Fixes #653: Skin normals/tangents before applying world space transform (#656) 2018-12-24 08:50:29 +01:00
shartte
5ea35ab87e Removed outdated documentation about static lights (#662) 2018-12-22 15:57:15 +01:00
gstanlo
c21d11e20f Fixes LinearImage memory leak (#658)
LinearImage leaks memory if assigned to itself, this ensures the old LinearImage::SharedReference object will be deleted first
2018-12-21 06:42:52 +01:00
Ben Doherty
8fe11a067d Include unwindows in Frustum and DriverEnums (#649)
* Include unwindows in Frustum and DriverEnums

* Distribute unwindows.h
2018-12-17 18:20:32 -08:00
Ben Doherty
67ffa91843 Fix Windows Debug builds (#648)
* Fix Windows Debug builds

* Use NDEBUG for Noop driver files
2018-12-17 17:15:22 -08:00
Ben Doherty
55fbb300ca Update README for VS 2017 (#647) 2018-12-17 14:00:43 -08:00
Romain Guy
4901f6f72a Fix FXAA computations in mediump (#643)
* Fix FXAA computations in mediump

UV coordinates computed in highp should be passed to the FXAA function
in highp as well. This change also fixes a potential division by 0 which
was causing dir1 to have components set to inifinity, thus breaking the
texture sampling calls below. We fix this with an early exit when a
potential division by 0 is detected. The original code contained a bias
to try to avoid this problem but that bias was not always enough. It
was frequent in mediump to cancel out the bias.

* Update shaders/src/fxaa.fs

Co-Authored-By: romainguy <romainguy@curious-creature.com>
2018-12-14 22:48:26 -08:00
Mathias Agopian
cfb9c03226 Improve JobSystem, especially under contention
- only signal waitAndRelease() when the corresponding job finishes and
only if there is waitAndRelease() active -- instead of signaling 
every time a job ends.

- don't surrender time slice when attempting to steal a job and it fails
as long as some queue has jobs.

- check that we have to wait, because taking the lock

- add a benchmark

This change more than doubles the amount of jobs we can handle per
second (~965,000 jobs/s on Pixel3)
2018-12-14 16:01:17 -08:00
Mathias Agopian
d6de2bf426 get rid of JobSystem::reset()
It was only used to clear the master job, instead the master job is
cleared when waited on.
2018-12-14 14:48:33 -08:00
Ben Doherty
b5eb00bdb1 Fix shaders compilation with VS (#641) 2018-12-14 14:03:35 -08:00
Romain Guy
ede9f7fdbb Speedup Android builds
We don't need libfilamat/spirv*/glslang for now. They greatly
reduce the time it takes to build our Android targets. We
may want to create a separate CI profile for filamat actually.
2018-12-13 16:03:39 -08:00
Romain Guy
eaf790aaa7 Improve rendering to TextureView (#635)
* Improve rendering to TextureView

UiHelper wasn't calling the resize callback at init time when attaching
to a TextureView, but it was for a SurfaceView. This makes both code
paths consistent and fixes the standard samples if they are modified to
render to a TextureView.

This change also adds a new sample app that shows how to render into
a TextureView.

* Suppress warning

* Suppress another warning
2018-12-13 15:57:15 -08:00
Mathias Agopian
02b0eb3ae2 fix a potential crasher when copying the camera stream
there was a very small race, where we would dereference a pointer
that might not be set yet.
2018-12-13 10:51:28 -08:00
Mathias Agopian
e38870ebf5 Improve JobSystem::wait
JobSystem::waitAndRelease used to spin to wait for the job to finish,
usually this wasn't a problem because the spinning thread was
able to handle other jobs. However, in cases where no job was
available it would actually spin in burn cpu cycles.

we now use a (separate) condition variable to handle that case.
2018-12-13 10:50:52 -08:00
Romain Guy
8ae1b06bce Fix frame pacing on Android (#634)
The renderer was misusing eglSetPresentationTime(), causing frame
misses when a frame was completed quickly.
2018-12-13 10:42:35 -08:00
Romain Guy
380e3fa690 Simplify UiHelper API, add transparent rendering sample (#629)
* Simplify UiHelper API, add transparent rendering sample

* Rename the app

* Address review comments

Also use the proper package name
2018-12-13 09:09:09 -08:00
Mathias Agopian
2d6b43827e Improve StaticString hashing
In a lot of case the StaticString hash can be computed a compile time,
so we now take advantage of that.

Removed StaticString(const char*) ctor, and replaced it with a
StaticString::make() method.

Fixed a couple wrong uses of the old StaticString(const char*) ctor.
2018-12-12 17:47:21 -08:00
Romain Guy
d135108763 Add mipgen.md to install directory 2018-12-12 09:09:01 -08:00
Philip Rideout
73e1bfb134 Vulkan: add support for compressed cubemaps.
This simply removes an assert from the Vulkan driver, adds a
compressed environment to our desktop samples, and contains some minor
code cleanup.
2018-12-12 08:55:17 -08:00
Philip Rideout
b81349b227 Vulkan: fix DXT => BC enum mapping. 2018-12-11 18:44:03 -08:00
prideout
71df133053 Fix Vulkan validation warning about enabled features. 2018-12-11 18:43:40 -08:00
Mathias Agopian
42fd0f5dad reduce AAR's content by about 150K
We simply don't emit unwind tables, which are not needed anyways since
we're compiling without exceptions. the combined saving for all four 
targets we support is about 120K.

This seems to improve .aar's compression, for a total gain of 152 KiB. 

We also disable stack-protector in the jni code, since it wasn't
enabled in libfilament.a anyways. However, we now compile all debug 
builds with -fstack-protector
2018-12-11 18:24:16 -08:00
Romain Guy
ff74255e6e Use clang70 in CI (#622)
* Use clang70 in CI

* Use version 7 not 7.0

* Use libc++ 7.0.0
2018-12-11 17:46:45 -08:00
Pixelflinger
2529a34c36 code size optimizations
- make Profiler::readCounters() not inline as it didn't need to be, 
it's not performance critical and it's sufficiently large.

- don't inline hasExtensions(), same reason.
2018-12-11 17:44:03 -08:00
Romain Guy
b291e11b90 Try to switch to clang60 in CI 2018-12-11 16:30:36 -08:00
Romain Guy
85a649b239 Apparently we can't use -static-libstdc++ in CI on Debug builds 2018-12-11 15:53:24 -08:00
Romain Guy
b96867e03a Link statically against libc++abi 2018-12-11 15:51:05 -08:00
Romain Guy
23e2e2a9bd Always link libc++ statically on Linux 2018-12-11 15:40:44 -08:00
Pixelflinger
e624dff037 set cpu affinity of JobSystem's threads
this is to try to prevent threads from bouncing
between cores
2018-12-11 13:46:05 -08:00
Romain Guy
025f4a54f5 Use root utils namespace in Systrace.h 2018-12-11 13:45:37 -08:00
Philip Rideout
b375d029d2 Work around CMake issue on win32 with asm-only libs. 2018-12-11 11:23:33 -08:00
Philip Rideout
40298f3cc0 Add C++ sample for compressed textures.
This is similar to its WebGL and Android counterparts, we simply did not
have a version for desktop. This uses resgen to package the model's
textures (albedo, normal, roughness, metallic, ao) into a library that
is linked only to this sample.

This is a good test because it applies multiple textures to the model.
Moreover Aaron was asking me for a C++ example that uses compressed
textures.

For now this selects the OpenGL backend. We can change it to use Vulkan
after we add support for 3-band formats to VulkanDriver.
2018-12-11 11:23:33 -08:00
Romain Guy
a38c40cf11 Turn on shaders optimization by default (#614)
* Turn on shaders optimization by default

Release builds of Filament only work well with optimize shaders,
turning optimizations on by default will help avoid mismatches.

This change also adds -g to disable all optimizations, for debug
builds.

* Use -g on debug builds

* Use -g on debug builds

* Update tutorial_redball.md to remove matc's -O

* Update tutorial_suzanne.md to remove matc's -O

* Use -g in debug builds
2018-12-11 09:36:37 -08:00
shartte
3c8b7e537c Fixes an overflow issue when exactly 256 bones are used (#617) 2018-12-11 09:35:06 -08:00
Mathias Agopian
ab3dddeb78 add missing @public-api comment 2018-12-10 21:36:20 -08:00
Mathias Agopian
cd00c4bbe8 Add getUserTimeModulo() to materials
This calculates the modulo of the user time by a given value, using
the high precision user time. This is useful for animations without
having to worry about resetting the time.
2018-12-10 21:36:20 -08:00
Mathias Agopian
1dfc7fd5ae parallelize light and renderable culling
the code was structured so light culling and renderable culling could
be done in parallel, but this wasn't implemented.
Clean-up some methods to turn them to static and run light culling
in parallel with renderable culling.
2018-12-10 21:34:00 -08:00
Mathias Agopian
f9cc118bdb Always wake up a job queue when a job is ran
We used to only wake up a job-queue if there was already some jobs
running, the idea was that the current thread would handle the new job
as soon as calling wait(). However, there is no guarantee that wait() 
will be called anytime soon.

cv.signal() is not very expensive on Android/Linux, as we're using
a custom implementation.
2018-12-10 21:33:38 -08:00
Mathias Agopian
418aebb2a0 Run Froxelization during shadow pass
We can start the froxelization earlier so it happens during the
shadow pass.
2018-12-10 21:33:18 -08:00
Philip Rideout
96c0e999ae Vulkan: support 2D compressed textures. 2018-12-10 18:05:09 -08:00
Philip Rideout
8dda07bf2c mipgen: support generation of 4-band KTX files
This is useful because our Vulkan backend currently does not accept
3-band texture data. (although we intend to fix that soon)
2018-12-10 18:04:52 -08:00
Mathias Agopian
76b15e895a [MATERIALS BREAK] higher period clock
THIS CHANGE BREAKS MATERIALS.

This adds getUserTime() in shaders/materials, which returns the time
in second since Renderer::resetUserTime() was called.
Two values are provided, the time in second encoded as a float and
the difference between that and the double value, which together allows
to perform high precision time computation when needed.

This change allows longer running animations in materials. Using only
the float value, give millisecond resolution for more than 4h.
2018-12-10 16:28:07 -08:00
Philip Rideout
e3d0630704 Vulkan: fix mipmapping for 2D textures.
The dimensions passed into the VkBuffer-to-VkImage copy utility
specify a subregion for the copy, not the dimensions of the base level.

We were handling mipmapped cubemaps correctly, but mipmapped 2D images
were incorrect.
2018-12-10 16:23:55 -08:00
Romain Guy
e41dd027ab Enable optimization passes on materials with external samplers (#605)
* Enable optimization passes on materials with external samplers

Because external samplers are not properly supported by SPIRV and
associated library (spirv-cross and spirv-tools) we currently disable
all optimizations when we encounter a material with external samplers.

This however causes issues on some misbehaved drivers (not running
the optimizations has a side effect which causes a crash). To enable
the optimization pass we simply rely on the Vulkan codegen target to
substitute samplerExternal with sampler2D. We then analyze the output
GLSL (post-optimization) and revert the relevants sampler2D declarations
to samplerExternal declarations.

This fixup only occurs after optimization and for mobile targets and
if external samplers were declared.

* Address review comments
2018-12-10 12:02:59 -08:00
Romain Guy
3c89f901af Remove key fetch 2018-12-07 17:37:42 -08:00
Romain Guy
6ae21d3825 Add View::setFrontFaceWindingInverted() API (#602)
* Add View::setFrontFaceWindingInverted() API

This API can be used to flip all meshes in a render pass
inside out. This is useful for mirrored rendering.

This change also disables face culling on the default skybox
renderable. Since it is unlit, there is no downside to this
and the mesh being in the device vertex domain it can never
be backfacing unless front face winding is inverted.

* Track face winding state in Vulkan
2018-12-07 16:36:03 -08:00
Romain Guy
866c694977 Fix Linux build 2018-12-07 16:33:06 -08:00
Romain Guy
c11d6e549a Use the proper domain for the key 2018-12-07 16:19:27 -08:00
Romain Guy
4789e81ebc Require API level 21, not 24 (#599)
* Require API level 21, not 24

Fixes #594

* Update README.md
2018-12-07 16:17:57 -08:00
Romain Guy
a042cc7b8b Fix apt-get key issue 2018-12-07 16:16:52 -08:00
Mathias Agopian
4d9788ffb9 improve skinning memory usage and udpates
- use the exact required size for bone data instead of always the max
of 256 bones. This also reduces the amount of data to update and
copy into the command stream.

- also get rid of the "reuse component" optimization, which is less
needed now that renderables don't have their own transform UBO.
2018-12-07 16:07:49 -08:00
Romain Guy
5bbdc673f2 Remove CMake warning 2018-12-07 15:11:24 -08:00
magicwhale
4be93cbdd6 Added warning about textures using the pbrSpecularGlossiness gltf extension in MeshAssimp (#597) 2018-12-07 14:33:00 -08:00
shartte
556baee70c Allow for the use of a shared CRT when compiling for release mode on Windows (#581) 2018-12-07 13:32:09 -08:00
magicwhale
2633edf2c4 Changed MeshAssimp to use snorm16 if uv values are in the range [-1, 1] (#592)
* grouped MeshAssimp arguments into struct

* added snormuv optimization to MeshAssimp and changed snormuv optimization range from [0, 1] to [-1, 1] in filamesh
2018-12-07 13:03:18 -08:00
Philip Rideout
1feb07ba8b Add webpack / TypeScript demo. 2018-12-07 09:50:06 -08:00
Philip Rideout
083a60938e Update web site to v1.1.0 (includes KTX fixes) 2018-12-07 09:43:30 -08:00
345 changed files with 14507 additions and 1810 deletions

View File

@@ -24,25 +24,37 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
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
# a choice to opt for the shared runtime if they want.
option(USE_STATIC_CRT "Link against the static runtime libraries." ON)
# On Windows we need to instruct cmake to generate the .def in order to get the .lib required
# when linking against dlls. CL.EXE will not generate .lib without .def file (or without pragma
# __declspec(dllexport) in front of each functions).
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (${USE_STATIC_CRT})
set(CRT_FLAGS_RELEASE "/MT")
set(CRT_FLAGS_DEBUG "/MTd")
else()
set(CRT_FLAGS_RELEASE "/MD")
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} /Z7")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
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 RELEASE, link statically against c/c++ lib to avoid missing redistriburable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.". Also generate PDBs.
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Zi")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT /Zi")
# 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} /Z7")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
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()
# ==================================================================================================
@@ -147,7 +159,7 @@ endif()
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
if (ANDROID OR WEBGL)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
endif()
# ==================================================================================================
@@ -157,6 +169,10 @@ endif()
# -fsanitize=undefined causes extremely long link times
# -fsanitize=address causes a crash with assimp, which we can't explain for now
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
# clang-cl.exe on Windows does not support -fstack-protector.
if (NOT CLANG_CL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
# ==================================================================================================
@@ -210,6 +226,24 @@ if (FILAMENT_SUPPORTS_VULKAN)
add_definitions(-DFILAMENT_DRIVER_SUPPORTS_VULKAN)
endif()
# Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
else()
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" OFF)
endif()
if (FILAMENT_SUPPORTS_METAL)
add_definitions(-DFILAMENT_SUPPORTS_METAL)
endif()
# Building filamat increases build times and isn't required for non-desktop platforms, so turn it
# off by default.
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" ON)
else()
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
endif()
# ==================================================================================================
# Distribution
# ==================================================================================================
@@ -275,19 +309,18 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
${ARCHIVE_DIR}/${ARCHIVE_NAME}.apple.S
${ARCHIVE_DIR}/${ARCHIVE_NAME}.h
)
if (NOT WIN32)
set(ASM_ARCH_FLAG "-arch ${DIST_ARCH}")
endif()
set(ASM_ARCH_FLAG "-arch ${DIST_ARCH}")
if (APPLE)
set(ASM_SUFFIX ".apple")
endif()
if (WEBGL)
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
# Visual Studio makes it difficult to use assembly without using MASM. MASM doesn't support
# the equivalent of .incbin, so on Windows we'll just tell resgen to output a C file.
if (WEBGL OR WIN32)
set(RESGEN_OUTPUTS "${OUTPUTS};${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
set(RESGEN_FLAGS -cx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
else()
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
set(RESGEN_OUTPUTS "${OUTPUTS}" PARENT_SCOPE)
set(RESGEN_FLAGS -x ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}${ASM_SUFFIX}.S" PARENT_SCOPE)
@@ -298,17 +331,11 @@ endfunction()
# ==================================================================================================
# Sub-projects
# ==================================================================================================
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
add_subdirectory(${EXTERNAL}/spirv-tools)
add_subdirectory(${EXTERNAL}/glslang/tnt)
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
# Common to all platforms
add_subdirectory(${EXTERNAL}/libgtest/tnt)
add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filamat)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/image)
add_subdirectory(${LIBRARIES}/math)
@@ -320,6 +347,16 @@ add_subdirectory(${EXTERNAL}/smol-v/tnt)
add_subdirectory(${EXTERNAL}/benchmark/tnt)
add_subdirectory(${EXTERNAL}/meshoptimizer)
if (FILAMENT_BUILD_FILAMAT)
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
add_subdirectory(${EXTERNAL}/spirv-tools)
add_subdirectory(${EXTERNAL}/glslang/tnt)
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
add_subdirectory(android/filamat-android)
add_subdirectory(${LIBRARIES}/filamat)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
add_subdirectory(${LIBRARIES}/bluevk)
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
@@ -341,13 +378,13 @@ if (WEBGL)
endif()
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${LIBRARIES}/bluegl)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${FILAMENT}/java)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/getopt)
@@ -362,6 +399,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${TOOLS}/cmgen)
add_subdirectory(${TOOLS}/filamesh)
add_subdirectory(${TOOLS}/glslminifier)
add_subdirectory(${TOOLS}/matc)
add_subdirectory(${TOOLS}/matinfo)
add_subdirectory(${TOOLS}/mipgen)
@@ -374,5 +412,5 @@ endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
if (NOT CMAKE_CROSSCOMPILING)
export(TARGETS matc cmgen filamesh mipgen resgen FILE ${IMPORT_EXECUTABLES})
export(TARGETS matc cmgen filamesh mipgen resgen glslminifier FILE ${IMPORT_EXECUTABLES})
endif()

View File

@@ -18,6 +18,9 @@ Android devices and as the renderer inside the Android Studio plugin.
[Download Filament releases](https://github.com/google/filament/releases) to access stable builds.
Make sure you always use tools from the same release as the runtime library. This is particularly
important for `matc` (material compiler).
If you prefer to live on the edge, you can download a continuous build by clicking one of the build
badges above.
@@ -102,6 +105,7 @@ and tools.
- `android`: Android libraries and projects
- `build`: Custom Gradle tasks for Android builds
- `filamat-android`: Filament material generation library (AAR) for Android
- `filament-android`: Filament library (AAR) for Android
- `samples`: Android-specific Filament samples
- `art`: Source for various artworks (logos, PDF manuals, etc.)
@@ -133,6 +137,7 @@ and tools.
- `tools`: Host tools
- `cmgen`: Image-based lighting asset generator
- `filamesh`: Mesh converter
- `glslminifier`: Minifies GLSL source code
- `matc`: Material compiler
- `matinfo` Displays information about materials compiled with `matc`
- `mipgen` Generates a series of miplevels from a source image
@@ -150,7 +155,7 @@ and tools.
To build Filament, you must first install the following tools:
- CMake 3.4 (or more recent)
- clang 5.0 (or more recent)
- clang 7.0 (or more recent)
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
To build the Java based components of the project you can optionally install (recommended):
@@ -162,7 +167,7 @@ section below.
To build Filament for Android you must also install the following:
- Android Studio 3.1
- Android Studio 3.3
- Android SDK
- Android NDK
@@ -226,8 +231,8 @@ If you use CMake directly instead of the build script, pass `-DENABLE_JAVA=OFF`
Make sure you've installed the following dependencies:
- `libglu1-mesa-dev`
- `libc++-dev` (`libcxx-devel` on Fedora)
- `libc++abi-dev`
- `libc++-7-dev` (`libcxx-devel` on Fedora)
- `libc++abi-7-dev`
- `ninja-build`
- `libxi-dev`
@@ -256,8 +261,8 @@ Your Linux distribution might default to `gcc` instead of `clang`, if that's the
```
$ mkdir out/cmake-release
$ cd out/cmake-release
# Or use a specific version of clang, for instance /usr/bin/clang-5.0
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ \
# Or use a specific version of clang, for instance /usr/bin/clang-7
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ LDFLAGS=-lc++abi \
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
```
@@ -268,8 +273,8 @@ specific version of clang:
```
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-5.0 100
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-5.0 100
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
```
Finally, invoke `ninja`:
@@ -327,14 +332,21 @@ Google employees require additional steps which can be found here [go/filawin](h
Install the following components:
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
- [Visual Studio 2015](https://www.visualstudio.com/downloads)
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
- [Clang 6](http://releases.llvm.org/download.html)
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
- [Git 2.16.1 or later](https://github.com/git-for-windows/git/releases/download/v2.16.1.windows.4/PortableGit-2.16.1.4-64-bit.7z.exe)
- [Cmake 3.11 or later](https://cmake.org/files/v3.11/cmake-3.11.0-rc1-win64-x64.msi)
Open an VS2015 x64 Native Tools terminal (click the start button, type "x64 native tools" and
select: "VS2015 x64 Native Tools Command Prompt").
If you're using Visual Studio 2017, you'll also need to install the [LLVM Compiler
Toolchain](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain)
extension.
Open an appropriate Native Tools terminal for the version of Visual Studio you are using:
- VS 2015: VS2015 x64 Native Tools Command Prompt
- VS 2017: x64 Native Tools Command Prompt for VS 2017
You can find these by clicking the start button and typing "x64 native tools".
Create a working directory:
```
@@ -344,11 +356,20 @@ Create a working directory:
Create the msBuild project:
```
# Visual Studio 2015:
> cmake -T"LLVM-vs2014" -G "Visual Studio 14 2015 Win64" ../..
# Visual Studio 2017
> cmake ..\.. -T"LLVM" -G "Visual Studio 15 2017 Win64" ^
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe"
```
Check out the output and make sure Clang for Windows frontend was found. You should see a line
showing the following output.
showing the following output. Note that for Visual Studio 2017 this line may list Microsoft's
compiler, but the build will still in fact use Clang and you can proceed.
```
Clang:C:/Program Files/LLVM/msbuild-bin/cl.exe
```
@@ -379,11 +400,11 @@ Alternatively, you can use [Ninja](https://ninja-build.org/) to build for Window
installation is still necessary.
First, install the dependencies listed under [Windows](#Windows) as well as Ninja. Then open up a
VS2015 x64 Native Tools terminal as before. Create a build directory inside Filament and run the
Native Tools terminal as before. Create a build directory inside Filament and run the
following CMake command:
```
cmake .. -G Ninja ^
> cmake .. -G Ninja ^
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
@@ -426,6 +447,8 @@ Filament can be built for the following architectures:
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### Easy Android build
The easiest way to build Filament for Android is to use `build.sh` and the
@@ -442,7 +465,7 @@ Run `build.sh -h` for more information.
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/aarch64-linux-android-4.9
```
@@ -450,7 +473,7 @@ $ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 24
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/aarch64-linux-android-4.9
```
@@ -487,7 +510,7 @@ binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/arm-linux-androideabi-4.9
```
@@ -495,7 +518,7 @@ $ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 24 \
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/arm-linux-androideabi-4.9
```
@@ -532,7 +555,7 @@ binaries should be found in `out/android-release/filament/lib/armeabi-v7a`.
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/x86_64-linux-android-4.9
```
@@ -540,7 +563,7 @@ $ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 2
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/x86_64-linux-android-4.9
```
@@ -577,7 +600,7 @@ binaries should be found in `out/android-release/filament/lib/x86_64`.
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/i686-linux-android-4.9
```
@@ -585,7 +608,7 @@ $ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 24 \
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 24 \
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/i686-linux-android-4.9
```

160
android/Windows.md Normal file
View File

@@ -0,0 +1,160 @@
# Building Filament for Android on Windows
## Prerequisites
In addition to the requirements for [building Filament on Windows](../README.md#windows), you'll
need the Android SDK and NDK. See [Getting Started with the
NDK](https://developer.android.com/ndk/guides/) for detailed installation instructions.
Ensure the `%ANDROID_HOME%` environment variable is set to your Android SDK installation location.
All of the following commands should be executed in a Visual Studio x64 Native Tools Command Prompt.
## Desktop Tools
First, a few Filament tools need to be compiled for desktop.
1. From Filament's root directory, create a desktop build directory and run CMake.
```
mkdir out\cmake-release
cd out\cmake-release
cmake ^
-G Ninja ^
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
-DCMAKE_INSTALL_PREFIX=..\release\filament ^
-DENABLE_JAVA=NO ^
-DCMAKE_BUILD_TYPE=Release ^
..\..
```
2. Build the required desktop host tools.
```
ninja matc resgen cmgen
```
The build should succeed and a `ImportExecutables-Release.cmake` file should automatically be
created at Filament's root directory.
## Toolchains
Generate a toolchain for each Android architecture you're interested in building for.
From Filament's root directory, run the NDK `make_standalone_toolchain.py` script for each
architecture.
```
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch arm64 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/aarch64-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch arm ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/arm-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch x86_64 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/x86_64-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch x86 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/x86-linux-android-4.9"
````
## Build
1. Create the build directories.
```
mkdir out\cmake-android-release-aarch64
mkdir out\cmake-android-release-arm7
mkdir out\cmake-android-release-x86_64
mkdir out\cmake-android-release-x86
```
2. Run CMake for each architecture.
```
cd out\cmake-android-release-aarch64
cmake ^
-G Ninja ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-aarch64-linux-android.cmake ^
..\..
cd out\cmake-android-release-arm7
cmake ^
-G Ninja ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-arm7-linux-android.cmake ^
..\..
cd out\cmake-android-release-x86_64
cmake ^
-G Ninja ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-x86_64-linux-android.cmake ^
..\..
cd out\cmake-android-release-x86
cmake ^
-G Ninja ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-x86-linux-android.cmake ^
..\..
```
3. Build.
Inside of each build directory, run:
```
ninja install
```
## Generate AAR
The Gradle project used to generate the AAR is located at `<filament>\android\filament-android`.
```
cd android\filament-android
gradlew -Pfilament_dist_dir=..\..\out\android-release\filament assembleRelease
copy build\outputs\aar\filament-android-release.aar ..\..\out\
```
If you're only interested in building for a single ABI, you'll need to add an `abiFilters` override
inside the `build.gradle` file underneath `defaultConfig`:
```
ndk {
abiFilters 'arm64-v8a'
}
```
See
[NdkOptions](https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.NdkOptions.html#com.android.build.gradle.internal.dsl.NdkOptions:abiFilters)
for more information.
`filament-android-release.aar` should now be present at `<filament>\out\filament-android-release.aar`.
See [Using Filament's AAR](../README.md#using-filaments-aar) for usage instructions.

View File

@@ -96,7 +96,7 @@ class MaterialCompiler extends DefaultTask {
standardOutput out
errorOutput err
executable "${matcPath}"
args('-O', '-p', 'mobile', '-o', getOutputFile(file), file)
args('-a', 'all', '-p', 'mobile', '-o', getOutputFile(file), file)
}
}

11
android/filamat-android/.gitignore vendored Normal file
View File

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

View File

@@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.4.1)
project(filamat-java)
if (NOT ENABLE_JAVA)
return()
endif()
find_package(Java)
if (NOT Java_FOUND)
message(WARNING "JDK not found, skipping Java projects")
return()
endif()
# Android already has the JNI headers in its system include path.
if (NOT ANDROID)
find_package(JNI)
if (NOT JNI_FOUND)
message(WARNING "JNI not found, skipping Java projects")
return()
endif()
endif()
if (NOT DEFINED ENV{JAVA_HOME})
message(WARNING "The JAVA_HOME environment variable must be set to compile Java projects")
message(WARNING "Skipping Java projects")
return()
endif()
# ==================================================================================================
# JNI bindings
# ==================================================================================================
set(TARGET filamat-jni)
set(JNI_SOURCE_FILES
src/main/cpp/MaterialBuilder.cpp)
add_library(${TARGET} SHARED ${JNI_SOURCE_FILES})
target_include_directories(${TARGET} PRIVATE ${JNI_INCLUDE_DIRS})
set(EXPORTED_SYMBOLS)
if (APPLE)
set(EXPORTED_SYMBOLS "-exported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/libfilamat-jni.symbols")
elseif (ANDROID)
set(EXPORTED_SYMBOLS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilamat-jni.map")
endif()
# This is necessary to avoid a CMake error due to setting RPATH on non-elf platforms.
# Setting this also causes CMake to issue a warning on Mac:
# "Policy CMP0068 is not set: RPATH settings on macOS do not affect install_name." which can be
# safely ignored.
set(CMAKE_SKIP_RPATH TRUE)
set_target_properties(${TARGET} PROPERTIES
CXX_STANDARD 14
COMPILE_FLAGS "-fno-exceptions -fvisibility=hidden"
LINK_FLAGS "${GC_SECTIONS} ${EXPORTED_SYMBOLS}")
target_compile_options(${TARGET} PRIVATE
$<$<PLATFORM_ID:Linux>:-fPIC>
)
target_link_libraries(${TARGET} filamat)
set(INSTALL_TYPE LIBRARY)
if (WIN32 OR CYGWIN)
set(INSTALL_TYPE RUNTIME)
endif()
install(TARGETS ${TARGET} ${INSTALL_TYPE} DESTINATION lib/${DIST_DIR})
install(CODE "execute_process(COMMAND ${CMAKE_STRIP} -x ${CMAKE_INSTALL_PREFIX}/lib/${DIST_DIR}/lib${TARGET}${CMAKE_SHARED_LIBRARY_SUFFIX})")
# ==================================================================================================
# Java APIs
# ==================================================================================================
# Android builds its Java bindings for filamat through Gradle.
if (ANDROID)
return()
endif()
set(TARGET filamat-java)
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8")
set(JAVA_SOURCE_FILES
src/main/java/com/google/android/filament/filamat/MaterialBuilder.java
src/main/java/com/google/android/filament/filamat/MaterialPackage.java)
add_jar(${TARGET}
SOURCES ${JAVA_SOURCE_FILES}
INCLUDE_JARS ../../java/lib/support-annotations.jar)
install_jar(${TARGET} lib)

View File

@@ -0,0 +1,78 @@
// 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.3.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
group = "com.google.android.filament"
version = "0.1"
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 28
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs "${filament_path}/lib"
}
}
// Ensure that only the libfilamat-jni.so library is included in the AAR, in case any other
// libraries happen to be present.
packagingOptions {
exclude '**/*.so'
merge '**/libfilamat-jni.so'
}
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'
}

Binary file not shown.

View File

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

172
android/filamat-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=""
# 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/filamat-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=
@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 @@
LIBFILAMAT {
global: Java_com_google_android_filament_*; JNI*;
local: *;
};

View File

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

View File

@@ -0,0 +1,10 @@
/*
* 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
*/
rootProject.name = 'filamat-android'

View File

@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.filamat" />

View File

@@ -0,0 +1,121 @@
/*
* 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 <filamat/MaterialBuilder.h>
#include <filament/EngineEnums.h>
using namespace filament;
using namespace filamat;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nCreateMaterialBuilder(JNIEnv *env,
jclass type) {
return (jlong) new MaterialBuilder();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyMaterialBuilder(JNIEnv *env,
jclass type, jlong nativeBuilder) {
auto builder = (MaterialBuilder*) nativeBuilder;
delete builder;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nBuilderBuild(JNIEnv* env, jclass type,
jlong nativeBuilder) {
auto builder = (MaterialBuilder*) nativeBuilder;
return (jlong) new Package(builder->build());
}
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nGetPackageBytes(JNIEnv* env, jclass type,
jlong nativePackage) {
auto package = (Package*) nativePackage;
auto size = jsize(package->getSize());
jbyteArray ret = env->NewByteArray(size);
auto data = (jbyte*) package->getData();
env->SetByteArrayRegion(ret, 0, size, data);
return ret;
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nGetPackageIsValid(JNIEnv* env,
jclass type, jlong nativePackage) {
auto* package = (Package*) nativePackage;
return jboolean(package->isValid());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyPackage(JNIEnv* env, jclass type,
jlong nativePackage) {
Package* package = (Package*) nativePackage;
delete package;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderName(JNIEnv* env,
jclass type, jlong nativeBuilder, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->name(name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShading(JNIEnv* env,
jclass type, jlong nativeBuilder, jint shading) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->shading((Shading) shading);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRequire(JNIEnv* env,
jclass type, jlong nativeBuilder, jint attribute) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->require((VertexAttribute) attribute);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterial(JNIEnv* env,
jclass type, jlong nativeBuilder, jstring code_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* code = env->GetStringUTFChars(code_, nullptr);
builder->material(code);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterialVertex(JNIEnv* env,
jclass type, jlong nativeBuilder, jstring code_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* code = env->GetStringUTFChars(code_, nullptr);
builder->materialVertex(code);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWrite(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean enable) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->colorWrite(enable);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderPlatform(JNIEnv* env,
jclass type, jlong nativeBuilder, jint platform) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->platform((MaterialBuilder::Platform) platform);
}

View File

@@ -0,0 +1,142 @@
/*
* 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.filamat;
import android.support.annotation.NonNull;
import java.nio.ByteBuffer;
public class MaterialBuilder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
private final BuilderFinalizer mFinalizer;
private final long mNativeObject;
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)
BONE_INDICES, // indices of 4 bones (uvec4)
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
}
public enum Shading {
UNLIT, // no lighting applied, emissive possible
LIT, // default, standard lighting
SUBSURFACE, // subsurface lighting model
CLOTH // cloth lighting model
}
public enum Platform {
DESKTOP,
MOBILE,
ALL
}
public MaterialBuilder() {
mNativeObject = nCreateMaterialBuilder();
mFinalizer = new BuilderFinalizer(mNativeObject);
}
@NonNull
public MaterialBuilder name(@NonNull String name) {
nMaterialBuilderName(mNativeObject, name);
return this;
}
@NonNull
public MaterialBuilder shading(@NonNull Shading shading) {
nMaterialBuilderShading(mNativeObject, shading.ordinal());
return this;
}
@NonNull
public MaterialBuilder require(@NonNull VertexAttribute attribute) {
nMaterialBuilderRequire(mNativeObject, attribute.ordinal());
return this;
}
@NonNull
public MaterialBuilder material(@NonNull String code) {
nMaterialBuilderMaterial(mNativeObject, code);
return this;
}
@NonNull
public MaterialBuilder materialVertex(@NonNull String code) {
nMaterialBuilderMaterialVertex(mNativeObject, code);
return this;
}
@NonNull
public MaterialBuilder colorWrite(boolean enable) {
nMaterialBuilderColorWrite(mNativeObject, enable);
return this;
}
@NonNull
public MaterialBuilder platform(@NonNull Platform platform) {
nMaterialBuilderPlatform(mNativeObject, platform.ordinal());
return this;
}
@NonNull
public MaterialPackage build() {
long nativePackage = nBuilderBuild(mNativeObject);
byte[] data = nGetPackageBytes(nativePackage);
MaterialPackage result =
new MaterialPackage(ByteBuffer.wrap(data), nGetPackageIsValid(nativePackage));
nDestroyPackage(nativePackage);
return result;
}
private static class BuilderFinalizer {
private final long mNativeObject;
BuilderFinalizer(long nativeObject) {
mNativeObject = nativeObject;
}
@Override
public void finalize() {
try {
super.finalize();
} catch (Throwable t) { // Ignore
} finally {
nDestroyMaterialBuilder(mNativeObject);
}
}
}
private static native long nCreateMaterialBuilder();
private static native void nDestroyMaterialBuilder(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder);
private static native byte[] nGetPackageBytes(long nativePackage);
private static native boolean nGetPackageIsValid(long nativePackage);
private static native void nDestroyPackage(long nativePackage);
private static native void nMaterialBuilderName(long nativeBuilder, String name);
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
private static native void nMaterialBuilderRequire(long nativeBuilder, int attribute);
private static native void nMaterialBuilderMaterial(long nativeBuilder, String code);
private static native void nMaterialBuilderMaterialVertex(long nativeBuilder, String code);
private static native void nMaterialBuilderColorWrite(long nativeBuilder, boolean enable);
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
}

View File

@@ -0,0 +1,41 @@
/*
* 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.filamat;
import android.support.annotation.NonNull;
import java.nio.ByteBuffer;
public class MaterialPackage {
private final ByteBuffer mBuffer;
private final boolean mIsValid;
MaterialPackage(@NonNull ByteBuffer buffer, boolean isValid) {
mBuffer = buffer;
mIsValid = isValid;
}
@NonNull
public ByteBuffer getBuffer() {
return mBuffer;
}
public boolean isValid() {
return mIsValid;
}
}

View File

@@ -29,11 +29,12 @@ set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
include_directories(${FILAMENT_DIR}/include)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
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} -ffunction-sections -fdata-sections")
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")

View File

@@ -13,7 +13,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
}
}
@@ -37,6 +37,9 @@ if (project.hasProperty("filament_dist_dir")) {
android {
compileSdkVersion 28
defaultConfig {
// Our minSdkVersion is actually 21, 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.
minSdkVersion 14
targetSdkVersion 28
versionCode 1
@@ -47,7 +50,7 @@ android {
externalNativeBuild {
cmake {
arguments.add("-DANDROID_PIE=ON")
arguments.add("-DANDROID_PLATFORM=android-24")
arguments.add("-DANDROID_PLATFORM=android-21")
arguments.add("-DANDROID_STL=c++_static")
arguments.add("-DFILAMENT_DIST_DIR=${filament_path}".toString())
cppFlags.add("-std=c++14")

View File

@@ -1,6 +1,6 @@
#Tue Aug 28 15:45:13 PDT 2018
#Mon Jan 14 11:04:36 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

View File

@@ -22,9 +22,9 @@ using namespace filament;
using namespace utils;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nCreateEngine(JNIEnv*, jclass,
Java_com_google_android_filament_Engine_nCreateEngine(JNIEnv*, jclass, jlong backend,
jlong sharedContext) {
return (jlong) Engine::create(Engine::Backend::OPENGL, nullptr, (void*) sharedContext);
return (jlong) Engine::create((Engine::Backend) backend, nullptr, (void*) sharedContext);
}
extern "C" JNIEXPORT void JNICALL

View File

@@ -96,3 +96,15 @@ Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
return 0;
}
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Renderer_nGetUserTime(JNIEnv*, jclass, jlong nativeRenderer) {
Renderer *renderer = (Renderer *) nativeRenderer;
return renderer->getUserTime();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nResetUserTime(JNIEnv*, jclass, jlong nativeRenderer) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->resetUserTime();
}

View File

@@ -36,8 +36,10 @@ using namespace driver;
static size_t getTextureDataSize(const Texture *texture, size_t level,
Texture::Format format, Texture::Type type, size_t stride, size_t alignment) {
// Zero stride implies tight row-to-row packing.
stride = stride == 0 ? texture->getWidth(level) : std::max(size_t(1), stride >> level);
return Texture::computeTextureDataSize(format, type,
std::max(size_t(1), stride >> level), texture->getHeight(level), alignment);
stride, texture->getHeight(level), alignment);
}
extern "C" JNIEXPORT jboolean JNICALL

View File

@@ -65,9 +65,9 @@ Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jcl
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv *env, jclass type,
jlong nativeBuilder, jint attribute) {
jlong nativeBuilder, jint attribute, jboolean normalized) {
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
builder->normalized((VertexAttribute) attribute);
builder->normalized((VertexAttribute) attribute, normalized);
}
extern "C" JNIEXPORT jlong JNICALL

View File

@@ -177,3 +177,17 @@ Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*,
View* view = (View*) nativeView;
return static_cast<jboolean>(view->isPostProcessingEnabled());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetFrontFaceWindingInverted(JNIEnv*,
jclass, jlong nativeView, jboolean inverted) {
View* view = (View*) nativeView;
view->setFrontFaceWindingInverted(inverted);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsFrontFaceWindingInverted(JNIEnv*,
jclass, jlong nativeView) {
View* view = (View*) nativeView;
return static_cast<jboolean>(view->isFrontFaceWindingInverted());
}

View File

@@ -24,6 +24,13 @@ public class Engine {
@NonNull private final LightManager mLightManager;
@NonNull private final RenderableManager mRenderableManager;
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.
}
private Engine(long nativeEngine) {
mNativeObject = nativeEngine;
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
@@ -33,7 +40,14 @@ public class Engine {
@NonNull
public static Engine create() {
long nativeEngine = nCreateEngine(0);
long nativeEngine = nCreateEngine(0, 0);
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
return new Engine(nativeEngine);
}
@NonNull
public static Engine create(@NonNull Backend backend) {
long nativeEngine = nCreateEngine(backend.ordinal(), 0);
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
return new Engine(nativeEngine);
}
@@ -46,7 +60,7 @@ public class Engine {
@NonNull
public static Engine create(@NonNull Object sharedContext) {
if (Platform.get().validateSharedContext(sharedContext)) {
long nativeEngine = nCreateEngine(
long nativeEngine = nCreateEngine(0,
Platform.get().getSharedContextNativeHandle(sharedContext));
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
return new Engine(nativeEngine);
@@ -71,13 +85,19 @@ public class Engine {
* - Other: none
*/
public SwapChain createSwapChain(@NonNull Object surface) {
return createSwapChain(surface, 0);
return createSwapChain(surface, SwapChain.CONFIG_DEFAULT);
}
/**
* Valid surface types:
* - Android: Surface
* - Other: none
*
* Flags: see CONFIG flags in SwapChain.
*
* @see SwapChain#CONFIG_DEFAULT
* @see SwapChain#CONFIG_TRANSPARENT
* @see SwapChain#CONFIG_READABLE
*/
public SwapChain createSwapChain(@NonNull Object surface, long flags) {
if (Platform.get().validateSurface(surface)) {
@@ -257,7 +277,7 @@ public class Engine {
mNativeObject = 0;
}
private static native long nCreateEngine(long sharedContext);
private static native long nCreateEngine(long backend, long sharedContext);
private static native void nDestroyEngine(long nativeEngine);
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);

View File

@@ -89,6 +89,14 @@ public class Renderer {
}
}
double getUserTime() {
return nGetUserTime(getNativeObject());
}
void resetUserTime() {
nResetUserTime(getNativeObject());
}
long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Renderer");
@@ -112,4 +120,6 @@ public class Renderer {
Buffer storage, int remaining,
int left, int top, int type, int alignment, int stride, int format,
Object handler, Runnable callback);
private static native double nGetUserTime(long nativeRenderer);
private static native void nResetUserTime(long nativeRenderer);
}

View File

@@ -22,6 +22,7 @@ public class SwapChain {
private final Object mSurface;
private long mNativeObject;
public static final long CONFIG_DEFAULT = 0x0;
public static final long CONFIG_TRANSPARENT = 0x1;
public static final long CONFIG_READABLE = 0x2;

View File

@@ -108,7 +108,13 @@ public class VertexBuffer {
@NonNull
public Builder normalized(@NonNull VertexAttribute attribute) {
nBuilderNormalized(mNativeBuilder, attribute.ordinal());
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), true);
return this;
}
@NonNull
public Builder normalized(@NonNull VertexAttribute attribute, boolean enabled) {
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), enabled);
return this;
}
@@ -183,7 +189,8 @@ public class VertexBuffer {
private static native void nBuilderBufferCount(long nativeBuilder, int bufferCount);
private static native void nBuilderAttribute(long nativeBuilder, int attribute,
int bufferIndex, int attributeType, int byteOffset, int byteStride);
private static native void nBuilderNormalized(long nativeBuilder, int attribute);
private static native void nBuilderNormalized(long nativeBuilder, int attribute,
boolean normalized);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nGetVertexCount(long nativeVertexBuffer);

View File

@@ -212,6 +212,14 @@ public class View {
nSetPostProcessingEnabled(getNativeObject(), enabled);
}
public boolean isFrontFaceWindingInverted() {
return nIsFrontFaceWindingInverted(getNativeObject());
}
public void setFrontFaceWindingInverted(boolean inverted) {
nSetFrontFaceWindingInverted(getNativeObject(), inverted);
}
public void setDynamicLightingOptions(float zLightNear, float zLightFar) {
nSetDynamicLightingOptions(getNativeObject(), zLightNear, zLightFar);
}
@@ -258,4 +266,6 @@ public class View {
private static native void nSetDepthPrepass(long nativeView, int value);
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
private static native boolean nIsPostProcessingEnabled(long nativeView);
private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted);
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
}

View File

@@ -16,15 +16,111 @@
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;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import com.google.android.filament.SwapChain;
/**
* UiHelper is a simple class that can manage either a SurfaceView or a TextureView so it can
* be used to render into with Filament.
*
* Here is a simple example with a SurfaceView. The code would be exactly the same with a
* TextureView:
*
* <pre>
* public class FilamentActivity extends Activity {
* private UiHelper mUiHelper;
* private SurfaceView mSurfaceView;
*
* // Filament specific APIs
* private Engine mEngine;
* private Renderer mRenderer;
* private View mView; // com.google.android.filament.View, not android.view.View
* private SwapChain mSwapChain;
*
* public void onCreate(Bundle savedInstanceState) {
* super.onCreate(savedInstanceState);
*
* // Create a SurfaceView and add it to the activity
* mSurfaceView = new SurfaceView(this);
* setContentView(mSurfaceView);
*
* // Create the Filament UI helper
* mUiHelper = new UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK);
*
* // Attach the SurfaceView to the helper, you could do the same with a TextureView
* mUiHelper.attachTo(surfaceView)
*
* // Set a rendering callback that we will use to invoke Filament
* mUiHelper.setRenderCallback(new UiHelper.RendererCallback() {
* public void onNativeWindowChanged(Surface surface) {
* if (mSwapChain != null) mEngine.destroySwapChain(mSwapChain);
* mSwapChain = mEngine.createSwapChain(surface, mUiHelper.getSwapChainFlags());
* }
*
* // The native surface went away, we must stop rendering.
* public void onDetachedFromSurface() {
* if (mSwapChain != null) {
* mEngine.destroySwapChain(mSwapChain);
*
* // Required to ensure we don't return before Filament is done executing the
* // destroySwapChain command, otherwise Android might destroy the Surface
* // too early
* mEngine.flushAndWait();
*
* mSwapChain = null;
* }
* }
*
* // The native surface has changed size. This is always called at least once
* // after the surface is created (after onNativeWindowChanged() is invoked).
* public void onResized(int width, int height) {
* // Compute camera projection and set the viewport on the view
* }
* });
*
* mEngine = Engine.create();
* mRenderer = mEngine.createRenderer();
* mView = mEngine.createView();
* // Create scene, camera, etc.
* }
*
* public void onDestroy() {
* super.onDestroy()
* // Always detach the surface before destroying the engine
* 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()
* }
*
* // This is an example of a render function. You will most likely invoke this from
* // a Choreographer callback to trigger rendering at vsync.
* public void render() {
* if (mUiHelper.isReadyToRender) {
* // 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()
* }
* }
* }
* }
* </pre>
*/
public class UiHelper {
private static final String LOG_TAG = "UiHelper";
private static final boolean LOGGING = false;
@@ -36,27 +132,46 @@ public class UiHelper {
private RendererCallback mRenderCallback;
private boolean mHasSwapChain;
private RenderSurface mRenderSurface;
private boolean mOpaque = true;
/**
* Enum used to decide whether UiHelper should perform extra error checking.
*
* @see UiHelper#UiHelper(ContextErrorPolicy)
*/
public enum ContextErrorPolicy {
CHECK, DONT_CHECK
/** Check for extra errors. */
CHECK,
/** Do not check for extra errors. */
DONT_CHECK
}
/**
* Interface used to know when the native surface is created, destroyed or resized.
*
* @see #setRenderCallback(RendererCallback)
*/
public interface RendererCallback {
// called when the underlying native window has changed
// NOTE: this could be called from UiHelper's constructor.
/**
* Called when the underlying native window has changed.
*/
void onNativeWindowChanged(Surface surface);
// called when the surface is going away. after this call isReadyToRender() returns false.
// you MUST have stopped drawing when returning.
// This is called from detach() or if the surface disappears on its own.
/**
* Called when the surface is going away. After this call <code>isReadyToRender()</code>
* returns false. You MUST have stopped drawing when returning.
* This is called from detach() or if the surface disappears on its own.
*/
void onDetachedFromSurface();
// called when the underlying native window has been resized
/**
* Called when the underlying native window has been resized.
*/
void onResized(int width, int height);
}
// --------------------------------------------------------------------------------------------
private interface RenderSurface {
void resize(int width, int height);
void detach();
@@ -108,34 +223,46 @@ public class UiHelper {
mSurface = surface;
}
}
// --------------------------------------------------------------------------------------------
private RenderSurface mRenderSurface;
/**
* Creates a UiHelper which will help manage the EGL context
* and EGL surfaces. UiHelper handles SurfaceView and TextureView.
*
* When this call returns, OpenGL ES is ready to use.
* Creates a UiHelper which will help manage the native surface provided by a
* SurfaceView or a TextureView.
*/
public UiHelper() {
this(ContextErrorPolicy.CHECK);
}
/**
* Creates a UiHelper which will help manage the native surface provided by a
* SurfaceView or a TextureView.
*
* @param policy The error checking policy to use.
*/
public UiHelper(ContextErrorPolicy policy) {
// TODO: do something with policy
}
public void setRenderCallback(RendererCallback renderCallback) {
/**
* Sets the renderer callback that will be notified when the native surface is
* created, destroyed or resized.
*
* @param renderCallback The callback to register.
*/
public void setRenderCallback(@Nullable RendererCallback renderCallback) {
mRenderCallback = renderCallback;
}
/**
* Returns the current render callback associated with this UiHelper.
*/
@Nullable
public RendererCallback getRenderCallback() {
return mRenderCallback;
}
/**
* Free resources associated to the native window specified in attachTo().
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
*/
public void detach() {
destroySwapChain();
@@ -143,13 +270,6 @@ public class UiHelper {
mRenderSurface = null;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
// TODO: check that detach() has been called
// TODO: call Surface.release() if not already done
}
/**
* Checks whether we are ready to render into the attached surface.
*
@@ -163,7 +283,7 @@ public class UiHelper {
}
/**
* Set the size of the underlying buffers
* Set the size of the render target buffers of the native surface.
*/
public void setDesiredSize(int width, int height) {
mDesiredWidth = width;
@@ -173,47 +293,90 @@ public class UiHelper {
}
}
/**
* Returns the requested width for the native surface.
*/
public int getDesiredWidth() {
return mDesiredWidth;
}
/**
* Returns the requested height for the native surface.
*/
public int getDesiredHeight() {
return mDesiredHeight;
}
/**
* Returns true if the render target is opaque.
*/
public boolean isOpaque() {
return mOpaque;
}
/**
* Controls whether the render target (SurfaceView or TextureView) is opaque or not.
* The render target is considered opaque by default.
*
* Must be called before calling {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
*
* @param opaque Indicates whether the render target should be opaque. True by default.
*/
public void setOpaque(boolean opaque) {
mOpaque = opaque;
}
/**
* Returns the flags to pass to
* {@link com.google.android.filament.Engine#createSwapChain(Object, long)} to honor all
* the options set on this UiHelper.
*/
public long getSwapChainFlags() {
return isOpaque() ? SwapChain.CONFIG_DEFAULT : SwapChain.CONFIG_TRANSPARENT;
}
/**
* Associate UiHelper with a SurfaceView.
*
* As soon as SurfaceView is ready (i.e. has a Surface), we'll create the
* EGL resources needed, and call user callbacks if needed.
*/
public void attachTo(SurfaceView view) {
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
createSwapChain(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Note: this is always called at least once after surfaceCreated()
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
mRenderCallback.onResized(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
destroySwapChain();
}
};
public void attachTo(@NonNull SurfaceView view) {
if (attach(view)) {
if (!isOpaque()) {
view.setZOrderOnTop(true);
view.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
mRenderSurface = new SurfaceViewHandler(view);
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
createSwapChain(holder.getSurface());
}
@Override
public void surfaceChanged(
SurfaceHolder holder, int format, int width, int height) {
// Note: this is always called at least once after surfaceCreated()
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
mRenderCallback.onResized(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
destroySwapChain();
}
};
SurfaceHolder holder = view.getHolder();
holder.addCallback(callback);
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
// in case the SurfaceView's surface already existed
final Surface surface = holder.getSurface();
if (surface != null && surface.isValid()) {
@@ -228,49 +391,64 @@ public class UiHelper {
* As soon as TextureView is ready (i.e. has a buffer), we'll create the
* EGL resources needed, and call user callbacks if needed.
*/
public void attachTo(TextureView view) {
final TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
}
Surface surface = new Surface(surfaceTexture);
TextureViewHandler textureViewHandler = (TextureViewHandler)mRenderSurface;
textureViewHandler.setSurface(surface);
createSwapChain(surface);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureSizeChanged()");
mRenderCallback.onResized(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureDestroyed()");
destroySwapChain();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) { }
};
public void attachTo(@NonNull TextureView view) {
if (attach(view)) {
view.setOpaque(isOpaque());
mRenderSurface = new TextureViewHandler(view);
TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(
SurfaceTexture surfaceTexture, int width, int height) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
}
}
Surface surface = new Surface(surfaceTexture);
TextureViewHandler textureViewHandler = (TextureViewHandler) mRenderSurface;
textureViewHandler.setSurface(surface);
createSwapChain(surface);
// Call this the first time because onSurfaceTextureSizeChanged()
// isn't called at initialization time
mRenderCallback.onResized(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(
SurfaceTexture surfaceTexture, int width, int height) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureSizeChanged()");
mRenderCallback.onResized(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureDestroyed()");
destroySwapChain();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) { }
};
view.setSurfaceTextureListener(listener);
// in case the View's SurfaceTexture already existed
if (view.isAvailable()) {
final SurfaceTexture surfaceTexture = view.getSurfaceTexture();
SurfaceTexture surfaceTexture = view.getSurfaceTexture();
listener.onSurfaceTextureAvailable(surfaceTexture, mDesiredWidth, mDesiredHeight);
}
}
}
private boolean attach(Object nativeWindow) {
private boolean attach(@NonNull Object nativeWindow) {
if (mNativeWindow != null) {
// we are already attached to a native window
if (mNativeWindow == nativeWindow) {
@@ -283,8 +461,8 @@ public class UiHelper {
return true;
}
private void createSwapChain(Surface sur) {
mRenderCallback.onNativeWindowChanged(sur);
private void createSwapChain(@NonNull Surface surface) {
mRenderCallback.onNativeWindowChanged(surface);
mHasSwapChain = true;
}

View File

@@ -5,13 +5,13 @@ Filament APIs:
### `hello-triangle`
A minimal example showing how to setup a rendering surface for Filament:
Demonstrates how to setup a rendering surface for Filament:
![Hellow Triangle](../../docs/images/samples/sample_hello_triangle.jpg)
![Hello Triangle](../../docs/images/samples/sample_hello_triangle.jpg)
### `lit-cube`
Shows how to create a light and a mesh with the attributes required for lighting:
Demonstrates how to create a light and a mesh with the attributes required for lighting:
![Lit Cube](../../docs/images/samples/sample_lit_cube.jpg)
@@ -27,6 +27,18 @@ Demonstrates how to load and use textures for complex materials:
![Textured Object](../../docs/images/samples/sample_textured_object.jpg)
### `transparent-rendering`
Demonstrates how to render into a transparent `SurfaceView`:
![Transparent Rendering](../../docs/images/samples/sample_transparent_rendering.jpg)
### `texture-view`
Demonstrates how to render into a `TextureView` instead of a `SurfaceView`:
![Texture View](../../docs/images/samples/sample_texture_view.jpg)
## Prerequisites
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
@@ -60,8 +72,7 @@ SDK. This includes the project `filament-android` in the parent directory.
## Android Studio
Due to issues with composite builds in Android Studio 3.1, it is highly recommended to use
Android Studio 3.2 or higher to open this project.
You must use Android Studio 3.3 or higher to open these projects.
## Compiling

View File

@@ -24,16 +24,14 @@ 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.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
@@ -102,7 +100,6 @@ class MainActivity : Activity() {
// NOTE: To choose a specific rendering resolution, add the following line:
// uiHelper.setDesiredSize(1280, 720)
uiHelper.attachTo(surfaceView)
}
@@ -303,7 +300,7 @@ class MainActivity : Activity() {
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
}
override fun onDetachedFromSurface() {

View File

@@ -2,7 +2,7 @@
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -O -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
// matc -p mobile -a opengl -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.

View File

@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.0'
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@@ -1,6 +1,6 @@
#Tue Aug 28 15:45:13 PDT 2018
#Mon Jan 14 11:09:37 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

View File

@@ -60,7 +60,7 @@ private fun loadIndirectLight(
assets: AssetManager,
name: String,
engine: Engine): Pair<IndirectLight, Texture> {
val (w, h) = peekSize(assets, "$name/nx.rgbm")
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
val texture = Texture.Builder()
.width(w)
.height(h)
@@ -142,6 +142,7 @@ private fun loadCubemap(texture: Texture,
// Rewind the texture buffer
storage.flip()
android.util.Log.d("Texture", "Cubemap level: $level $faceSize ${texture.getWidth(level)}")
val buffer = Texture.PixelBufferDescriptor(storage, Texture.Format.RGBM, Texture.Type.UBYTE)
texture.setImage(engine, level, buffer, offsets)

View File

@@ -69,12 +69,18 @@ fun loadMesh(assets: AssetManager, name: String,
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
private const val MAX_UINT32 = 4294967295
@Suppress("unused")
private const val HEADER_FLAG_INTERLEAVED = 0x1L
private const val HEADER_FLAG_SNORM16_UV = 0x2L
@Suppress("unused")
private const val HEADER_FLAG_COMPRESSED = 0x4L
private class Header {
var valid = false
var versionNumber = 0L
var parts = 0L
var aabb = Box()
var interleaved = 0L
var flags = 0L
var posOffset = 0L
var positionStride = 0L
var tangentOffset = 0L
@@ -121,7 +127,7 @@ private fun readHeader(input: InputStream): Header {
header.aabb = Box(
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
header.interleaved = readUIntLE(input)
header.flags = readUIntLE(input)
header.posOffset = readUIntLE(input)
header.positionStride = readUIntLE(input)
header.tangentOffset = readUIntLE(input)
@@ -142,7 +148,6 @@ private fun readHeader(input: InputStream): Header {
return header
}
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
buffer.order(ByteOrder.LITTLE_ENDIAN)
@@ -190,7 +195,15 @@ private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer):
.apply { setBuffer(engine, data) }
}
private fun uvNormalized(header: Header) = header.flags and HEADER_FLAG_SNORM16_UV != 0L
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
val uvType = if (!uvNormalized(header)) {
HALF2
} else {
SHORT2
}
val vertexBufferBuilder = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(header.totalVertices.toInt())
@@ -203,11 +216,18 @@ private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer)
.attribute(POSITION, 0, HALF4, header.posOffset.toInt(), header.positionStride.toInt())
.attribute(TANGENTS, 0, SHORT4, header.tangentOffset.toInt(), header.tangentStride.toInt())
.attribute(COLOR, 0, UBYTE4, header.colorOffset.toInt(), header.colorStride.toInt())
.attribute(UV0, 0, HALF2, header.uv0Offset.toInt(), header.uv0Stride.toInt())
// UV coordinates are stored as normalized 16-bit integers or half-floats depending on
// the range they span. When stored as half-float, there is only enough precision for
// sub-pixel addressing in textures that are <= 1024x1024
.attribute(UV0, 0, uvType, header.uv0Offset.toInt(), header.uv0Stride.toInt())
// When UV coordinates are stored as 16-bit integers we must normalize them (we want
// values in the range -1..1)
.normalized(UV0, uvNormalized(header))
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
vertexBufferBuilder
.attribute(UV1, 0, HALF2, header.uv1Offset.toInt(), header.uv1Stride.toInt())
.attribute(UV1, 0, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
.normalized(UV1, uvNormalized(header))
}
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
@@ -224,7 +244,7 @@ private fun createRenderable(
val builder = RenderableManager.Builder(header.parts.toInt()).boundingBox(header.aabb)
(0 until header.parts.toInt()).forEach { i ->
repeat(header.parts.toInt()) { i ->
builder.geometry(i,
RenderableManager.PrimitiveType.TRIANGLES,
vertexBuffer,

View File

@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.0'
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@@ -1,6 +1,6 @@
#Tue Aug 28 15:45:13 PDT 2018
#Mon Jan 14 11:08:47 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

View File

@@ -7,7 +7,7 @@
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -O -o app/src/main/assets/lit.filamat app/src/materials/lit.mat
// matc -p mobile -a opengl -o app/src/main/assets/lit.filamat app/src/materials/lit.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.

View File

@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.0'
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@@ -1,6 +1,6 @@
#Tue Aug 28 15:45:13 PDT 2018
#Mon Jan 14 11:08:15 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

12
android/samples/texture-view/.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/materials/*.filamat
.externalNativeBuild

View File

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

View File

@@ -0,0 +1,80 @@
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")
}
preBuild.dependsOn compileMaterials
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.google.android.filament.textureview"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// Filament comes with native code, the following declarations
// can be used to generate architecture specific APKs
flavorDimensions 'cpuArch'
productFlavors {
arm8 {
dimension 'cpuArch'
ndk {
abiFilters 'arm64-v8a'
}
}
arm7 {
dimension 'cpuArch'
ndk {
abiFilters 'armeabi-v7a'
}
}
x86_64 {
dimension 'cpuArch'
ndk {
abiFilters 'x86_64'
}
}
x86 {
dimension 'cpuArch'
ndk {
abiFilters 'x86'
}
}
universal {
dimension 'cpuArch'
}
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat'
}
}
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'
}

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.textureview">
<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=".MainActivity">
<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,339 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.textureview
import android.animation.ValueAnimator
import android.app.Activity
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.TextureView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
// Make sure to initialize Filament first
// This loads the JNI library needed by most API calls
companion object {
init {
Filament.init()
}
}
// The View we want to render into
private lateinit var textureView: TextureView
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
private lateinit var uiHelper: UiHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
private lateinit var material: Material
private lateinit var vertexBuffer: VertexBuffer
private lateinit var indexBuffer: IndexBuffer
// Filament entity representing a renderable object
@Entity private var renderable = 0
// A swap chain is Filament's representation of a surface
private var swapChain: SwapChain? = null
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
textureView = TextureView(this)
setContentView(textureView)
choreographer = Choreographer.getInstance()
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
// NOTE: To choose a specific rendering resolution, add the following line:
// uiHelper.setDesiredSize(1280, 720)
uiHelper.attachTo(textureView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
}
private fun setupView() {
// Clear the background to middle-grey
// Setting up a clear color is useful for debugging but usually
// unnecessary when using a skybox
view.setClearColor(0.035f, 0.035f, 0.035f, 1.0f)
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
// view.isPostProcessingEnabled = false
// Tell the view which camera we want to use
view.camera = camera
// Tell the view which scene we want to render
view.scene = scene
}
private fun setupScene() {
loadMaterial()
createMesh()
// To create a renderable we first create a generic entity
renderable = EntityManager.get().create()
// We then create a renderable component on that entity
// A renderable is made of several primitives; in this case we declare only 1
RenderableManager.Builder(1)
// Overall bounding box of the renderable
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.01f))
// Sets the mesh data of the first primitive
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
// Sets the material of the first primitive
.material(0, material.defaultInstance)
.build(engine, renderable)
// Add the entity to the scene to render it
scene.addEntity(renderable)
startAnimation()
}
private fun loadMaterial() {
readUncompressedAsset("materials/baked_color.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
private fun createMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
// A vertex is a position + a color:
// 3 floats for XYZ position, 1 integer for color
val vertexSize = 3 * floatSize + intSize
// Define a vertex and a function to put a vertex in a ByteBuffer
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
// We are going to generate a single triangle
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
// It is important to respect the native byte order
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
// Make sure the cursor is pointing in the right place in the byte buffer
.flip()
// Declare the layout of our mesh
vertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
// Because we interleave position and color data we must specify offset and stride
// We could use de-interleaved data by declaring two buffers and giving each
// attribute a different buffer index
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
// We store colors as unsigned bytes but since we want values between 0 and 1
// in the material (shaders), we must mark the attribute as normalized
.normalized(VertexAttribute.COLOR)
.build(engine)
// Feed the vertex data to the mesh
// We only set 1 buffer because the data is interleaved
vertexBuffer.setBufferAt(engine, 0, vertexData)
// Create the indices
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
indexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
indexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
// Animate the triangle
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener {
val transformMatrix = FloatArray(16)
override fun onAnimationUpdate(a: ValueAnimator) {
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(renderable), transformMatrix)
}
})
animator.start()
}
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()
// 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
Fence.waitAndDestroy(engine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH)
// Cleanup all resources
engine.destroyEntity(renderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(vertexBuffer)
engine.destroyIndexBuffer(indexBuffer)
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(renderable)
// 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) {
// Schedule the next frame
choreographer.postFrameCallback(this)
// This check guarantees that we have a swap chain
if (uiHelper.isReadyToRender) {
// If beginFrame() returns false you should skip the frame
// This means you are sending frames too quickly to the GPU
if (renderer.beginFrame(swapChain!!)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
}
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) {
val zoom = 1.5
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO,
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
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() }
}
}
}

View File

@@ -0,0 +1,32 @@
// Simple unlit material that uses the colors associated with each vertex.
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.
material {
name : baked_color,
// Lists the required vertex attributes
// Here we only need a color (RGBA)
requires : [
color
],
// This material disables all lighting
shadingModel : unlit,
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}

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">Texture View</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.3.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

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Mon Jan 14 11:07:34 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

172
android/samples/texture-view/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=""
# 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" "$@"

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=
@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,3 @@
includeBuild '../../filament-android'
include ':app'

View File

@@ -60,7 +60,7 @@ private fun loadIndirectLight(
assets: AssetManager,
name: String,
engine: Engine): Pair<IndirectLight, Texture> {
val (w, h) = peekSize(assets, "$name/nx.rgbm")
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
val texture = Texture.Builder()
.width(w)
.height(h)

View File

@@ -69,12 +69,16 @@ fun loadMesh(assets: AssetManager, name: String,
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
private const val MAX_UINT32 = 4294967295
private const val HEADER_FLAG_INTERLEAVED = 0x1L
private const val HEADER_FLAG_SNORM16_UV = 0x2L
private const val HEADER_FLAG_COMPRESSED = 0x4L
private class Header {
var valid = false
var versionNumber = 0L
var parts = 0L
var aabb = Box()
var interleaved = 0L
var flags = 0L
var posOffset = 0L
var positionStride = 0L
var tangentOffset = 0L
@@ -121,7 +125,7 @@ private fun readHeader(input: InputStream): Header {
header.aabb = Box(
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
header.interleaved = readUIntLE(input)
header.flags = readUIntLE(input)
header.posOffset = readUIntLE(input)
header.positionStride = readUIntLE(input)
header.tangentOffset = readUIntLE(input)
@@ -142,7 +146,6 @@ private fun readHeader(input: InputStream): Header {
return header
}
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
buffer.order(ByteOrder.LITTLE_ENDIAN)
@@ -190,7 +193,15 @@ private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer):
.apply { setBuffer(engine, data) }
}
private fun uvNormalized(header: Header) = header.flags and HEADER_FLAG_SNORM16_UV != 0L
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
val uvType = if (!uvNormalized(header)) {
HALF2
} else {
SHORT2
}
val vertexBufferBuilder = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(header.totalVertices.toInt())
@@ -203,13 +214,18 @@ private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer)
.attribute(POSITION, 0, HALF4, header.posOffset.toInt(), header.positionStride.toInt())
.attribute(TANGENTS, 0, SHORT4, header.tangentOffset.toInt(), header.tangentStride.toInt())
.attribute(COLOR, 0, UBYTE4, header.colorOffset.toInt(), header.colorStride.toInt())
// UV coordinates are stored in fp16, which gives sub-pixel precision only
// for textures up to 1024x1024
.attribute(UV0, 0, HALF2, header.uv0Offset.toInt(), header.uv0Stride.toInt())
// UV coordinates are stored as normalized 16-bit integers or half-floats depending on
// the range they span. When stored as half-float, there is only enough precision for
// sub-pixel addressing in textures that are <= 1024x1024
.attribute(UV0, 0, uvType, header.uv0Offset.toInt(), header.uv0Stride.toInt())
// When UV coordinates are stored as 16-bit integers we must normalize them (we want
// values in the range -1..1)
.normalized(UV0, uvNormalized(header))
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
vertexBufferBuilder
.attribute(UV1, 0, HALF2, header.uv1Offset.toInt(), header.uv1Stride.toInt())
.attribute(UV1, 0, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
.normalized(UV1, uvNormalized(header))
}
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }

View File

@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.0'
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong

View File

@@ -1,6 +1,6 @@
#Tue Aug 28 15:45:13 PDT 2018
#Mon Jan 14 11:04:36 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

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/materials/*.filamat
.externalNativeBuild

View File

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

View File

@@ -0,0 +1,80 @@
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")
}
preBuild.dependsOn compileMaterials
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.google.android.filament.hellotriangle"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// Filament comes with native code, the following declarations
// can be used to generate architecture specific APKs
flavorDimensions 'cpuArch'
productFlavors {
arm8 {
dimension 'cpuArch'
ndk {
abiFilters 'arm64-v8a'
}
}
arm7 {
dimension 'cpuArch'
ndk {
abiFilters 'armeabi-v7a'
}
}
x86_64 {
dimension 'cpuArch'
ndk {
abiFilters 'x86_64'
}
}
x86 {
dimension 'cpuArch'
ndk {
abiFilters 'x86'
}
}
universal {
dimension 'cpuArch'
}
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat'
}
}
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'
}

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.transparentrendering">
<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.transparentrendering.MainActivity">
<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,357 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.transparentrendering
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.Activity
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Gravity
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import android.widget.FrameLayout
import android.widget.TextView
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
// Make sure to initialize Filament first
// This loads the JNI library needed by most API calls
companion object {
init {
Filament.init()
}
}
// The View we want to render into
private lateinit var surfaceView: SurfaceView
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
private lateinit var uiHelper: UiHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
private lateinit var material: Material
private lateinit var vertexBuffer: VertexBuffer
private lateinit var indexBuffer: IndexBuffer
// Filament entity representing a renderable object
@Entity private var renderable = 0
// A swap chain is Filament's representation of a surface
private var swapChain: SwapChain? = null
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
choreographer = Choreographer.getInstance()
surfaceView = SurfaceView(this)
val textView = TextView(this).apply {
val d = resources.displayMetrics.density
text = "This TextView is under the Filament SurfaceView."
textSize = 32.0f
setPadding((16 * d).toInt(), 0, (16 * d).toInt(), 0)
}
setContentView(FrameLayout(this).apply {
addView(textView, FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_VERTICAL
))
addView(surfaceView)
})
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
// Make the render target transparent
uiHelper.isOpaque = false
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
}
private fun setupView() {
// Make sure to clear to a fully transparent color
view.setClearColor(0.0f, 0.0f, 0.0f, 0.0f)
// Tell the view which camera we want to use
view.camera = camera
// Tell the view which scene we want to render
view.scene = scene
}
private fun setupScene() {
loadMaterial()
createMesh()
// To create a renderable we first create a generic entity
renderable = EntityManager.get().create()
// We then create a renderable component on that entity
// A renderable is made of several primitives; in this case we declare only 1
RenderableManager.Builder(1)
// Overall bounding box of the renderable
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.01f))
// Sets the mesh data of the first primitive
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
// Sets the material of the first primitive
.material(0, material.defaultInstance)
.build(engine, renderable)
// Add the entity to the scene to render it
scene.addEntity(renderable)
startAnimation()
}
private fun loadMaterial() {
readUncompressedAsset("materials/baked_color.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
private fun createMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
// A vertex is a position + a color:
// 3 floats for XYZ position, 1 integer for color
val vertexSize = 3 * floatSize + intSize
// Define a vertex and a function to put a vertex in a ByteBuffer
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
// We are going to generate a single triangle
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
// It is important to respect the native byte order
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
// Make sure the cursor is pointing in the right place in the byte buffer
.flip()
// Declare the layout of our mesh
vertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
// Because we interleave position and color data we must specify offset and stride
// We could use de-interleaved data by declaring two buffers and giving each
// attribute a different buffer index
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
// We store colors as unsigned bytes but since we want values between 0 and 1
// in the material (shaders), we must mark the attribute as normalized
.normalized(VertexAttribute.COLOR)
.build(engine)
// Feed the vertex data to the mesh
// We only set 1 buffer because the data is interleaved
vertexBuffer.setBufferAt(engine, 0, vertexData)
// Create the indices
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
indexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
indexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
// Animate the triangle
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener {
val transformMatrix = FloatArray(16)
override fun onAnimationUpdate(a: ValueAnimator) {
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(renderable), transformMatrix)
}
})
animator.start()
}
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()
// 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
Fence.waitAndDestroy(engine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH)
// Cleanup all resources
engine.destroyEntity(renderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(vertexBuffer)
engine.destroyIndexBuffer(indexBuffer)
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(renderable)
// 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) {
// Schedule the next frame
choreographer.postFrameCallback(this)
// This check guarantees that we have a swap chain
if (uiHelper.isReadyToRender) {
// If beginFrame() returns false you should skip the frame
// This means you are sending frames too quickly to the GPU
if (renderer.beginFrame(swapChain!!)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
}
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) {
val zoom = 1.5
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO,
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
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() }
}
}
}

View File

@@ -0,0 +1,32 @@
// Simple unlit material that uses the colors associated with each vertex.
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.
material {
name : baked_color,
// Lists the required vertex attributes
// Here we only need a color (RGBA)
requires : [
color
],
// This material disables all lighting
shadingModel : unlit,
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}

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

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