Compare commits

..

104 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
246 changed files with 11604 additions and 993 deletions

View File

@@ -169,7 +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")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
# 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}")
# ==================================================================================================
@@ -223,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
# ==================================================================================================
@@ -288,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)
@@ -311,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)
@@ -333,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)
@@ -354,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)
@@ -375,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)
@@ -387,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

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('-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

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

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

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

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

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

@@ -20,6 +20,8 @@ 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;
@@ -27,6 +29,98 @@ 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;
@@ -42,22 +136,39 @@ public class UiHelper {
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);
}
@@ -114,29 +225,44 @@ public class UiHelper {
}
/**
* 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();
@@ -144,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.
*
@@ -164,7 +283,7 @@ public class UiHelper {
}
/**
* Set the size of the render target buffers.
* Set the size of the render target buffers of the native surface.
*/
public void setDesiredSize(int width, int height) {
mDesiredWidth = width;
@@ -174,10 +293,16 @@ 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;
}
@@ -202,6 +327,11 @@ public class UiHelper {
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;
}
@@ -212,7 +342,7 @@ public class UiHelper {
* 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) {
public void attachTo(@NonNull SurfaceView view) {
if (attach(view)) {
if (!isOpaque()) {
view.setZOrderOnTop(true);
@@ -261,7 +391,7 @@ 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) {
public void attachTo(@NonNull TextureView view) {
if (attach(view)) {
view.setOpaque(isOpaque());
@@ -274,13 +404,20 @@ public class UiHelper {
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
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
@@ -311,7 +448,7 @@ public class UiHelper {
}
}
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) {
@@ -324,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

@@ -33,6 +33,12 @@ 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
@@ -66,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

@@ -18,23 +18,20 @@ package com.google.android.filament.hellotriangle
import android.animation.ValueAnimator
import android.app.Activity
import android.graphics.PixelFormat
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.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

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

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

@@ -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:05:59 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

@@ -4,7 +4,8 @@ set -e
# NDK API level
API_LEVEL=21
# Host tools required by Android, WebGL, and iOS builds
HOST_TOOLS="matc cmgen filamesh mipgen resgen"
MOBILE_HOST_TOOLS="matc resgen cmgen"
WEB_HOST_TOOLS="${MOBILE_HOST_TOOLS} mipgen filamesh"
IOS_TOOLCHAIN_URL="https://opensource.apple.com/source/clang/clang-800.0.38/src/cmake/platforms/iOS.cmake"
function print_help {
@@ -40,6 +41,8 @@ function print_help {
echo " Add Vulkan support to the Android build."
echo " -s"
echo " Add iOS simulator support to the iOS build."
echo " -l"
echo " Add filamat support to the Android build."
echo ""
echo "Build types:"
echo " release"
@@ -99,6 +102,9 @@ GENERATE_TOOLCHAINS=false
VULKAN_ANDROID_OPTION="-DFILAMENT_SUPPORTS_VULKAN=OFF"
BUILD_FILAMAT_ANDROID=false
FILAMAT_ANDROID_OPTION="-DFILAMENT_BUILD_FILAMAT=OFF"
IOS_BUILD_SIMULATOR=false
BUILD_GENERATOR=Ninja
@@ -116,6 +122,7 @@ function build_clean {
echo "Cleaning build directories..."
rm -Rf out
rm -Rf android/filament-android/build
rm -Rf android/filament-android/.externalNativeBuild
}
function generate_toolchain {
@@ -215,6 +222,8 @@ function build_webgl_with_target {
ISSUE_CMAKE_ALWAYS=true
fi
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
# Apply the emscripten environment within a subshell.
(
source ${EMSDK}/emsdk_env.sh
cmake \
-G "$BUILD_GENERATOR" \
@@ -224,6 +233,7 @@ function build_webgl_with_target {
-DWEBGL=1 \
../..
${BUILD_COMMAND} ${BUILD_TARGETS}
)
fi
if [ -d "web/filament-js" ]; then
@@ -263,7 +273,7 @@ function build_webgl {
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}; INSTALL_COMMAND=
OLD_ISSUE_DEBUG_BUILD=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
OLD_ISSUE_RELEASE_BUILD=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
build_desktop "${HOST_TOOLS}"
build_desktop "${WEB_HOST_TOOLS}"
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
ISSUE_DEBUG_BUILD=${OLD_ISSUE_DEBUG_BUILD}
ISSUE_RELEASE_BUILD=${OLD_ISSUE_RELEASE_BUILD}
@@ -293,6 +303,7 @@ function build_android_target {
-DCMAKE_INSTALL_PREFIX=../android-${LC_TARGET}/filament \
-DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-${ARCH}-linux-android.cmake \
$VULKAN_ANDROID_OPTION \
$FILAMAT_ANDROID_OPTION \
../..
fi
@@ -338,7 +349,7 @@ function build_android {
# Supress intermediate desktop tools install
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}
INSTALL_COMMAND=
build_desktop "${HOST_TOOLS}"
build_desktop "${MOBILE_HOST_TOOLS}"
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
build_android_arch "aarch64" "aarch64-linux-android" "arm64"
@@ -377,6 +388,33 @@ function build_android {
fi
cd ../..
if [ "$BUILD_FILAMAT_ANDROID" == "true" ]; then
cd android/filamat-android
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
./gradlew -Pfilament_dist_dir=../../out/android-debug/filament assembleDebug
if [ "$INSTALL_COMMAND" ]; then
echo "Installing out/filamat-android-debug.aar..."
cp build/outputs/aar/filamat-android-debug.aar ../../out/
fi
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
if [ "$INSTALL_COMMAND" ]; then
echo "Installing out/filamat-android-release.aar..."
cp build/outputs/aar/filamat-android-release.aar ../../out/
fi
fi
cd ../..
fi
}
function ensure_ios_toolchain {
@@ -450,7 +488,7 @@ function build_ios {
# Supress intermediate desktop tools install
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}
INSTALL_COMMAND=
build_desktop "${HOST_TOOLS}"
build_desktop "${MOBILE_HOST_TOOLS}"
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
ensure_ios_toolchain
@@ -523,16 +561,24 @@ function run_test {
}
function run_tests {
while read test; do
run_test "$test"
done < build/common/test_list.txt
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
echo "TypeScript `tsc --version`"
tsc --noEmit \
third_party/gl-matrix/gl-matrix.d.ts \
web/filament-js/filament.d.ts \
web/filament-js/test.ts
else
while read test; do
run_test "$test"
done < build/common/test_list.txt
fi
}
# Beginning of the script
pushd `dirname $0` > /dev/null
while getopts ":hacfijmp:tuvs" opt; do
while getopts ":hacfijmp:tuvsl" opt; do
case ${opt} in
h)
print_help
@@ -599,7 +645,13 @@ while getopts ":hacfijmp:tuvs" opt; do
echo "To switch your application to Vulkan, in Android Studio go to "
echo "File > Settings > Build > Compiler. In the command-line options field, "
echo "add -Pextra_cmake_args=-DFILAMENT_SUPPORTS_VULKAN=ON."
echo "Also be sure to pass Backend::VULKAN to Engine::create."
echo "Also be sure to pass Engine.Backend.VULKAN to Engine.create."
echo ""
;;
l)
FILAMAT_ANDROID_OPTION="-DFILAMENT_BUILD_FILAMAT=ON"
BUILD_FILAMAT_ANDROID=true
echo "Building filamat JNI library for Android."
echo ""
;;
s)

View File

@@ -26,5 +26,8 @@ elif [ "$LC_UNAME" == "darwin" ]; then
fi
source `dirname $0`/../common/build-common.sh
yes | $ANDROID_HOME/tools/bin/sdkmanager --update >/dev/null && \
yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null
pushd `dirname $0`/../.. > /dev/null
./build.sh -p android -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE

View File

@@ -1,9 +1,9 @@
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData
filament/test/test_filament_exposure --gtest_filter=-FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100
libs/math/test_math
libs/image/test_image compare libs/image/tests/reference/
libs/utils/test_utils
libs/filamat/test_filamat
tools/matc/test_matc
tools/cmgen/test_cmgen compare
tools/glslminifier/test_glslminifier
libs/filameshio/test_filameshio

View File

@@ -28,8 +28,13 @@ set(DIST_ARCH arm64-v8a)
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
# specify the cross compiler
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
set(COMPILER_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)

View File

@@ -28,8 +28,13 @@ set(DIST_ARCH armeabi-v7a)
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
# specify the cross compiler
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
set(COMPILER_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)

View File

@@ -28,8 +28,13 @@ set(DIST_ARCH x86)
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
# specify the cross compiler
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
set(COMPILER_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)

View File

@@ -28,8 +28,13 @@ set(DIST_ARCH x86_64)
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
# specify the cross compiler
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
set(COMPILER_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)

View File

@@ -14,6 +14,6 @@ set -x
source `dirname $0`/../common/ci-common.sh
source `dirname $0`/ci-common.sh
source `dirname $0`/../common/build-common.sh
pushd `dirname $0`/../.. > /dev/null
./build.sh -p webgl -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
./build.sh -p webgl -c $RUN_TESTS $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE

View File

@@ -10,6 +10,10 @@ export PATH="$PWD:$PATH"
python3 --version
pip3 install mistletoe pygments jsbeautifier future_fstrings
# Install a typescript compiler to allow testing.
npm install -g typescript
# Install a specific version of emscripen to avoid surprises.
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
unzip emsdk.zip
mv emsdk-* emsdk

View File

@@ -2367,7 +2367,8 @@ using an environment made of colored vertical stripes (skybox hidden).](images/i
When sampling the IBL, the clear coat layer is calculated as a second specular lobe. This specular lobe is oriented along the view direction since we cannot reasonably integrate over the hemisphere. Listing [clearCoatIBL] demonstrates this approximation in practice. It also shows the energy conservation step. It is important to note that this second specular lobe is computed exactly the same way as the main specular lobe, using the same DFG approximation.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float Fc = F_Schlick(0.04, 1.0, shading_NoV) * clearCoat;
// clearCoat_NoV == shading_NoV if the clear coat layer doesn't have its own normal map
float Fc = F_Schlick(0.04, 1.0, clearCoat_NoV) * clearCoat;
// base layer attenuation for energy compensation
iblDiffuse *= 1.0 - Fc;
iblSpecular *= sq(1.0 - Fc);

View File

@@ -1084,6 +1084,48 @@ fragment {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### curvatureToRoughness
Type
: `boolean`
Value
: `true` or `false`. Defaults to `false`.
Description
: Reduces specular aliasing by increasing roughness based on the local geometric curvature.
This property is particularly effective if you only use MSAA.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
curvatureToRoughness : true
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
![Figure [curvatureToRoughness]: Close up of a glossy metallic surface rendered normally (left) and
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.png)
### limitOverInterpolation
Type
: `boolean`
Value
: `true` or `false`. Defaults to `false`.
Description
: Reduces specular aliasing by attempting to eliminate normal over-interpolation. When this
property is turned on, the material switches to centroid normal interpolation when the
interpolated normals are too long. This property should only be used if your anti-aliasing
method is MSAA. The effects are a lot more subtle than `curvatureToRoughness`, which should be
used first to eliminate specular aliasing.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
limitOverInterpolation : true
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### variantFilter
Type
@@ -1117,6 +1159,25 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### flipUV
Type
: `boolean`
Value
: `true` or `false`. Defaults to `true`.
Description
: When set to `true` (default value), the Y coordinate of UV attributes will be flipped when
read by this material's vertex shader. Flipping is equivalent to `y = 1.0 - y`. When set
to `false`, flipping is disabled and the UV attributes are read as is.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
flipUV : false
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Vertex block
The vertex block is optional and can be used to control the vertex shading stage of the material.
@@ -1173,6 +1234,11 @@ struct MaterialVertexInputs {
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! TIP: UV attributes
By default the vertex shader of a material will flip the Y coordinate of the UV attributes
of the current mesh: `material.uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y)`. You can control
this behavior using the `flipUV` property and setting it to `false`.
## Fragment block
The fragment block must be used to control the fragment shading stage of the material. The vertex

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

View File

@@ -46,6 +46,9 @@ set(SRCS
src/components/LightManager.cpp
src/components/RenderableManager.cpp
src/components/TransformManager.cpp
src/fg/FrameGraph.cpp
src/driver/noop/NoopDriver.cpp
src/driver/noop/PlatformNoop.cpp
src/driver/opengl/gl_headers.cpp
src/driver/opengl/OpenGLBlitter.cpp
src/driver/opengl/GLUtils.cpp
@@ -100,6 +103,10 @@ set(PRIVATE_HDRS
src/components/LightManager.h
src/components/RenderableManager.h
src/components/TransformManager.h
src/fg/FrameGraph.h
src/fg/FrameGraphPass.h
src/fg/FrameGraphPassResources.h
src/fg/FrameGraphResource.h
src/details/Allocators.h
src/details/Camera.h
src/details/Culler.h
@@ -128,6 +135,7 @@ set(PRIVATE_HDRS
src/driver/CommandBufferQueue.h
src/driver/CommandStream.h
src/driver/CommandStreamDispatcher.h
src/driver/DataReshaper.h
src/driver/Driver.h
src/driver/DriverAPI.inc
src/driver/DriverApi.h
@@ -152,17 +160,6 @@ set(MATERIAL_SRCS
src/materials/skyboxRGBM.mat
)
# The noop driver is only useful for ensuring we don't have certain build issues.
# Remove it from release builds, since it uses some space needlessly.
if (CMAKE_BUILD_TYPE MATCHES Debug)
list(APPEND SRCS src/driver/noop/NoopDriver.cpp)
list(APPEND SRCS src/driver/noop/PlatformNoop.cpp)
endif()
if(IOS AND NOT FILAMENT_SUPPORTS_VULKAN)
message(FATAL_ERROR "Filament for iOS must be built with Vulkan support.")
endif()
# Embed the binary resource blob for materials.
get_resgen_vars(${RESOURCE_DIR} materials)
list(APPEND PRIVATE_HDRS ${RESGEN_HEADER})
@@ -200,6 +197,17 @@ endif()
# "2" corresponds to SYSTRACE_TAG_FILEMENT (See: utils/Systrace.h)
add_definitions(-DSYSTRACE_TAG=2 )
# ==================================================================================================
# Metal Sources
# ==================================================================================================
if (FILAMENT_SUPPORTS_METAL)
list(APPEND SRCS
src/driver/metal/MetalDriver.mm
src/driver/metal/PlatformMetal.mm
)
endif()
# ==================================================================================================
# Vulkan Sources
# ==================================================================================================
@@ -247,8 +255,8 @@ else()
set(MATC_TARGET desktop)
endif()
# Include SPIRV when building default materials on platforms that support Vulkan.
if (FILAMENT_SUPPORTS_VULKAN)
# Generate shader code for all platforms when Vulkan or Metal is supported.
if (FILAMENT_SUPPORTS_VULKAN OR FILAMENT_SUPPORTS_METAL)
set(MATC_BASE_FLAGS -a all)
else()
set(MATC_BASE_FLAGS -a opengl)
@@ -348,6 +356,10 @@ if (FILAMENT_SUPPORTS_VULKAN)
target_link_libraries(${TARGET} PUBLIC bluevk vkmemalloc)
endif()
if (FILAMENT_SUPPORTS_METAL)
target_link_libraries(${TARGET} PUBLIC "-framework Metal")
endif()
if (LINUX)
target_link_libraries(${TARGET} PRIVATE dl)
endif()

View File

@@ -25,6 +25,8 @@
#include <math/vec4.h>
#include <math/vec2.h>
#include <utils/unwindows.h> // Because we define NEAR and FAR in the Plane enum.
namespace filament {
namespace details {

View File

@@ -136,8 +136,6 @@ class FLightManager;
* On the other hand, a scene can contain hundreds of non overlapping lights without
* incurring a significant overhead.
*
* 3. Use Type.Static Lights as much as possible.
*
*/
class UTILS_PUBLIC LightManager : public FilamentAPI {
struct BuilderDetails;
@@ -477,8 +475,6 @@ public:
* @param i Instance of the component obtained from getInstance().
* @param position Light's position in world space. The default is at the origin.
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.position()
*/
void setPosition(Instance i, const math::float3& position) noexcept;
@@ -493,8 +489,6 @@ public:
* @param direction Light's direction in world space. Should be a unit vector.
* The default is {0,-1,0}.
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.direction()
*/
void setDirection(Instance i, const math::float3& direction) noexcept;
@@ -509,8 +503,6 @@ public:
* @param color Color of the light specified in the linear sRGB color-space.
* The default is white {1,1,1}.
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.color(), getInstance()
*/
void setColor(Instance i, const LinearColor& color) noexcept;
@@ -531,8 +523,6 @@ public:
* - For point lights and spot lights, it specifies the luminous power
* in *lumen*.
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.intensity()
*/
void setIntensity(Instance i, float intensity) noexcept;
@@ -554,8 +544,6 @@ public:
* LED | 8.7%
* Fluorescent | 10.7%
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.intensity(float watts, float efficiency)
*/
void setIntensity(Instance i, float watts, float efficiency) noexcept {
@@ -579,8 +567,6 @@ public:
* @param i Instance of the component obtained from getInstance().
* @param radius falloff distance in world units. Default is 1 meter.
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.falloff()
*/
void setFalloff(Instance i, float radius) noexcept;
@@ -599,8 +585,6 @@ public:
* @param inner inner cone angle in *radians* between 0 and @f$ \pi @f$
* @param outer outer cone angle in *radians* between 0 and @f$ \pi @f$
*
* @note ignored for Mode.STATIC lights.
*
* @see Builder.spotLightCone()
*/
void setSpotLightCone(Instance i, float inner, float outer) noexcept;

View File

@@ -64,7 +64,7 @@ public:
uint8_t byteStride = 0) noexcept; // default is attribute size
// no-op if attribute is an invalid enum
Builder& normalized(VertexAttribute attribute) noexcept;
Builder& normalized(VertexAttribute attribute, bool normalize = true) noexcept;
/**
* Creates the VertexBuffer object and returns a pointer to it.

View File

@@ -118,6 +118,12 @@ public:
uint32_t* width, uint32_t* height) noexcept = 0;
};
class UTILS_PUBLIC MetalPlatform : public Platform {
public:
~MetalPlatform() noexcept override;
};
} // namespace driver
} // namespace filament

View File

@@ -257,6 +257,8 @@ void FEngine::shutdown() {
destroy(mDefaultIblTexture);
destroy(mDefaultIbl);
destroy(mDefaultMaterial);
/*
* clean-up after the user -- we call terminate on each "leaked" object and clear each list.
*
@@ -354,10 +356,25 @@ int FEngine::loop() {
if (platform == nullptr) {
platform = Platform::create(&mBackend);
mPlatform = platform;
#if !defined(NDEBUG)
slog.d << "FEngine resolved backend: "
<< (mBackend == driver::Backend::VULKAN ? "Vulkan" : "OpenGL") << io::endl;
#endif
slog.d << "FEngine resolved backend: ";
switch (mBackend) {
case driver::Backend::OPENGL:
slog.d << "OpenGL";
break;
case driver::Backend::VULKAN:
slog.d << "Vulkan";
break;
case driver::Backend::METAL:
slog.d << "Metal";
break;
default:
slog.d << "Unknown";
break;
}
slog.d << io::endl;
}
mDriver = platform->createDriver(mSharedGLContext);
mDriverBarrier.latch();
@@ -416,9 +433,10 @@ Handle<HwProgram> FEngine::createPostProcessProgram(MaterialParser& parser,
// need to populate a SamplerBindingMap and pass a weak reference to Program. Binding maps are
// normally owned by Material, but in this case we'll simply own a copy right here in static
// storage.
static const SamplerBindingMap* pBindings = [] {
static const SamplerBindingMap* pBindings = [backend = this->mBackend] {
static SamplerBindingMap bindings;
bindings.populate();
uint8_t offset = filament::getSamplerBindingsStart(backend);
bindings.populate(offset);
return &bindings;
}();

View File

@@ -22,6 +22,8 @@
#include "FilamentAPI-impl.h"
#include <filament/driver/DriverEnums.h>
#include <private/filament/SibGenerator.h>
#include <private/filament/UibGenerator.h>
#include <private/filament/Variant.h>
@@ -123,9 +125,9 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
UTILS_UNUSED_IN_RELEASE bool uibOK = parser->getUIB(&mUniformInterfaceBlock);
assert(uibOK);
// Sampler bindings are only required for Vulkan.
UTILS_UNUSED_IN_RELEASE bool sbOK = parser->getSamplerBindingMap(&mSamplerBindings);
assert(engine.getBackend() == Backend::OPENGL || sbOK);
// Populate sampler bindings for the backend that will consume this Material.
const uint8_t offset = getSamplerBindingsStart(engine.getBackend());
mSamplerBindings.populate(offset, &mSamplerInterfaceBlock);
parser->getShading(&mShading);
parser->getBlendingMode(&mBlendingMode);

View File

@@ -19,6 +19,8 @@
#include "details/Engine.h"
#include "fg/FrameGraph.h"
#include <private/filament/SibGenerator.h>
#include <utils/Log.h>
@@ -39,7 +41,8 @@ void PostProcessManager::init(FEngine& engine) noexcept {
// create sampler for post-process FBO
DriverApi& driver = engine.getDriverApi();
mPostProcessSbh = driver.createSamplerBuffer(engine.getPostProcessSib().getSize());
mPostProcessUbh = driver.createUniformBuffer(engine.getPerPostProcessUib().getSize(), driver::BufferUsage::DYNAMIC);
mPostProcessUbh = driver.createUniformBuffer(engine.getPerPostProcessUib().getSize(),
driver::BufferUsage::DYNAMIC);
driver.bindSamplers(BindingPoints::POST_PROCESS, mPostProcessSbh);
driver.bindUniformBuffer(BindingPoints::POST_PROCESS, mPostProcessUbh);
}
@@ -50,7 +53,7 @@ void PostProcessManager::terminate(driver::DriverApi& driver) noexcept {
}
void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeight,
const RenderTargetPool::Target* pos) const noexcept {
Handle<HwTexture> texture, uint32_t textureWidth, uint32_t textureHeight) const noexcept {
FEngine& engine = *mEngine;
DriverApi& driver = engine.getDriverApi();
@@ -60,7 +63,7 @@ void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeig
params.filterMag = SamplerMagFilter::LINEAR;
params.filterMin = SamplerMinFilter::LINEAR;
SamplerBuffer sb(engine.getPostProcessSib());
sb.setSampler(PostProcessSib::COLOR_BUFFER, pos->texture, params);
sb.setSampler(PostProcessSib::COLOR_BUFFER, texture, params);
auto duration = engine.getEngineTime();
float fraction = (duration.count() % 1000000000) / 1000000000.0f;
@@ -68,11 +71,11 @@ void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeig
UniformBuffer& ub = mPostProcessUb;
ub.setUniform(offsetof(PostProcessingUib, time), fraction);
ub.setUniform(offsetof(PostProcessingUib, uvScale),
math::float2{ viewportWidth, viewportHeight } / math::float2{ pos->w, pos->h });
math::float2{ viewportWidth, viewportHeight } / math::float2{ textureWidth, textureHeight });
// The shader may need to know the offset between the top of the texture and the top
// of the rectangle that it actually needs to sample from.
const float yOffset = pos->h - viewportHeight;
const float yOffset = textureHeight - viewportHeight;
ub.setUniform(offsetof(PostProcessingUib, yOffset), yOffset);
driver.updateSamplerBuffer(mPostProcessSbh, std::move(sb));
@@ -134,7 +137,7 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
if (commands[i].program) {
// set the source for this pass (i.e. previous target)
setSource(params.width, params.height, previous);
setSource(params.width, params.height, previous->texture, previous->w, previous->h);
// draw a full screen triangle
pipeline.program = commands[i].program;
@@ -164,7 +167,7 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
params.width = vp.width;
params.height = vp.height;
setSource(params.width, params.height, previous);
setSource(params.width, params.height, previous->texture, previous->w, previous->h);
pipeline.program = commands.back().program;
driver.beginRenderPass(viewRenderTarget, params);
driver.draw(pipeline, fullScreenRenderPrimitive);
@@ -182,4 +185,175 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
commands.clear();
}
// ------------------------------------------------------------------------------------------------
FrameGraphResource PostProcessManager::msaa(FrameGraph& fg,
FrameGraphResource input, driver::TextureFormat outFormat) noexcept {
struct PostProcessMSAA {
FrameGraphResource input;
FrameGraphResource output;
};
auto& ppMSAA = fg.addPass<PostProcessMSAA>("msaa",
[&](FrameGraph::Builder& builder, PostProcessMSAA& data) {
auto const* inputDesc = fg.getDescriptor(input);
data.input = builder.blit(input);
FrameGraphResource::Descriptor outputDesc{
.width = inputDesc->width,
.height = inputDesc->height,
.format = outFormat
};
data.output = builder.write(builder.createResource("msaa output", outputDesc));
},
[=](FrameGraphPassResources const& resources,
PostProcessMSAA const& data, DriverApi& driver) {
auto in = resources.getRenderTarget(data.input);
auto out = resources.getRenderTarget(data.output);
auto const& desc = resources.getDescriptor(data.input);
driver.blit(TargetBufferFlags::COLOR,
out.target, 0, 0, desc.width, desc.height,
in.target, 0, 0, desc.width, desc.height);
});
return ppMSAA.getData().output;
}
FrameGraphResource PostProcessManager::toneMapping(FrameGraph& fg,
FrameGraphResource input, driver::TextureFormat outFormat, bool translucent) noexcept {
FEngine* engine = mEngine;
Handle<HwRenderPrimitive> const& fullScreenRenderPrimitive = engine->getFullScreenRenderPrimitive();
struct PostProcessToneMapping {
FrameGraphResource input;
FrameGraphResource output;
};
Handle<HwProgram> toneMappingProgram = engine->getPostProcessProgram(
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
: PostProcessStage::TONE_MAPPING_OPAQUE);
auto& ppToneMapping = fg.addPass<PostProcessToneMapping>("tonemapping",
[&](FrameGraph::Builder& builder, PostProcessToneMapping& data) {
auto const* inputDesc = fg.getDescriptor(input);
data.input = builder.read(input);
FrameGraphResource::Descriptor outputDesc{
.width = inputDesc->width,
.height = inputDesc->height,
.format = outFormat
};
data.output = builder.write(
builder.createResource("tonemapping output", outputDesc));
},
[=](FrameGraphPassResources const& resources,
PostProcessToneMapping const& data, DriverApi& driver) {
Driver::PipelineState pipeline;
pipeline.rasterState.culling = Driver::RasterState::CullingMode::NONE;
pipeline.rasterState.colorWrite = true;
pipeline.rasterState.depthFunc = Driver::RasterState::DepthFunc::A;
pipeline.program = toneMappingProgram;
auto const& targetDesc = resources.getDescriptor(data.output);
auto const& textureDesc = resources.getDescriptor(data.input);
auto const& texture = resources.getTexture(data.input, TextureUsage::COLOR_ATTACHMENT);
setSource(targetDesc.width, targetDesc.height, texture, textureDesc.width, textureDesc.height);
auto const& target = resources.getRenderTarget(data.output);
driver.beginRenderPass(target.target, target.params);
driver.draw(pipeline, fullScreenRenderPrimitive);
driver.endRenderPass();
});
return ppToneMapping.getData().output;
}
FrameGraphResource PostProcessManager::fxaa(FrameGraph& fg,
FrameGraphResource input, driver::TextureFormat outFormat, bool translucent) noexcept {
FEngine* engine = mEngine;
Handle<HwRenderPrimitive> const& fullScreenRenderPrimitive = engine->getFullScreenRenderPrimitive();
struct PostProcessFXAA {
FrameGraphResource input;
FrameGraphResource output;
};
Handle<HwProgram> antiAliasingProgram = engine->getPostProcessProgram(
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
: PostProcessStage::ANTI_ALIASING_OPAQUE);
auto& ppFXAA = fg.addPass<PostProcessFXAA>("fxaa",
[&](FrameGraph::Builder& builder, PostProcessFXAA& data) {
auto* inputDesc = fg.getDescriptor(input);
inputDesc->format = TextureFormat::RGBA8;
data.input = builder.read(input);
FrameGraphResource::Descriptor outputDesc{
.width = inputDesc->width,
.height = inputDesc->height,
.format = outFormat
};
data.output = builder.write(builder.createResource("fxaa output", outputDesc));
},
[=](FrameGraphPassResources const& resources,
PostProcessFXAA const& data, DriverApi& driver) {
Driver::PipelineState pipeline;
pipeline.rasterState.culling = Driver::RasterState::CullingMode::NONE;
pipeline.rasterState.colorWrite = true;
pipeline.rasterState.depthFunc = Driver::RasterState::DepthFunc::A;
pipeline.program = antiAliasingProgram;
auto const& targetDesc = resources.getDescriptor(data.output);
auto const& textureDesc = resources.getDescriptor(data.input);
auto const& texture = resources.getTexture(data.input, TextureUsage::COLOR_ATTACHMENT);
setSource(targetDesc.width, targetDesc.height, texture, textureDesc.width, textureDesc.height);
auto const& target = resources.getRenderTarget(data.output);
driver.beginRenderPass(target.target, target.params);
driver.draw(pipeline, fullScreenRenderPrimitive);
driver.endRenderPass();
});
return ppFXAA.getData().output;
}
FrameGraphResource PostProcessManager::dynamicScaling(FrameGraph& fg,
FrameGraphResource input, driver::TextureFormat outFormat,
Viewport const& outViewport) noexcept {
struct PostProcessScaling {
FrameGraphResource input;
FrameGraphResource output;
};
auto& ppScaling = fg.addPass<PostProcessScaling>("scaling",
[&](FrameGraph::Builder& builder, PostProcessScaling& data) {
auto* inputDesc = fg.getDescriptor(input);
data.input = builder.blit(input);
FrameGraphResource::Descriptor outputDesc{
.width = inputDesc->width,
.height = inputDesc->height,
.format = outFormat
};
data.output = builder.write(builder.createResource("scale output", outputDesc));
},
[=](FrameGraphPassResources const& resources,
PostProcessScaling const& data, DriverApi& driver) {
auto in = resources.getRenderTarget(data.input);
auto out = resources.getRenderTarget(data.output);
auto const& inDesc = resources.getDescriptor(data.input);
driver.blit(TargetBufferFlags::COLOR,
out.target, outViewport.left, outViewport.bottom, outViewport.width,
outViewport.height,
in.target, 0, 0, inDesc.width, inDesc.height);
});
return ppScaling.getData().output;
}
} // namespace filament

View File

@@ -21,6 +21,8 @@
#include "UniformBuffer.h"
#include "fg/FrameGraphResource.h"
#include "driver/DriverApiForward.h"
#include "driver/Handle.h"
@@ -41,8 +43,8 @@ class PostProcessManager {
public:
void init(details::FEngine& engine) noexcept;
void terminate(driver::DriverApi& driver) noexcept;
void setSource(uint32_t viewportWidth, uint32_t viewportHeight,
const RenderTargetPool::Target* pos) const noexcept;
void setSource(uint32_t viewportWidth, uint32_t viewportHeight, Handle <HwTexture> texture,
uint32_t textureWidth, uint32_t textureHeight) const noexcept;
// start() is a scam, it does nothing
void start() noexcept { }
@@ -60,6 +62,23 @@ public:
Viewport const& svp);
FrameGraphResource msaa(
FrameGraph& fg, FrameGraphResource input,
driver::TextureFormat outFormat) noexcept;
FrameGraphResource toneMapping(
FrameGraph& fg, FrameGraphResource input, driver::TextureFormat outFormat,
bool translucent) noexcept;
FrameGraphResource fxaa(
FrameGraph& fg, FrameGraphResource input, driver::TextureFormat outFormat,
bool translucent) noexcept;
FrameGraphResource dynamicScaling(
FrameGraph& fg, FrameGraphResource input,
driver::TextureFormat outFormat, Viewport const& outViewport) noexcept;
private:
details::FEngine* mEngine = nullptr;

View File

@@ -25,15 +25,18 @@
#include "details/View.h"
#include <filament/Scene.h>
#include <filament/Renderer.h>
#include <filament/driver/PixelBufferDescriptor.h>
#include "fg/FrameGraph.h"
#include "fg/FrameGraphResource.h"
#include <utils/Panic.h>
#include <utils/Systrace.h>
#include <utils/vector.h>
#include <assert.h>
#include <filament/Renderer.h>
using namespace math;
@@ -146,7 +149,6 @@ void FRenderer::render(FView const* view) {
// and wait for all jobs to finish as a safety (this should be a no-op)
js.runAndWait(masterJob);
js.reset();
}
}
@@ -228,37 +230,89 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
* Post Processing...
*/
#define USE_FRAME_GRAPH false
if (UTILS_LIKELY(hasPostProcess)) {
driver.pushGroupMarker("Post Processing");
ppm.start();
assert(colorTarget);
if (USE_FRAME_GRAPH) {
FrameGraph fg;
const bool translucent = mSwapChain->isTransparent();
FrameGraphResource::Descriptor colorDesc{
.width = colorTarget->w,
.height= colorTarget->h,
.format= colorTarget->format,
.samples= colorTarget->samples
};
FrameGraphResource::Descriptor viewRenderTargetDesc{
.width = vp.width,
.height= vp.height
};
FrameGraphResource input = fg.importResource("colorTarget", colorDesc,
colorTarget->target, colorTarget->texture);
FrameGraphResource output = fg.importResource("viewRenderTarget",
viewRenderTargetDesc, viewRenderTarget);
if (useMSAA > 1) {
input = ppm.msaa(fg, input, hdrFormat);
}
input = ppm.toneMapping(fg, input, ldrFormat, translucent);
if (useFXAA) {
input = ppm.fxaa(fg, input, ldrFormat, translucent);
}
if (scaled) {
input = ppm.dynamicScaling(fg, input, ldrFormat, vp);
}
fg.moveResource(output, input);
fg.present(output, FrameGraph::Builder::COLOR);
fg.compile();
//fg.export_graphviz(slog.d);
fg.execute(driver);
rtp.put(colorTarget);
} else {
ppm.start();
if (useMSAA > 1) {
// Note: MSAA, when used is applied before tone-mapping (which is not ideal)
// (tone mapping currently only works without multi-sampling)
// this blit does a MSAA resolve
ppm.blit(hdrFormat);
}
const bool translucent = mSwapChain->isTransparent();
Handle<HwProgram> toneMappingProgram = engine.getPostProcessProgram(
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
: PostProcessStage::TONE_MAPPING_OPAQUE);
ppm.pass(useFXAA ? TextureFormat::RGBA8 : ldrFormat, toneMappingProgram);
if (useFXAA) {
Handle<HwProgram> antiAliasingProgram = engine.getPostProcessProgram(
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
: PostProcessStage::ANTI_ALIASING_OPAQUE);
ppm.pass(ldrFormat, antiAliasingProgram);
}
if (scaled) {
// because it's the last command, the TextureFormat is not relevant
ppm.blit();
}
ppm.finish(view.getDiscardedTargetBuffers(), viewRenderTarget, vp, colorTarget, svp);
if (useMSAA > 1) {
// Note: MSAA, when used is applied before tone-mapping (which is not ideal)
// (tone mapping currently only works without multi-sampling)
// this blit does a MSAA resolve
ppm.blit(hdrFormat);
}
const bool translucent = mSwapChain->isTransparent();
Handle<HwProgram> toneMappingProgram = engine.getPostProcessProgram(
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
: PostProcessStage::TONE_MAPPING_OPAQUE);
ppm.pass(useFXAA ? TextureFormat::RGBA8 : ldrFormat, toneMappingProgram);
if (useFXAA) {
Handle<HwProgram> antiAliasingProgram = engine.getPostProcessProgram(
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
: PostProcessStage::ANTI_ALIASING_OPAQUE);
ppm.pass(ldrFormat, antiAliasingProgram);
}
if (scaled) {
// because it's the last command, the TextureFormat is not relevant
ppm.blit();
}
ppm.finish(view.getDiscardedTargetBuffers(), viewRenderTarget, vp, colorTarget, svp);
driver.popGroupMarker();
}
@@ -384,13 +438,13 @@ void FRenderer::endFrame() {
}
mFrameSkipper.endFrame();
driver.endFrame(mFrameId);
if (mSwapChain) {
mSwapChain->commit(driver);
mSwapChain = nullptr;
}
driver.endFrame(mFrameId);
// Run the component managers' GC in parallel
// WARNING: while doing this we can't access any component manager
auto& js = engine.getJobSystem();

View File

@@ -67,21 +67,26 @@ void FScene::prepare(const math::mat4f& worldOriginTransform) {
// NOTE: we can't know in advance how many entities are renderable or lights because the corresponding
// component can be added after the entity is added to the scene.
// for the purpose of allocation, we'll assume all our entities are renderables
size_t capacity = entities.size();
size_t renderableDataCapacity = entities.size();
// we need the capacity to be multiple of 16 for SIMD loops
capacity = (capacity + 0xF) & ~0xF;
renderableDataCapacity = (renderableDataCapacity + 0xF) & ~0xF;
// we need 1 extra entry at the end for the summed primitive count
capacity = capacity + 1;
renderableDataCapacity = renderableDataCapacity + 1;
sceneData.clear();
if (sceneData.capacity() < capacity) {
sceneData.setCapacity(capacity);
if (sceneData.capacity() < renderableDataCapacity) {
sceneData.setCapacity(renderableDataCapacity);
}
// The light data list will always contain at least one entry for the
// dominating directional light, even if there are no entities.
size_t lightDataCapacity = std::max<size_t>(1, entities.size());
// we need the capacity to be multiple of 16 for SIMD loops
lightDataCapacity = (lightDataCapacity + 0xF) & ~0xF;
lightData.clear();
if (lightData.capacity() < capacity) {
lightData.setCapacity(capacity);
if (lightData.capacity() < lightDataCapacity) {
lightData.setCapacity(lightDataCapacity);
}
// the first entries are reserved for the directional lights (currently only one)
lightData.resize(DIRECTIONAL_LIGHTS_COUNT);

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