Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8a37a537a | ||
|
|
13d3ade5bb | ||
|
|
54d292bc8a | ||
|
|
43ac656a38 | ||
|
|
f8fc2dd808 | ||
|
|
529c44e548 | ||
|
|
637390ea85 | ||
|
|
69db5134a6 | ||
|
|
0102489748 | ||
|
|
3b827da834 | ||
|
|
ce50ea17c0 | ||
|
|
ca79e9d420 | ||
|
|
fb4e498bc1 | ||
|
|
b44717ae54 | ||
|
|
6e4491c852 | ||
|
|
07bb62490b | ||
|
|
b8f72590bb | ||
|
|
39c63146e0 | ||
|
|
960d1321e6 | ||
|
|
8ffba072b2 | ||
|
|
031ff260f7 | ||
|
|
c78db48b81 | ||
|
|
11eaad7992 | ||
|
|
eda6ea64c8 | ||
|
|
79dec2f8b5 | ||
|
|
41397e1b82 | ||
|
|
31a70d2352 | ||
|
|
98ce5e2f5a | ||
|
|
9d8c000bcc | ||
|
|
d238d7f6f2 | ||
|
|
73af2620f9 | ||
|
|
160297db9c | ||
|
|
8628c43fbf | ||
|
|
af9b3a99e0 | ||
|
|
7a2924738c | ||
|
|
06964a787a | ||
|
|
2e8c01d8aa | ||
|
|
b2738a2c8c | ||
|
|
0e4ca0bc7b | ||
|
|
64f2a580da | ||
|
|
f1f9fde3a4 | ||
|
|
c98ac44827 | ||
|
|
3c2a6d5f8c | ||
|
|
d5178f862a | ||
|
|
4de71f7239 | ||
|
|
302d296949 | ||
|
|
1836377753 | ||
|
|
462251bde6 | ||
|
|
a1eedb95a0 | ||
|
|
b14759a0a4 | ||
|
|
f02fe33070 | ||
|
|
1ccf2d6a08 | ||
|
|
d2afc27703 | ||
|
|
801d24b6e7 | ||
|
|
91738d0513 | ||
|
|
2a72e8aee8 | ||
|
|
b0d640832a | ||
|
|
50d8a8a2d8 | ||
|
|
23fe2cba98 | ||
|
|
906097625e | ||
|
|
8d979a7cb8 | ||
|
|
5ef0247569 | ||
|
|
46e3326b81 | ||
|
|
413f6a97b1 | ||
|
|
1597b6f572 | ||
|
|
dc57eb4b7b | ||
|
|
7d81d9bb51 | ||
|
|
4abe017bc5 | ||
|
|
0f6f53d501 | ||
|
|
084fd95489 | ||
|
|
ff53515295 | ||
|
|
bba42ea81f | ||
|
|
66f6031e2c | ||
|
|
f2ba48f4a7 | ||
|
|
955ab2d2f3 | ||
|
|
561726b938 | ||
|
|
7b3475f1da | ||
|
|
923db48614 | ||
|
|
9558f0d6ca | ||
|
|
3297c9bc78 | ||
|
|
6c75c6436e | ||
|
|
28ebc64fd9 | ||
|
|
3c027b9ea0 | ||
|
|
8861b55d3d | ||
|
|
bb72e796bf | ||
|
|
c5fc7a01e8 | ||
|
|
ee1377fcad | ||
|
|
1aa4eff190 | ||
|
|
16d878186c | ||
|
|
bf93468c3f | ||
|
|
71762cf55e | ||
|
|
a6a4055a0a | ||
|
|
8d484dd762 | ||
|
|
6e7c705c92 | ||
|
|
38facc9038 | ||
|
|
c7848efd86 | ||
|
|
13cd77bc9a | ||
|
|
fa9ba2c592 | ||
|
|
4f22eb44e6 | ||
|
|
4b587a1f6d | ||
|
|
583645a943 | ||
|
|
42875b7809 | ||
|
|
54283291d1 | ||
|
|
9263eda90e | ||
|
|
16cef02441 | ||
|
|
d07222fc3c | ||
|
|
0dd8414844 | ||
|
|
7a5ca724fc | ||
|
|
c8a6a4dd62 | ||
|
|
4d90b9d0f0 | ||
|
|
ebe7b2e182 | ||
|
|
08af0f06bc | ||
|
|
cdbfbcc1e4 | ||
|
|
ced19bde17 | ||
|
|
523e1b957f | ||
|
|
2ec6916f63 | ||
|
|
9d78f1a54e | ||
|
|
1ec8fc16a4 | ||
|
|
705c1969b2 | ||
|
|
ace38eff24 | ||
|
|
6d1e0ed6f4 | ||
|
|
c65e561c59 | ||
|
|
552b1c551f | ||
|
|
b1ba798312 | ||
|
|
e40935dae8 | ||
|
|
38a6d047c9 | ||
|
|
b3284edb36 | ||
|
|
2378e64153 | ||
|
|
186920e8d0 | ||
|
|
d8ca867691 | ||
|
|
5e27fdea68 | ||
|
|
c0e63b24c1 | ||
|
|
8a6de4cff1 | ||
|
|
e56ff75e1b | ||
|
|
147dafb4c1 | ||
|
|
5f6f026648 | ||
|
|
fdee8e2e5c | ||
|
|
e9430dd07f | ||
|
|
538243295c | ||
|
|
fa3f34ea4b | ||
|
|
3faef1f9cb | ||
|
|
d0bab0fa8a | ||
|
|
4738e93b83 | ||
|
|
803c922ac1 | ||
|
|
cc637870b6 | ||
|
|
5c57a18b35 | ||
|
|
d538e71959 | ||
|
|
c1c84f6400 | ||
|
|
84eb9547f5 | ||
|
|
9b5060bb1d | ||
|
|
d22e2f2834 | ||
|
|
52ebfb1665 | ||
|
|
07eda48196 | ||
|
|
b2f19a1879 | ||
|
|
39b9d30d1a | ||
|
|
45beccc68b | ||
|
|
45e7580dc6 | ||
|
|
6f9df5bfab | ||
|
|
91ce2f412b | ||
|
|
e60744a6e4 | ||
|
|
de4abe3295 | ||
|
|
b6ccdc0529 |
@@ -16,7 +16,7 @@ option(ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env
|
||||
|
||||
option(USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
|
||||
|
||||
option(GENERATE_WEB_DOCS "Build WebGL documentation and tutorials" OFF)
|
||||
option(GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
|
||||
|
||||
# ==================================================================================================
|
||||
# OS specific
|
||||
@@ -218,8 +218,7 @@ endif()
|
||||
# By default, build with Vulkan support on desktop platforms, although clients must request to use
|
||||
# it at run time. On Android, the build does not include Vulkan support unless CMake is invoked
|
||||
# with -DFILAMENT_SUPPORTS_VULKAN=ON.
|
||||
# Vulkan is not supported on Windows.
|
||||
if (ANDROID OR WIN32 OR WEBGL)
|
||||
if (ANDROID OR WIN32 OR WEBGL OR IOS)
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" OFF)
|
||||
else()
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" ON)
|
||||
@@ -229,7 +228,8 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
endif()
|
||||
|
||||
# Build with Metal support on non-WebGL Apple platforms.
|
||||
if (APPLE AND NOT WEBGL)
|
||||
# Apple's simulator does not support Metal.
|
||||
if (APPLE AND (NOT IOS OR IOS_ARCH STREQUAL "arm64") AND NOT WEBGL)
|
||||
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
|
||||
else()
|
||||
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" OFF)
|
||||
@@ -303,7 +303,9 @@ endif()
|
||||
# ==================================================================================================
|
||||
|
||||
# Sets the following variables: RESGEN_HEADER, RESGEN_SOURCE, RESGEN_FLAGS, RESGEN_SOURCE_FLAGS,
|
||||
# and RESGEN_OUTPUTS
|
||||
# and RESGEN_OUTPUTS. Please pass in an ARCHIVE_NAME that is unique to your project, otherwise the
|
||||
# incbin directive will happily consume a blob from the wrong project without warnings or errors.
|
||||
# Also be sure to include the ASM language in the CMake "project" directive for your project.
|
||||
function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
|
||||
set(OUTPUTS
|
||||
${ARCHIVE_DIR}/${ARCHIVE_NAME}.bin
|
||||
@@ -318,7 +320,7 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
|
||||
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)
|
||||
if (WEBGL OR WIN32 OR ANDROID_ON_WINDOWS)
|
||||
set(RESGEN_OUTPUTS "${OUTPUTS};${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
|
||||
set(RESGEN_FLAGS -cx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
|
||||
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
|
||||
@@ -339,6 +341,8 @@ add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
add_subdirectory(${LIBRARIES}/geometry)
|
||||
add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
@@ -373,7 +377,7 @@ if (WEBGL)
|
||||
add_subdirectory(web/filament-js)
|
||||
add_subdirectory(web/samples)
|
||||
|
||||
if (GENERATE_WEB_DOCS)
|
||||
if (GENERATE_JS_DOCS)
|
||||
add_subdirectory(web/docs)
|
||||
endif()
|
||||
|
||||
@@ -384,6 +388,7 @@ endif()
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
add_subdirectory(${LIBRARIES}/gltfio)
|
||||
add_subdirectory(${LIBRARIES}/imageio)
|
||||
|
||||
add_subdirectory(${FILAMENT}/java/filamat)
|
||||
@@ -391,6 +396,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/cgltf/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
|
||||
@@ -20,7 +20,7 @@ again.
|
||||
Contributor License Agreement (see details above).
|
||||
1. Fork the desired repo, develop and test your code changes.
|
||||
1. Ensure that your code adheres to the existing style in the sample to which
|
||||
you are contributing. Refer to [CodeStyle.md](/CodeStyle.md) for the recommended coding
|
||||
you are contributing. Refer to [CodeStyle.md](/CODE_STYLE.md) for the recommended coding
|
||||
standards for this project.
|
||||
1. Ensure that your code has an appropriate set of unit tests which all pass.
|
||||
1. Submit a pull request.
|
||||
|
||||
@@ -26,11 +26,11 @@ badges above.
|
||||
|
||||
## Documentation
|
||||
|
||||
- [Filament](https://google.github.io/filament/Filament.md.html), an in-depth explanation of
|
||||
- [Filament](https://google.github.io/filament/Filament.html), an in-depth explanation of
|
||||
real-time physically based rendering, the graphics capabilities and implementation of Filament.
|
||||
This document explains the math and reasoning behind most of our decisions. This document is a
|
||||
good introduction to PBR for graphics programmers.
|
||||
- [Materials](https://google.github.io/filament/Materials.md.html), the full reference
|
||||
- [Materials](https://google.github.io/filament/Materials.html), the full reference
|
||||
documentation for our material system. This document explains our different material models, how
|
||||
to use the material compiler `matc` and how to write custom materials.
|
||||
- [Material Properties](https://google.github.io/filament/Material%20Properties.pdf), a reference
|
||||
@@ -62,6 +62,7 @@ Here are a few sample materials rendered with Filament:
|
||||
|
||||
- OpenGL 4.1+ for Linux, macOS and Windows
|
||||
- OpenGL ES 3.0+ for Android and iOS
|
||||
- Metal for macOS and iOS
|
||||
- Vulkan 1.0 for Android, Linux, macOS and iOS (with MoltenVk), and Windows
|
||||
- WebGL 2.0 for all platforms
|
||||
|
||||
@@ -90,7 +91,7 @@ Here are a few sample materials rendered with Filament:
|
||||
|
||||
Many other features have been either prototyped or planned:
|
||||
|
||||
- IES light profiles
|
||||
- IES light profiles/cookies
|
||||
- Area lights
|
||||
- Fog
|
||||
- Color grading
|
||||
@@ -124,7 +125,9 @@ and tools.
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny mesh parsing library (see also `tools/filamesh`)
|
||||
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
|
||||
- `geometry`: Mesh-related utilities
|
||||
- `gltfio`: Loader for glTF 2.0
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `math`: Math library
|
||||
@@ -133,6 +136,7 @@ and tools.
|
||||
- `shaders`: Shaders used by `filamat` and `matc`
|
||||
- `third_party`: External libraries and assets
|
||||
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
|
||||
- `models`: Models under permissive licenses
|
||||
- `textures`: Textures under CC0 license
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
@@ -154,7 +158,7 @@ and tools.
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.4 (or more recent)
|
||||
- CMake 3.10 (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)
|
||||
|
||||
@@ -169,7 +173,7 @@ To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.3
|
||||
- Android SDK
|
||||
- Android NDK
|
||||
- Android NDK 19 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -232,8 +236,8 @@ Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7`
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` on Fedora)
|
||||
- `libc++abi-7-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora)
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora)
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
|
||||
@@ -334,10 +338,9 @@ Install the following components:
|
||||
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
|
||||
- [Clang 6](http://releases.llvm.org/download.html)
|
||||
- [Clang 7](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)
|
||||
- [Cmake 3.13 or later](https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi)
|
||||
|
||||
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)
|
||||
@@ -463,24 +466,6 @@ Run `build.sh -h` for more information.
|
||||
|
||||
#### ARM 64-bit target (arm64-v8a)
|
||||
|
||||
##### Linux toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Linux/aarch64-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Darwin toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Darwin/aarch64-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Compiling
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
@@ -508,24 +493,6 @@ binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||
|
||||
#### ARM 32-bit target (armeabi-v7a)
|
||||
|
||||
##### Linux toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Linux/arm-linux-androideabi-4.9
|
||||
```
|
||||
|
||||
##### Darwin toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Darwin/arm-linux-androideabi-4.9
|
||||
```
|
||||
|
||||
##### Compiling
|
||||
|
||||
Then invoke CMake in a build directory of your choice, inside of filament's directory:
|
||||
|
||||
```
|
||||
@@ -553,24 +520,6 @@ binaries should be found in `out/android-release/filament/lib/armeabi-v7a`.
|
||||
|
||||
#### Intel 64-bit target (x86_64)
|
||||
|
||||
##### Linux toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Linux/x86_64-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Darwin toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Darwin/x86_64-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Compiling
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
@@ -598,24 +547,6 @@ binaries should be found in `out/android-release/filament/lib/x86_64`.
|
||||
|
||||
#### Intel 32-bit target (x86)
|
||||
|
||||
##### Linux toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Linux/i686-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Darwin toolchain
|
||||
|
||||
```
|
||||
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
|
||||
--stl libc++ --force \
|
||||
--install-dir toolchains/Darwin/i686-linux-android-4.9
|
||||
```
|
||||
|
||||
##### Compiling
|
||||
|
||||
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
|
||||
|
||||
```
|
||||
@@ -725,13 +656,13 @@ same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/a77638d.zip > emsdk.zip
|
||||
unzip emsdk.zip
|
||||
mv emsdk-* emsdk
|
||||
cd emsdk
|
||||
./emsdk update
|
||||
./emsdk install sdk-1.38.11-64bit
|
||||
./emsdk activate sdk-1.38.11-64bit
|
||||
./emsdk install sdk-1.38.28-64bit
|
||||
./emsdk activate sdk-1.38.28-64bit
|
||||
```
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
@@ -898,7 +829,8 @@ MoltenVK.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen`, then run the following commands:
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
|
||||
@@ -39,43 +39,6 @@ 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.
|
||||
|
||||
@@ -18,11 +18,23 @@
|
||||
|
||||
#include <filamat/MaterialBuilder.h>
|
||||
|
||||
#include <filament/EngineEnums.h>
|
||||
#include <private/filament/EngineEnums.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace filamat;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInit(JNIEnv *env,
|
||||
jclass type) {
|
||||
MaterialBuilder::init();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShutdown(JNIEnv *env,
|
||||
jclass type) {
|
||||
MaterialBuilder::shutdown();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nCreateMaterialBuilder(JNIEnv *env,
|
||||
jclass type) {
|
||||
@@ -80,7 +92,49 @@ 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);
|
||||
builder->shading((MaterialBuilder::Shading) shading);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpolation(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint interpolation) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->interpolation((MaterialBuilder::Interpolation) interpolation);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jint uniformType, jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSamplerParameter(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jint samplerType, jint format,
|
||||
jint precision, jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->parameter((MaterialBuilder::SamplerType) samplerType,
|
||||
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
|
||||
name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariable(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jint variable, jstring name_) {
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->variable((MaterialBuilder::Variable) variable, name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -106,6 +160,27 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMateria
|
||||
builder->materialVertex(code);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderBlending(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint mode) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->blending((MaterialBuilder::BlendingMode) mode);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVertexDomain(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint vertexDomain) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->vertexDomain((MaterialBuilder::VertexDomain) vertexDomain);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCulling(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint mode) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->culling((MaterialBuilder::CullingMode) mode);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWrite(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean enable) {
|
||||
@@ -113,9 +188,100 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWr
|
||||
builder->colorWrite(enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDepthWrite(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean depthWrite) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->depthWrite(depthWrite);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDepthCulling(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean depthCulling) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->depthCulling(depthCulling);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDoubleSided(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean doubleSided) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->doubleSided(doubleSided);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaskThreshold(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jfloat maskThreshold) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->maskThreshold(maskThreshold);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShadowMultiplier(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean shadowMultiplier) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->shadowMultiplier(shadowMultiplier);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCurvatureToRoughness(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean curvatureToRoughness) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->curvatureToRoughness(curvatureToRoughness);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderLimitOverInterpolation(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean limitOverInterpolation) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->limitOverInterpolation(limitOverInterpolation);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderClearCoatIorChange(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean clearCoatIorChange) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->clearCoatIorChange(clearCoatIorChange);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean flipUV) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->flipUV(flipUV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTransparencyMode(
|
||||
JNIEnv* env, jclass type, jlong nativeBuilder, jint mode) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->transparencyMode((MaterialBuilder::TransparencyMode) mode);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTargetApi(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint targetApi) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->targetApi((MaterialBuilder::TargetApi) targetApi);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderOptimization(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint optimization) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->optimization((MaterialBuilder::Optimization) optimization);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariantFilter(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jbyte variantFilter) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->variantFilter((uint8_t) variantFilter);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,70 @@ public class MaterialBuilder {
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeObject;
|
||||
|
||||
static {
|
||||
System.loadLibrary("filamat-jni");
|
||||
}
|
||||
|
||||
public enum Shading {
|
||||
UNLIT, // no lighting applied, emissive possible
|
||||
LIT, // default, standard lighting
|
||||
SUBSURFACE, // subsurface lighting model
|
||||
CLOTH // cloth lighting model
|
||||
}
|
||||
|
||||
public enum Interpolation {
|
||||
SMOOTH, // default, smooth interpolation
|
||||
FLAT // flat interpolation
|
||||
}
|
||||
|
||||
public enum UniformType {
|
||||
BOOL,
|
||||
BOOL2,
|
||||
BOOL3,
|
||||
BOOL4,
|
||||
FLOAT,
|
||||
FLOAT2,
|
||||
FLOAT3,
|
||||
FLOAT4,
|
||||
INT,
|
||||
INT2,
|
||||
INT3,
|
||||
INT4,
|
||||
UINT,
|
||||
UINT2,
|
||||
UINT3,
|
||||
UINT4,
|
||||
MAT3,
|
||||
MAT4
|
||||
}
|
||||
|
||||
public enum SamplerType {
|
||||
SAMPLER_2D, // 2D texture
|
||||
SAMPLER_CUBEMAP, // Cube map texture
|
||||
SAMPLER_EXTERNAL, // External texture
|
||||
}
|
||||
|
||||
public enum SamplerFormat {
|
||||
INT,
|
||||
UINT,
|
||||
FLOAT,
|
||||
SHADOW
|
||||
}
|
||||
|
||||
public enum SamplerPrecision {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH,
|
||||
DEFAULT
|
||||
}
|
||||
|
||||
public enum Variable {
|
||||
CUSTOM0,
|
||||
CUSTOM1,
|
||||
CUSTOM2,
|
||||
CUSTOM3
|
||||
}
|
||||
|
||||
public enum VertexAttribute {
|
||||
POSITION, // XYZ position (float3)
|
||||
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
|
||||
@@ -36,11 +100,38 @@ public class MaterialBuilder {
|
||||
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 BlendingMode {
|
||||
OPAQUE, // material is opaque
|
||||
TRANSPARENT, // material is transparent and color is alpha-pre-multiplied,
|
||||
// affects diffuse lighting only
|
||||
ADD, // material is additive (e.g.: hologram)
|
||||
MASKED, // material is masked (i.e. alpha tested)
|
||||
FADE // material is transparent and color is alpha-pre-multiplied,
|
||||
// affects specular lighting
|
||||
}
|
||||
|
||||
public enum VertexDomain {
|
||||
OBJECT, // vertices are in object space, default
|
||||
WORLD, // vertices are in world space
|
||||
VIEW, // vertices are in view space
|
||||
DEVICE // vertices are in normalized device space
|
||||
}
|
||||
|
||||
public enum CullingMode {
|
||||
NONE,
|
||||
FRONT,
|
||||
BACK,
|
||||
FRONT_AND_BACK
|
||||
}
|
||||
|
||||
public enum TransparencyMode {
|
||||
DEFAULT, // the transparent object is drawn honoring the raster state
|
||||
TWO_PASSES_ONE_SIDE, // the transparent object is first drawn in the depth buffer,
|
||||
// then in the color buffer, honoring the culling mode, but
|
||||
// ignoring the depth test function
|
||||
TWO_PASSES_TWO_SIDES // the transparent object is drawn twice in the color buffer,
|
||||
// first with back faces only, then with front faces; the culling
|
||||
// mode is ignored. Can be combined with two-sided lighting
|
||||
}
|
||||
|
||||
public enum Platform {
|
||||
@@ -49,6 +140,27 @@ public class MaterialBuilder {
|
||||
ALL
|
||||
}
|
||||
|
||||
public enum TargetApi {
|
||||
ALL,
|
||||
OPENGL,
|
||||
VULKAN,
|
||||
}
|
||||
|
||||
public enum Optimization {
|
||||
NONE,
|
||||
PREPROCESSOR,
|
||||
SIZE,
|
||||
PERFORMANCE
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
nMaterialBuilderInit();
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
nMaterialBuilderShutdown();
|
||||
}
|
||||
|
||||
public MaterialBuilder() {
|
||||
mNativeObject = nCreateMaterialBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeObject);
|
||||
@@ -66,6 +178,38 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder interpolation(@NonNull Interpolation interpolation) {
|
||||
nMaterialBuilderInterpolation(mNativeObject, interpolation.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
|
||||
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
|
||||
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
|
||||
SamplerPrecision precision, String name) {
|
||||
nMaterialBuilderSamplerParameter(
|
||||
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder variable(@NonNull Variable variable, String name) {
|
||||
nMaterialBuilderVariable(mNativeObject, variable.ordinal(), name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder require(@NonNull VertexAttribute attribute) {
|
||||
nMaterialBuilderRequire(mNativeObject, attribute.ordinal());
|
||||
@@ -84,18 +228,114 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder blending(@NonNull BlendingMode mode) {
|
||||
nMaterialBuilderBlending(mNativeObject, mode.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder vertexDomain(@NonNull VertexDomain vertexDomain) {
|
||||
nMaterialBuilderVertexDomain(mNativeObject, vertexDomain.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder culling(@NonNull CullingMode mode) {
|
||||
nMaterialBuilderCulling(mNativeObject, mode.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder colorWrite(boolean enable) {
|
||||
nMaterialBuilderColorWrite(mNativeObject, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder depthWrite(boolean enable) {
|
||||
nMaterialBuilderDepthWrite(mNativeObject, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder depthCulling(boolean enable) {
|
||||
nMaterialBuilderDepthCulling(mNativeObject, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder doubleSided(boolean doubleSided) {
|
||||
nMaterialBuilderDoubleSided(mNativeObject, doubleSided);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder maskThreshold(float threshold) {
|
||||
nMaterialBuilderMaskThreshold(mNativeObject, threshold);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder shadowMultiplier(boolean shadowMultiplier) {
|
||||
nMaterialBuilderShadowMultiplier(mNativeObject, shadowMultiplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder curvatureToRoughness(boolean curvatureToRoughness) {
|
||||
nMaterialBuilderCurvatureToRoughness(mNativeObject, curvatureToRoughness);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder limitOverInterpolation(boolean limitOverInterpolation) {
|
||||
nMaterialBuilderLimitOverInterpolation(mNativeObject, limitOverInterpolation);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder clearCoatIorChange(boolean clearCoatIorChange) {
|
||||
nMaterialBuilderClearCoatIorChange(mNativeObject, clearCoatIorChange);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder flipUV(boolean flipUV) {
|
||||
nMaterialBuilderFlipUV(mNativeObject, flipUV);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder transparencyMode(@NonNull TransparencyMode mode) {
|
||||
nMaterialBuilderTransparencyMode(mNativeObject, mode.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder platform(@NonNull Platform platform) {
|
||||
nMaterialBuilderPlatform(mNativeObject, platform.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder targetApi(@NonNull TargetApi api) {
|
||||
nMaterialBuilderTargetApi(mNativeObject, api.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder optimization(@NonNull Optimization optimization) {
|
||||
nMaterialBuilderOptimization(mNativeObject, optimization.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder variantFilter(byte variantFilter) {
|
||||
nMaterialBuilderVariantFilter(mNativeObject, variantFilter);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialPackage build() {
|
||||
long nativePackage = nBuilderBuild(mNativeObject);
|
||||
@@ -124,6 +364,9 @@ public class MaterialBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nMaterialBuilderInit();
|
||||
private static native void nMaterialBuilderShutdown();
|
||||
|
||||
private static native long nCreateMaterialBuilder();
|
||||
private static native void nDestroyMaterialBuilder(long nativeBuilder);
|
||||
|
||||
@@ -134,9 +377,40 @@ public class MaterialBuilder {
|
||||
|
||||
private static native void nMaterialBuilderName(long nativeBuilder, String name);
|
||||
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
|
||||
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
|
||||
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
|
||||
String name);
|
||||
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
|
||||
int size, String name);
|
||||
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
|
||||
int format, int precision, String name);
|
||||
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,
|
||||
String name);
|
||||
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 nMaterialBuilderBlending(long nativeBuilder, int mode);
|
||||
private static native void nMaterialBuilderVertexDomain(long nativeBuilder, int vertexDomain);
|
||||
private static native void nMaterialBuilderCulling(long nativeBuilder, int mode);
|
||||
private static native void nMaterialBuilderColorWrite(long nativeBuilder, boolean enable);
|
||||
private static native void nMaterialBuilderDepthWrite(long nativeBuilder, boolean enable);
|
||||
private static native void nMaterialBuilderDepthCulling(long nativeBuilder, boolean enable);
|
||||
private static native void nMaterialBuilderDoubleSided(long nativeBuilder, boolean doubleSided);
|
||||
private static native void nMaterialBuilderMaskThreshold(long nativeBuilder, float mode);
|
||||
|
||||
private static native void nMaterialBuilderShadowMultiplier(long mNativeObject,
|
||||
boolean shadowMultiplier);
|
||||
private static native void nMaterialBuilderCurvatureToRoughness(long mNativeObject,
|
||||
boolean curvatureToRoughness);
|
||||
private static native void nMaterialBuilderLimitOverInterpolation(long mNativeObject,
|
||||
boolean limitOverInterpolation);
|
||||
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
||||
boolean clearCoatIorChange);
|
||||
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
|
||||
private static native void nMaterialBuilderTransparencyMode(long nativeBuilder, int mode);
|
||||
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
|
||||
private static native void nMaterialBuilderTargetApi(long nativeBuilder, int api);
|
||||
private static native void nMaterialBuilderOptimization(long nativeBuilder, int optimization);
|
||||
private static native void nMaterialBuilderVariantFilter(long nativeBuilder,
|
||||
byte variantFilter);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ add_library(filaflat STATIC IMPORTED)
|
||||
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
|
||||
|
||||
add_library(geometry STATIC IMPORTED)
|
||||
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
|
||||
|
||||
add_library(filabridge STATIC IMPORTED)
|
||||
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
|
||||
@@ -74,6 +78,7 @@ target_link_libraries(filament-jni
|
||||
filament
|
||||
filaflat
|
||||
filabridge
|
||||
geometry
|
||||
utils
|
||||
log
|
||||
GLESv3
|
||||
|
||||
@@ -91,8 +91,7 @@ Java_com_google_android_filament_IndexBuffer_nSetBuffer(JNIEnv *env, jclass type
|
||||
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
|
||||
indexBuffer->setBuffer(*engine, std::move(desc),
|
||||
(uint32_t) destOffsetInBytes, (uint32_t) sizeInBytes);
|
||||
indexBuffer->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
|
||||
vertexBuffer->setBufferAt(*engine, (uint8_t) bufferIndex, std::move(desc),
|
||||
(uint32_t) destOffsetInBytes, (uint32_t) sizeInBytes);
|
||||
(uint32_t) destOffsetInBytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -122,6 +122,20 @@ Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass,
|
||||
return (jint) view->getAntiAliasing();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDithering(JNIEnv*, jclass,
|
||||
jlong nativeView, jint dithering) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setDithering((View::Dithering) dithering);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_View_nGetDithering(JNIEnv*, jclass,
|
||||
jlong nativeView) {
|
||||
View* view = (View*) nativeView;
|
||||
return (jint)view->getDithering();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*,
|
||||
jclass, jlong nativeView, jboolean enabled, jboolean homogeneousScaling,
|
||||
|
||||
@@ -60,6 +60,11 @@ public class View {
|
||||
FXAA
|
||||
}
|
||||
|
||||
public enum Dithering {
|
||||
NONE,
|
||||
TEMPORAL
|
||||
}
|
||||
|
||||
public enum DepthPrepass {
|
||||
DEFAULT(-1),
|
||||
DISABLED(0),
|
||||
@@ -160,6 +165,15 @@ public class View {
|
||||
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
|
||||
}
|
||||
|
||||
public void setDithering(@NonNull Dithering dithering) {
|
||||
nSetDithering(getNativeObject(), dithering.ordinal());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Dithering getDithering() {
|
||||
return Dithering.values()[nGetDithering(getNativeObject())];
|
||||
}
|
||||
|
||||
public void setDynamicResolutionOptions(@NonNull DynamicResolutionOptions options) {
|
||||
mDynamicResolution = options;
|
||||
nSetDynamicResolutionOptions(getNativeObject(),
|
||||
@@ -257,6 +271,8 @@ public class View {
|
||||
private static native int nGetSampleCount(long nativeView);
|
||||
private static native void nSetAntiAliasing(long nativeView, int type);
|
||||
private static native int nGetAntiAliasing(long nativeView);
|
||||
private static native void nSetDithering(long nativeView, int dithering);
|
||||
private static native int nGetDithering(long nativeView);
|
||||
private static native void nSetDynamicResolutionOptions(long nativeView,
|
||||
boolean enabled, boolean homogeneousScaling,
|
||||
float targetFrameTimeMilli, float headRoomRatio, float scaleRate,
|
||||
|
||||
@@ -381,6 +381,9 @@ public class UiHelper {
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
callback.surfaceCreated(holder);
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
callback.surfaceChanged(holder, format,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,16 @@ Demonstrates how to render into a `TextureView` instead of a `SurfaceView`:
|
||||
|
||||

|
||||
|
||||
### `material-builder`
|
||||
|
||||
Demonstrates how to programatically generate Filament materials, as opposed to compiling them on the
|
||||
host machine:
|
||||
|
||||

|
||||
|
||||
The `material-builder` sample requires the `filamat` static library which can be compiled by adding
|
||||
the `-l` flag to the `./build.sh` command.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
|
||||
|
||||
@@ -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/envs
|
||||
.externalNativeBuild
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,92 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
apply from: '../../../build/filament-tasks.gradle'
|
||||
|
||||
compileMesh {
|
||||
group 'Filament'
|
||||
description 'Compile mesh'
|
||||
|
||||
inputFile = file("../../../../third_party/shader_ball/shader_ball.obj")
|
||||
outputDir = file("src/main/assets/models")
|
||||
}
|
||||
|
||||
generateIbl {
|
||||
group 'Filament'
|
||||
description 'Generate IBL'
|
||||
|
||||
inputFile = file("../../../../third_party/environments/flower_road_2k.hdr")
|
||||
outputDir = file("src/main/assets/envs")
|
||||
}
|
||||
|
||||
preBuild.dependsOn compileMesh
|
||||
preBuild.dependsOn generateIbl
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.ibl"
|
||||
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'
|
||||
|
||||
// Depend on Filamat
|
||||
implementation 'com.google.android.filament:filamat-android'
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.ibl">
|
||||
|
||||
<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>
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.ibl
|
||||
|
||||
import android.content.res.AssetManager
|
||||
import android.graphics.BitmapFactory
|
||||
|
||||
import com.google.android.filament.Engine
|
||||
import com.google.android.filament.IndirectLight
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.Texture
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
import kotlin.math.log2
|
||||
|
||||
data class Ibl(val indirectLight: IndirectLight,
|
||||
val indirectLightTexture: Texture,
|
||||
val skybox: Skybox,
|
||||
val skyboxTexture: Texture)
|
||||
|
||||
fun loadIbl(assets: AssetManager, name: String, engine: Engine): Ibl {
|
||||
val (ibl, iblTexture) = loadIndirectLight(assets, name, engine)
|
||||
val (skybox, skyboxTexture) = loadSkybox(assets, name, engine)
|
||||
return Ibl(ibl, iblTexture, skybox, skyboxTexture)
|
||||
}
|
||||
|
||||
fun destroyIbl(engine: Engine, ibl: Ibl) {
|
||||
engine.destroySkybox(ibl.skybox)
|
||||
engine.destroyTexture(ibl.skyboxTexture)
|
||||
engine.destroyIndirectLight(ibl.indirectLight)
|
||||
engine.destroyTexture(ibl.indirectLightTexture)
|
||||
}
|
||||
|
||||
private fun peekSize(assets: AssetManager, name: String): Pair<Int, Int> {
|
||||
assets.open(name).use { input ->
|
||||
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
BitmapFactory.decodeStream(input, null, opts)
|
||||
return opts.outWidth to opts.outHeight
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadIndirectLight(
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine): Pair<IndirectLight, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(log2(w.toFloat()).toInt() + 1)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
repeat(texture.levels) {
|
||||
loadCubemap(texture, assets, name, engine, "m${it}_", it)
|
||||
}
|
||||
|
||||
val sphericalHarmonics = loadSphericalHarmonics(assets, name)
|
||||
|
||||
return IndirectLight.Builder()
|
||||
.reflections(texture)
|
||||
.irradiance(3, sphericalHarmonics)
|
||||
.intensity(30_000.0f)
|
||||
.build(engine) to texture
|
||||
}
|
||||
|
||||
private fun loadSphericalHarmonics(assets: AssetManager, name: String): FloatArray {
|
||||
val re = Regex("""\(\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+)\);""")
|
||||
// 3 bands = 9 RGB coefficients, so 9 * 3 floats
|
||||
val sphericalHarmonics = FloatArray(9 * 3)
|
||||
BufferedReader(InputStreamReader(assets.open("$name/sh.txt"))).use { input ->
|
||||
repeat(9) { i ->
|
||||
val line = input.readLine()
|
||||
re.find(line)?.let {
|
||||
sphericalHarmonics[i * 3] = it.groups[1]?.value?.toFloat() ?: 0.0f
|
||||
sphericalHarmonics[i * 3 + 1] = it.groups[2]?.value?.toFloat() ?: 0.0f
|
||||
sphericalHarmonics[i * 3 + 2] = it.groups[3]?.value?.toFloat() ?: 0.0f
|
||||
}
|
||||
}
|
||||
}
|
||||
return sphericalHarmonics
|
||||
}
|
||||
|
||||
private fun loadSkybox(assets: AssetManager, name: String, engine: Engine): Pair<Skybox, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(1)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
loadCubemap(texture, assets, name, engine)
|
||||
|
||||
return Skybox.Builder().environment(texture).build(engine) to texture
|
||||
}
|
||||
|
||||
private fun loadCubemap(texture: Texture,
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine,
|
||||
prefix: String = "",
|
||||
level: Int = 0) {
|
||||
// This is important, in the RGBM format the alpha channel does not encode
|
||||
// opacity but a scale factor (to represent HDR data). We must tell Android
|
||||
// to not premultiply the RGB channels by the alpha channel
|
||||
val opts = BitmapFactory.Options().apply { inPremultiplied = false }
|
||||
|
||||
// RGBM is always 4 bytes per pixel
|
||||
val faceSize = texture.getWidth(level) * texture.getHeight(level) * 4
|
||||
val offsets = IntArray(6) { it * faceSize }
|
||||
// Allocate enough memory for all the cubemap faces
|
||||
val storage = ByteBuffer.allocateDirect(faceSize * 6)
|
||||
|
||||
arrayOf("px", "nx", "py", "ny", "pz", "nz").forEach { suffix ->
|
||||
assets.open("$name/$prefix$suffix.rgbm").use {
|
||||
val bitmap = BitmapFactory.decodeStream(it, null, opts)
|
||||
bitmap?.copyPixelsToBuffer(storage)
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.ibl
|
||||
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
|
||||
fun readIntLE(input: InputStream): Int {
|
||||
return input.read() and 0xff or (
|
||||
input.read() and 0xff shl 8) or (
|
||||
input.read() and 0xff shl 16) or (
|
||||
input.read() and 0xff shl 24)
|
||||
}
|
||||
|
||||
fun readFloat32LE(input: InputStream): Float {
|
||||
val bytes = ByteArray(4)
|
||||
input.read(bytes, 0, 4)
|
||||
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).float
|
||||
}
|
||||
|
||||
fun readUIntLE(input: InputStream): Long {
|
||||
return readIntLE(input).toLong() and 0xFFFFFFFFL
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* 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.ibl
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.Choreographer
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceView
|
||||
import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import com.google.android.filament.filamat.MaterialBuilder
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
class MainActivity : Activity() {
|
||||
// Make sure to initialize Filament first
|
||||
// This loads the JNI library needed by most API calls
|
||||
companion object {
|
||||
init {
|
||||
Filament.init()
|
||||
}
|
||||
}
|
||||
|
||||
// The View we want to render into
|
||||
private lateinit var surfaceView: SurfaceView
|
||||
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
|
||||
private lateinit var uiHelper: UiHelper
|
||||
// Choreographer is used to schedule new frames
|
||||
private lateinit var choreographer: Choreographer
|
||||
|
||||
// Engine creates and destroys Filament resources
|
||||
// Each engine must be accessed from a single thread of your choosing
|
||||
// Resources cannot be shared across engines
|
||||
private lateinit var engine: Engine
|
||||
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
|
||||
private lateinit var renderer: Renderer
|
||||
// A scene holds all the renderable, lights, etc. to be drawn
|
||||
private lateinit var scene: Scene
|
||||
// A view defines a viewport, a scene and a camera for rendering
|
||||
private lateinit var view: View
|
||||
// Should be pretty obvious :)
|
||||
private lateinit var camera: Camera
|
||||
|
||||
private lateinit var material: Material
|
||||
private lateinit var materialInstance: MaterialInstance
|
||||
|
||||
private lateinit var mesh: Mesh
|
||||
private lateinit var ibl: Ibl
|
||||
|
||||
// Filament entity representing a renderable object
|
||||
@Entity private var light = 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, (2.0 * PI).toFloat())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
surfaceView = SurfaceView(this)
|
||||
setContentView(surfaceView)
|
||||
|
||||
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(surfaceView)
|
||||
}
|
||||
|
||||
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() {
|
||||
buildMaterial()
|
||||
setupMaterial()
|
||||
loadImageBasedLight()
|
||||
|
||||
scene.skybox = ibl.skybox
|
||||
scene.indirectLight = ibl.indirectLight
|
||||
|
||||
// This map can contain named materials that will map to the material names
|
||||
// loaded from the filamesh file. The material called "DefaultMaterial" is
|
||||
// applied when no named material can be found
|
||||
val materials = mapOf("DefaultMaterial" to materialInstance)
|
||||
|
||||
// Load the mesh in the filamesh format (see filamesh tool)
|
||||
mesh = loadMesh(assets, "models/shader_ball.filamesh", materials, engine)
|
||||
|
||||
// Move the mesh down
|
||||
// Filament uses column-major matrices
|
||||
engine.transformManager.setTransform(engine.transformManager.getInstance(mesh.renderable),
|
||||
floatArrayOf(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, -1.2f, 0.0f, 1.0f
|
||||
))
|
||||
|
||||
// Add the entity to the scene to render it
|
||||
scene.addEntity(mesh.renderable)
|
||||
|
||||
// We now need a light, let's create a directional light
|
||||
light = EntityManager.get().create()
|
||||
|
||||
// Create a color from a temperature (D65)
|
||||
val (r, g, b) = Colors.cct(6_500.0f)
|
||||
LightManager.Builder(LightManager.Type.DIRECTIONAL)
|
||||
.color(r, g, b)
|
||||
// Intensity of the sun in lux on a clear day
|
||||
.intensity(110_000.0f)
|
||||
// The direction is normalized on our behalf
|
||||
.direction(-0.753f, -1.0f, 0.890f)
|
||||
.castShadows(true)
|
||||
.build(engine, light)
|
||||
|
||||
// Add the entity to the scene to light it
|
||||
scene.addEntity(light)
|
||||
|
||||
// Set the exposure on the camera, this exposure follows the sunny f/16 rule
|
||||
// Since we've defined a light that has the same intensity as the sun, it
|
||||
// guarantees a proper exposure
|
||||
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
|
||||
|
||||
startAnimation()
|
||||
}
|
||||
|
||||
private fun buildMaterial() {
|
||||
// MaterialBuilder.init() must be called before any MaterialBuilder methods can be used.
|
||||
// It only needs to be called once per process.
|
||||
// When your app is done building materials, call MaterialBuilder.shutdown() to free
|
||||
// internal MaterialBuilder resources.
|
||||
MaterialBuilder.init()
|
||||
|
||||
val matPackage = MaterialBuilder()
|
||||
// By default, materials are generated only for DESKTOP. Since we're an Android
|
||||
// app, we set the platform to MOBILE.
|
||||
.platform(MaterialBuilder.Platform.MOBILE)
|
||||
|
||||
// Set the name of the Material for debugging purposes.
|
||||
.name("Clear coat")
|
||||
|
||||
// Defaults to LIT. We could change the shading model here if we desired.
|
||||
.shading(MaterialBuilder.Shading.LIT)
|
||||
|
||||
// Add a parameter to the material that can be set via the setParameter method once
|
||||
// we have a material instance.
|
||||
.uniformParameter(MaterialBuilder.UniformType.FLOAT3, "baseColor")
|
||||
|
||||
// Fragment block- see the material readme (docs/Materials.md.html) for the full
|
||||
// specification.
|
||||
.material("void material(inout MaterialInputs material) {\n" +
|
||||
" prepareMaterial(material);\n" +
|
||||
" material.baseColor.rgb = materialParams.baseColor;\n" +
|
||||
" material.roughness = 0.65;\n" +
|
||||
" material.metallic = 1.0;\n" +
|
||||
" material.clearCoat = 1.0;\n" +
|
||||
"}\n")
|
||||
|
||||
.build()
|
||||
|
||||
if (matPackage.isValid) {
|
||||
val buffer = matPackage.buffer
|
||||
material = Material.Builder().payload(buffer, buffer.remaining()).build(engine)
|
||||
}
|
||||
|
||||
// We're done building materials, so we call shutdown here to free resources. If we wanted
|
||||
// to build more materials, we could call MaterialBuilder.init() again (with a slight
|
||||
// performance hit).
|
||||
MaterialBuilder.shutdown()
|
||||
}
|
||||
|
||||
private fun setupMaterial() {
|
||||
// Create an instance of the material to set different parameters on it
|
||||
materialInstance = material.createInstance()
|
||||
// Specify that our color is in sRGB so the conversion to linear
|
||||
// is done automatically for us. If you already have a linear color
|
||||
// you can pass it directly, or use Colors.RgbType.LINEAR
|
||||
materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 0.71f, 0.0f, 0.0f)
|
||||
}
|
||||
|
||||
private fun loadImageBasedLight() {
|
||||
ibl = loadIbl(assets, "envs/flower_road_2k", engine)
|
||||
ibl.indirectLight.intensity = 40_000.0f
|
||||
}
|
||||
|
||||
private fun startAnimation() {
|
||||
// Animate the triangle
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.duration = 18_000
|
||||
animator.repeatMode = ValueAnimator.RESTART
|
||||
animator.repeatCount = ValueAnimator.INFINITE
|
||||
animator.addUpdateListener { a ->
|
||||
val v = (a.animatedValue as Float)
|
||||
camera.lookAt(cos(v) * 4.5, 1.5, sin(v) * 4.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
|
||||
}
|
||||
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
|
||||
destroyMesh(engine, mesh)
|
||||
destroyIbl(engine, ibl)
|
||||
engine.destroyEntity(light)
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyMaterialInstance(materialInstance)
|
||||
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(light)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
engine.destroy()
|
||||
}
|
||||
|
||||
inner class FrameCallback : Choreographer.FrameCallback {
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
// 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)
|
||||
}
|
||||
|
||||
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 aspect = width.toDouble() / height.toDouble()
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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.ibl
|
||||
|
||||
import android.content.res.AssetManager
|
||||
import android.util.Log
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.VertexBuffer.AttributeType.*
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute.*
|
||||
|
||||
import java.io.InputStream
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.nio.channels.Channels
|
||||
import java.nio.channels.ReadableByteChannel
|
||||
|
||||
data class Mesh(
|
||||
@Entity val renderable: Int,
|
||||
val indexBuffer: IndexBuffer,
|
||||
val vertexBuffer: VertexBuffer,
|
||||
val aabb: Box)
|
||||
|
||||
fun destroyMesh(engine: Engine, mesh: Mesh) {
|
||||
engine.destroyEntity(mesh.renderable)
|
||||
engine.destroyIndexBuffer(mesh.indexBuffer)
|
||||
engine.destroyVertexBuffer(mesh.vertexBuffer)
|
||||
EntityManager.get().destroy(mesh.renderable)
|
||||
}
|
||||
|
||||
fun loadMesh(assets: AssetManager, name: String,
|
||||
materials: Map<String, MaterialInstance>, engine: Engine): Mesh {
|
||||
// See tools/filamesh/README.md for a description of the filamesh file format
|
||||
assets.open(name).use { input ->
|
||||
val header = readHeader(input)
|
||||
|
||||
val channel = Channels.newChannel(input)
|
||||
val vertexBufferData = readSizedData(channel, header.verticesSizeInBytes)
|
||||
val indexBufferData = readSizedData(channel, header.indicesSizeInBytes)
|
||||
|
||||
val parts = readParts(header, input)
|
||||
val definedMaterials = readMaterials(input)
|
||||
|
||||
val indexBuffer = createIndexBuffer(engine, header, indexBufferData)
|
||||
val vertexBuffer = createVertexBuffer(engine, header, vertexBufferData)
|
||||
|
||||
val renderable = createRenderable(
|
||||
engine, header, indexBuffer, vertexBuffer, parts, definedMaterials, materials)
|
||||
|
||||
return Mesh(renderable, indexBuffer, vertexBuffer, header.aabb)
|
||||
}
|
||||
}
|
||||
|
||||
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 flags = 0L
|
||||
var posOffset = 0L
|
||||
var positionStride = 0L
|
||||
var tangentOffset = 0L
|
||||
var tangentStride = 0L
|
||||
var colorOffset = 0L
|
||||
var colorStride = 0L
|
||||
var uv0Offset = 0L
|
||||
var uv0Stride = 0L
|
||||
var uv1Offset = 0L
|
||||
var uv1Stride = 0L
|
||||
var totalVertices = 0L
|
||||
var verticesSizeInBytes = 0L
|
||||
var indices16Bit = 0L
|
||||
var totalIndices = 0L
|
||||
var indicesSizeInBytes = 0L
|
||||
}
|
||||
|
||||
private class Part {
|
||||
var offset = 0L
|
||||
var indexCount = 0L
|
||||
var minIndex = 0L
|
||||
var maxIndex = 0L
|
||||
var materialID = 0L
|
||||
var aabb = Box()
|
||||
}
|
||||
|
||||
private fun readMagicNumber(input: InputStream): Boolean {
|
||||
val temp = ByteArray(FILAMESH_FILE_IDENTIFIER.length)
|
||||
input.read(temp)
|
||||
val tempS = String(temp, Charset.forName("UTF-8"))
|
||||
return tempS == FILAMESH_FILE_IDENTIFIER
|
||||
}
|
||||
|
||||
private fun readHeader(input: InputStream): Header {
|
||||
val header = Header()
|
||||
|
||||
if (!readMagicNumber(input)) {
|
||||
Log.e("Filament", "Invalid filamesh file.")
|
||||
return header
|
||||
}
|
||||
|
||||
header.versionNumber = readUIntLE(input)
|
||||
header.parts = readUIntLE(input)
|
||||
header.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
header.flags = readUIntLE(input)
|
||||
header.posOffset = readUIntLE(input)
|
||||
header.positionStride = readUIntLE(input)
|
||||
header.tangentOffset = readUIntLE(input)
|
||||
header.tangentStride = readUIntLE(input)
|
||||
header.colorOffset = readUIntLE(input)
|
||||
header.colorStride = readUIntLE(input)
|
||||
header.uv0Offset = readUIntLE(input)
|
||||
header.uv0Stride = readUIntLE(input)
|
||||
header.uv1Offset = readUIntLE(input)
|
||||
header.uv1Stride = readUIntLE(input)
|
||||
header.totalVertices = readUIntLE(input)
|
||||
header.verticesSizeInBytes = readUIntLE(input)
|
||||
header.indices16Bit = readUIntLE(input)
|
||||
header.totalIndices = readUIntLE(input)
|
||||
header.indicesSizeInBytes = readUIntLE(input)
|
||||
|
||||
header.valid = true
|
||||
return header
|
||||
}
|
||||
|
||||
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
|
||||
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
channel.read(buffer)
|
||||
buffer.flip()
|
||||
return buffer
|
||||
}
|
||||
|
||||
private fun readParts(header: Header, input: InputStream): List<Part> {
|
||||
return List(header.parts.toInt()) {
|
||||
val p = Part()
|
||||
p.offset = readUIntLE(input)
|
||||
p.indexCount = readUIntLE(input)
|
||||
p.minIndex = readUIntLE(input)
|
||||
p.maxIndex = readUIntLE(input)
|
||||
p.materialID = readUIntLE(input)
|
||||
p.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
private fun readMaterials(input: InputStream): List<String> {
|
||||
return List(readUIntLE(input).toInt()) {
|
||||
val data = ByteArray(readUIntLE(input).toInt())
|
||||
input.read(data)
|
||||
// Skip null terminator
|
||||
input.skip(1)
|
||||
data.toString(Charset.forName("UTF-8"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer): IndexBuffer {
|
||||
val indexType = if (header.indices16Bit != 0L) {
|
||||
IndexBuffer.Builder.IndexType.USHORT
|
||||
} else {
|
||||
IndexBuffer.Builder.IndexType.UINT
|
||||
}
|
||||
|
||||
return IndexBuffer.Builder()
|
||||
.bufferType(indexType)
|
||||
.indexCount(header.totalIndices.toInt())
|
||||
.build(engine)
|
||||
.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())
|
||||
// We store colors as unsigned bytes (0..255) but the shader wants values in the 0..1
|
||||
// range so we must mark this attribute normalized
|
||||
.normalized(COLOR)
|
||||
// The same goes for the tangent frame: we store it as a signed short, but we want
|
||||
// values in 0..1 in the shader
|
||||
.normalized(TANGENTS)
|
||||
.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 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, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
.normalized(UV1, uvNormalized(header))
|
||||
}
|
||||
|
||||
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
|
||||
}
|
||||
|
||||
private fun createRenderable(
|
||||
engine: Engine,
|
||||
header: Header,
|
||||
indexBuffer: IndexBuffer,
|
||||
vertexBuffer: VertexBuffer,
|
||||
parts: List<Part>,
|
||||
definedMaterials: List<String>,
|
||||
materials: Map<String, MaterialInstance>): Int {
|
||||
|
||||
val builder = RenderableManager.Builder(header.parts.toInt()).boundingBox(header.aabb)
|
||||
|
||||
repeat(header.parts.toInt()) { i ->
|
||||
builder.geometry(i,
|
||||
RenderableManager.PrimitiveType.TRIANGLES,
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
parts[i].offset.toInt(),
|
||||
parts[i].minIndex.toInt(),
|
||||
parts[i].maxIndex.toInt(),
|
||||
parts[i].indexCount.toInt())
|
||||
|
||||
// Find a material in the supplied material map, otherwise we fall back to
|
||||
// the default material named "DefaultMaterial"
|
||||
val material = materials[definedMaterials[parts[i].materialID.toInt()]]
|
||||
material?.let {
|
||||
builder.material(i, material)
|
||||
} ?: builder.material(i, materials["DefaultMaterial"]!!)
|
||||
}
|
||||
|
||||
return EntityManager.get().create().apply { builder.build(engine, this) }
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Clear coat material with a single parameter:
|
||||
// - baseColor
|
||||
|
||||
material {
|
||||
name : clear_coat,
|
||||
shadingModel : lit,
|
||||
parameters : [
|
||||
{
|
||||
type : float3,
|
||||
name : baseColor
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
|
||||
material.baseColor.rgb = materialParams.baseColor;
|
||||
|
||||
// To create a metallic paint-like material we want
|
||||
// a rough base metallic layer and a glossy clear coat
|
||||
material.roughness = 0.65;
|
||||
material.metallic = 1.0;
|
||||
material.clearCoat = 1.0;
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Image-Based Lighting</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
#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.10.1-all.zip
|
||||
@@ -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" "$@"
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
includeBuild '../../filament-android'
|
||||
includeBuild '../../filamat-android'
|
||||
|
||||
include ':app'
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# NDK API level
|
||||
API_LEVEL=21
|
||||
# Host tools required by Android, WebGL, and iOS builds
|
||||
MOBILE_HOST_TOOLS="matc resgen cmgen"
|
||||
WEB_HOST_TOOLS="${MOBILE_HOST_TOOLS} mipgen filamesh"
|
||||
@@ -31,10 +29,8 @@ function print_help {
|
||||
echo " -p platform1,platform2,..."
|
||||
echo " Where platformN is [desktop|android|ios|webgl|all]."
|
||||
echo " Platform(s) to build, defaults to desktop."
|
||||
echo " Building for Android or iOS will automatically generate / download"
|
||||
echo " Building for iOS will automatically generate / download"
|
||||
echo " the toolchains if needed and perform a partial desktop build."
|
||||
echo " -t"
|
||||
echo " Generate the Android toolchain, requires \$ANDROID_HOME to be set."
|
||||
echo " -u"
|
||||
echo " Run all unit tests, will trigger a debug build if needed."
|
||||
echo " -v"
|
||||
@@ -43,6 +39,8 @@ function print_help {
|
||||
echo " Add iOS simulator support to the iOS build."
|
||||
echo " -l"
|
||||
echo " Add filamat support to the Android build."
|
||||
echo " -w"
|
||||
echo " Build Web documents (compiles .md.html files to .html)."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -74,6 +72,10 @@ function print_help {
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Requirements
|
||||
CMAKE_MAJOR=3
|
||||
CMAKE_MINOR=10
|
||||
|
||||
# Internal variables
|
||||
TARGET=release
|
||||
|
||||
@@ -92,16 +94,16 @@ ISSUE_ARCHIVES=false
|
||||
|
||||
ISSUE_CMAKE_ALWAYS=false
|
||||
|
||||
ISSUE_WEB_DOCS=false
|
||||
|
||||
RUN_TESTS=false
|
||||
|
||||
WEB_DOCS_OPTION="-DGENERATE_WEB_DOCS=OFF"
|
||||
JS_DOCS_OPTION="-DGENERATE_JS_DOCS=OFF"
|
||||
|
||||
ENABLE_JAVA=ON
|
||||
|
||||
INSTALL_COMMAND=
|
||||
|
||||
GENERATE_TOOLCHAINS=false
|
||||
|
||||
VULKAN_ANDROID_OPTION="-DFILAMENT_SUPPORTS_VULKAN=OFF"
|
||||
|
||||
BUILD_FILAMAT_ANDROID=false
|
||||
@@ -116,8 +118,6 @@ BUILD_CUSTOM_TARGETS=
|
||||
UNAME=`echo $(uname)`
|
||||
LC_UNAME=`echo ${UNAME} | tr '[:upper:]' '[:lower:]'`
|
||||
|
||||
TOOLCHAIN_SCRIPT=${ANDROID_HOME}/ndk-bundle/build/tools/make_standalone_toolchain.py
|
||||
|
||||
# Functions
|
||||
|
||||
function build_clean {
|
||||
@@ -127,48 +127,11 @@ function build_clean {
|
||||
rm -Rf android/filament-android/.externalNativeBuild
|
||||
}
|
||||
|
||||
function generate_toolchain {
|
||||
local ARCH=$1
|
||||
local ARCH_NAME=$2
|
||||
local TOOLCHAIN_NAME=toolchains/${UNAME}/${ARCH_NAME}-4.9
|
||||
|
||||
if [ -z "$ANDROID_HOME" ]; then
|
||||
echo "The environment variable \$ANDROID_HOME is not set." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$TOOLCHAIN_SCRIPT" ]; then
|
||||
echo "The NDK is not properly installed in $ANDROID_HOME." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$TOOLCHAIN_NAME" ]; then
|
||||
echo "Removing existing $ARCH toolchain..."
|
||||
rm -Rf ${TOOLCHAIN_NAME}
|
||||
fi
|
||||
|
||||
echo "Generating $ARCH toolchain..."
|
||||
|
||||
${TOOLCHAIN_SCRIPT} \
|
||||
--arch ${ARCH} \
|
||||
--api ${API_LEVEL} \
|
||||
--stl libc++ \
|
||||
--force \
|
||||
--install-dir ${TOOLCHAIN_NAME}
|
||||
}
|
||||
|
||||
function generate_toolchains {
|
||||
generate_toolchain "arm64" "aarch64-linux-android"
|
||||
generate_toolchain "arm" "arm-linux-androideabi"
|
||||
generate_toolchain "x86_64" "x86_64-linux-android"
|
||||
generate_toolchain "x86" "i686-linux-android"
|
||||
}
|
||||
|
||||
function build_desktop_target {
|
||||
local LC_TARGET=`echo $1 | tr '[:upper:]' '[:lower:]'`
|
||||
local BUILD_TARGETS=$2
|
||||
|
||||
if [ ! "$BUILD_TARGETS" ]; then
|
||||
if [[ ! "$BUILD_TARGETS" ]]; then
|
||||
BUILD_TARGETS=${BUILD_CUSTOM_TARGETS}
|
||||
fi
|
||||
|
||||
@@ -177,7 +140,7 @@ function build_desktop_target {
|
||||
|
||||
cd out/cmake-${LC_TARGET}
|
||||
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
|
||||
cmake \
|
||||
-G "$BUILD_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE=$1 \
|
||||
@@ -188,13 +151,13 @@ function build_desktop_target {
|
||||
fi
|
||||
${BUILD_COMMAND} ${BUILD_TARGETS}
|
||||
|
||||
if [ "$INSTALL_COMMAND" ]; then
|
||||
if [[ "$INSTALL_COMMAND" ]]; then
|
||||
echo "Installing ${LC_TARGET} in out/${LC_TARGET}/filament..."
|
||||
${BUILD_COMMAND} ${INSTALL_COMMAND}
|
||||
fi
|
||||
|
||||
if [ -d "../${LC_TARGET}/filament" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
if [[ -d "../${LC_TARGET}/filament" ]]; then
|
||||
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
|
||||
echo "Generating out/filament-${LC_TARGET}-${LC_UNAME}.tgz..."
|
||||
cd ../${LC_TARGET}
|
||||
tar -czvf ../filament-${LC_TARGET}-${LC_UNAME}.tgz filament
|
||||
@@ -205,11 +168,11 @@ function build_desktop_target {
|
||||
}
|
||||
|
||||
function build_desktop {
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
build_desktop_target "Debug" "$1"
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
build_desktop_target "Release" "$1"
|
||||
fi
|
||||
}
|
||||
@@ -219,11 +182,11 @@ function build_webgl_with_target {
|
||||
echo "Building WebGL $LC_TARGET..."
|
||||
mkdir -p out/cmake-webgl-${LC_TARGET}
|
||||
cd out/cmake-webgl-${LC_TARGET}
|
||||
if [ ! "$BUILD_TARGETS" ]; then
|
||||
if [[ ! "$BUILD_TARGETS" ]]; then
|
||||
BUILD_TARGETS=${BUILD_CUSTOM_TARGETS}
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
fi
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
|
||||
# Apply the emscripten environment within a subshell.
|
||||
(
|
||||
source ${EMSDK}/emsdk_env.sh
|
||||
@@ -233,17 +196,17 @@ function build_webgl_with_target {
|
||||
-DCMAKE_BUILD_TYPE=$1 \
|
||||
-DCMAKE_INSTALL_PREFIX=../webgl-${LC_TARGET}/filament \
|
||||
-DWEBGL=1 \
|
||||
$WEB_DOCS_OPTION \
|
||||
${JS_DOCS_OPTION} \
|
||||
../..
|
||||
${BUILD_COMMAND} ${BUILD_TARGETS}
|
||||
)
|
||||
fi
|
||||
|
||||
if [ -d "web/filament-js" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
if [[ -d "web/filament-js" ]]; then
|
||||
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
|
||||
|
||||
which -s python3
|
||||
if [ $? == 0 ]; then
|
||||
if [[ $? == 0 ]]; then
|
||||
echo "Generating JavaScript documentation..."
|
||||
local DOCS_FOLDER="web/docs"
|
||||
local DOCS_SCRIPT="../../web/docs/build.py"
|
||||
@@ -281,11 +244,11 @@ function build_webgl {
|
||||
ISSUE_DEBUG_BUILD=${OLD_ISSUE_DEBUG_BUILD}
|
||||
ISSUE_RELEASE_BUILD=${OLD_ISSUE_RELEASE_BUILD}
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
build_webgl_with_target "Debug"
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
build_webgl_with_target "Release"
|
||||
fi
|
||||
}
|
||||
@@ -299,14 +262,14 @@ function build_android_target {
|
||||
|
||||
cd out/cmake-android-${LC_TARGET}-${ARCH}
|
||||
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
|
||||
cmake \
|
||||
-G "$BUILD_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE=$1 \
|
||||
-DCMAKE_INSTALL_PREFIX=../android-${LC_TARGET}/filament \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-${ARCH}-linux-android.cmake \
|
||||
$VULKAN_ANDROID_OPTION \
|
||||
$FILAMAT_ANDROID_OPTION \
|
||||
${VULKAN_ANDROID_OPTION} \
|
||||
${FILAMAT_ANDROID_OPTION} \
|
||||
../..
|
||||
fi
|
||||
|
||||
@@ -319,18 +282,12 @@ function build_android_target {
|
||||
function build_android_arch {
|
||||
local ARCH=$1
|
||||
local ARCH_NAME=$2
|
||||
local TOOLCHAIN_ARCH=$3
|
||||
local TOOLCHAIN_NAME=toolchains/${UNAME}/${ARCH_NAME}-4.9
|
||||
|
||||
if [ ! -d "$TOOLCHAIN_NAME" ]; then
|
||||
generate_toolchain ${TOOLCHAIN_ARCH} ${ARCH_NAME}
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
build_android_target "Debug" "$ARCH"
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
build_android_target "Release" "$ARCH"
|
||||
fi
|
||||
}
|
||||
@@ -338,8 +295,8 @@ function build_android_arch {
|
||||
function archive_android {
|
||||
local LC_TARGET=`echo $1 | tr '[:upper:]' '[:lower:]'`
|
||||
|
||||
if [ -d "out/android-${LC_TARGET}/filament" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
if [[ -d "out/android-${LC_TARGET}/filament" ]]; then
|
||||
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
|
||||
echo "Generating out/filament-android-${LC_TARGET}-${LC_UNAME}.tgz..."
|
||||
cd out/android-${LC_TARGET}
|
||||
tar -czvf ../filament-android-${LC_TARGET}-${LC_UNAME}.tgz filament
|
||||
@@ -355,36 +312,36 @@ function build_android {
|
||||
build_desktop "${MOBILE_HOST_TOOLS}"
|
||||
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
|
||||
|
||||
build_android_arch "aarch64" "aarch64-linux-android" "arm64"
|
||||
build_android_arch "arm7" "arm-linux-androideabi" "arm"
|
||||
build_android_arch "x86_64" "x86_64-linux-android" "x86_64"
|
||||
build_android_arch "x86" "i686-linux-android" "x86"
|
||||
build_android_arch "aarch64" "aarch64-linux-android"
|
||||
build_android_arch "arm7" "arm-linux-androideabi"
|
||||
build_android_arch "x86_64" "x86_64-linux-android"
|
||||
build_android_arch "x86" "i686-linux-android"
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
archive_android "Debug"
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
archive_android "Release"
|
||||
fi
|
||||
|
||||
cd android/filament-android
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
./gradlew -Pfilament_dist_dir=../../out/android-debug/filament assembleDebug \
|
||||
-Pextra_cmake_args=${VULKAN_ANDROID_OPTION}
|
||||
|
||||
if [ "$INSTALL_COMMAND" ]; then
|
||||
if [[ "$INSTALL_COMMAND" ]]; then
|
||||
echo "Installing out/filament-android-debug.aar..."
|
||||
cp build/outputs/aar/filament-android-debug.aar ../../out/
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease \
|
||||
-Pextra_cmake_args=${VULKAN_ANDROID_OPTION}
|
||||
|
||||
if [ "$INSTALL_COMMAND" ]; then
|
||||
if [[ "$INSTALL_COMMAND" ]]; then
|
||||
echo "Installing out/filament-android-release.aar..."
|
||||
cp build/outputs/aar/filament-android-release.aar ../../out/
|
||||
fi
|
||||
@@ -393,23 +350,23 @@ function build_android {
|
||||
cd ../..
|
||||
|
||||
|
||||
if [ "$BUILD_FILAMAT_ANDROID" == "true" ]; then
|
||||
if [[ "$BUILD_FILAMAT_ANDROID" == "true" ]]; then
|
||||
|
||||
cd android/filamat-android
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
./gradlew -Pfilament_dist_dir=../../out/android-debug/filament assembleDebug
|
||||
|
||||
if [ "$INSTALL_COMMAND" ]; then
|
||||
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
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
|
||||
if [ "$INSTALL_COMMAND" ]; then
|
||||
if [[ "$INSTALL_COMMAND" ]]; then
|
||||
echo "Installing out/filamat-android-release.aar..."
|
||||
cp build/outputs/aar/filamat-android-release.aar ../../out/
|
||||
fi
|
||||
@@ -422,7 +379,7 @@ function build_android {
|
||||
|
||||
function ensure_ios_toolchain {
|
||||
local TOOLCHAIN_PATH="build/toolchain-mac-ios.cmake"
|
||||
if [ -e ${TOOLCHAIN_PATH} ]; then
|
||||
if [[ -e ${TOOLCHAIN_PATH} ]]; then
|
||||
echo "iOS toolchain file exists."
|
||||
return 0
|
||||
fi
|
||||
@@ -462,7 +419,7 @@ function build_ios_target {
|
||||
|
||||
cd out/cmake-ios-${LC_TARGET}-${ARCH}
|
||||
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
|
||||
cmake \
|
||||
-G "$BUILD_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE=$1 \
|
||||
@@ -476,8 +433,8 @@ function build_ios_target {
|
||||
|
||||
${BUILD_COMMAND} install
|
||||
|
||||
if [ -d "../ios-${LC_TARGET}/filament" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
if [[ -d "../ios-${LC_TARGET}/filament" ]]; then
|
||||
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
|
||||
echo "Generating out/filament-${LC_TARGET}-ios.tgz..."
|
||||
cd ../ios-${LC_TARGET}
|
||||
tar -czvf ../filament-${LC_TARGET}-ios.tgz filament
|
||||
@@ -499,58 +456,97 @@ function build_ios {
|
||||
# In theory, we could support iPhone architectures older than arm64, but
|
||||
# only arm64 devices support OpenGL 3.0 / Metal
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
|
||||
build_ios_target "Debug" "arm64" "iphoneos"
|
||||
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
|
||||
if [[ "$IOS_BUILD_SIMULATOR" == "true" ]]; then
|
||||
build_ios_target "Debug" "x86_64" "iphonesimulator"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
|
||||
build_ios_target "Release" "arm64" "iphoneos"
|
||||
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
|
||||
if [[ "$IOS_BUILD_SIMULATOR" == "true" ]]; then
|
||||
build_ios_target "Release" "x86_64" "iphonesimulator"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function build_web_docs {
|
||||
echo "Building Web documents..."
|
||||
|
||||
mkdir -p out/web-docs
|
||||
cd out/web-docs
|
||||
|
||||
# Create an empty npm package to link markdeep-rasterizer into
|
||||
npm list | grep web-docs@1.0.0 > /dev/null || npm init --yes > /dev/null
|
||||
npm list | grep markdeep-rasterizer > /dev/null || npm install ../../build/web/markdeep-rasterizer > /dev/null
|
||||
|
||||
# Generate documents
|
||||
npx markdeep-rasterizer ../../docs/Filament.md.html ../../docs/Materials.md.html ../../docs/
|
||||
|
||||
cd ../..
|
||||
}
|
||||
|
||||
function validate_build_command {
|
||||
set +e
|
||||
# Make sure CMake is installed
|
||||
cmake_binary=`which cmake`
|
||||
if [ ! "$cmake_binary" ]; then
|
||||
if [[ ! "$cmake_binary" ]]; then
|
||||
echo "Error: could not find cmake, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Only check CMake's version number when building Android binaries
|
||||
if [[ "$ISSUE_ANDROID_BUILD" == "true" ]]; then
|
||||
cmake_version=`cmake --version`
|
||||
if [[ "$cmake_version" =~ ([0-9]+)\.([0-9]+)\.[0-9]+ ]]; then
|
||||
if [[ "${BASH_REMATCH[1]}" -lt "${CMAKE_MAJOR}" ]] || \
|
||||
[[ "${BASH_REMATCH[2]}" -lt "${CMAKE_MINOR}" ]]; then
|
||||
echo "Error: cmake version ${CMAKE_MAJOR}.${CMAKE_MINOR}+ is required," \
|
||||
"${BASH_REMATCH[1]}.${BASH_REMATCH[2]} installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make sure Ninja is installed
|
||||
if [ "$BUILD_COMMAND" == "ninja" ]; then
|
||||
if [[ "$BUILD_COMMAND" == "ninja" ]]; then
|
||||
ninja_binary=`which ninja`
|
||||
if [ ! "$ninja_binary" ]; then
|
||||
if [[ ! "$ninja_binary" ]]; then
|
||||
echo "Warning: could not find ninja, using make instead"
|
||||
BUILD_GENERATOR="Unix Makefiles"
|
||||
BUILD_COMMAND="make"
|
||||
fi
|
||||
fi
|
||||
# Make sure Make is installed
|
||||
if [ "$BUILD_COMMAND" == "make" ]; then
|
||||
if [[ "$BUILD_COMMAND" == "make" ]]; then
|
||||
make_binary=`which make`
|
||||
if [ ! "$make_binary" ]; then
|
||||
if [[ ! "$make_binary" ]]; then
|
||||
echo "Error: could not find make, exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
# Make sure we have Java
|
||||
javac_binary=`which javac`
|
||||
if [ "$JAVA_HOME" == "" ] || [ ! "$javac_binary" ]; then
|
||||
if [[ "$JAVA_HOME" == "" ]] || [[ ! "$javac_binary" ]]; then
|
||||
echo "Warning: JAVA_HOME is not set, skipping Java projects"
|
||||
ENABLE_JAVA=OFF
|
||||
fi
|
||||
# If building a WebAssembly module, ensure we know where Emscripten lives.
|
||||
if [ "$EMSDK" == "" ] && [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
|
||||
if [[ "$EMSDK" == "" ]] && [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
|
||||
echo "Error: EMSDK is not set, exiting"
|
||||
exit 1
|
||||
fi
|
||||
# Web documents require node and npm for processing
|
||||
if [[ "$ISSUE_WEB_DOCS" == "true" ]]; then
|
||||
node_binary=`which node`
|
||||
npm_binary=`which npm`
|
||||
npx_binary=`which npx`
|
||||
if [[ ! "$node_binary" ]] || [[ ! "$npm_binary" ]] || [[ ! "$npx_binary" ]]; then
|
||||
echo "Error: Web documents require node, npm and npx to be installed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
@@ -558,18 +554,19 @@ function run_test {
|
||||
test=$1
|
||||
# The input string might contain arguments, so we use "set -- $test" to replace $1 with the
|
||||
# first whitespace-separated token in the string.
|
||||
set -- $test
|
||||
set -- ${test}
|
||||
test_name=`basename $1`
|
||||
./out/cmake-debug/${test} --gtest_output="xml:out/test-results/$test_name/sponge_log.xml"
|
||||
}
|
||||
|
||||
function run_tests {
|
||||
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
|
||||
if [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
|
||||
if ! echo "TypeScript `tsc --version`" ; then
|
||||
tsc --noEmit \
|
||||
third_party/gl-matrix/gl-matrix.d.ts \
|
||||
web/filament-js/filament.d.ts \
|
||||
web/filament-js/test.ts
|
||||
fi
|
||||
else
|
||||
while read test; do
|
||||
run_test "$test"
|
||||
@@ -581,7 +578,7 @@ function run_tests {
|
||||
|
||||
pushd `dirname $0` > /dev/null
|
||||
|
||||
while getopts ":hacfijmp:tuvsl" opt; do
|
||||
while getopts ":hacfijmp:tuvslw" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -590,7 +587,7 @@ while getopts ":hacfijmp:tuvsl" opt; do
|
||||
a)
|
||||
ISSUE_ARCHIVES=true
|
||||
INSTALL_COMMAND=install
|
||||
WEB_DOCS_OPTION="-DGENERATE_WEB_DOCS=ON"
|
||||
JS_DOCS_OPTION="-DGENERATE_JS_DOCS=ON"
|
||||
;;
|
||||
c)
|
||||
ISSUE_CLEAN=true
|
||||
@@ -611,9 +608,9 @@ while getopts ":hacfijmp:tuvsl" opt; do
|
||||
p)
|
||||
ISSUE_DESKTOP_BUILD=false
|
||||
platforms=$(echo "$OPTARG" | tr ',' '\n')
|
||||
for platform in $platforms
|
||||
for platform in ${platforms}
|
||||
do
|
||||
case $platform in
|
||||
case ${platform} in
|
||||
desktop)
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
;;
|
||||
@@ -635,9 +632,6 @@ while getopts ":hacfijmp:tuvsl" opt; do
|
||||
esac
|
||||
done
|
||||
;;
|
||||
t)
|
||||
GENERATE_TOOLCHAINS=true
|
||||
;;
|
||||
u)
|
||||
ISSUE_DEBUG_BUILD=true
|
||||
RUN_TESTS=true
|
||||
@@ -662,6 +656,9 @@ while getopts ":hacfijmp:tuvsl" opt; do
|
||||
IOS_BUILD_SIMULATOR=true
|
||||
echo "iOS simulator support enabled."
|
||||
;;
|
||||
w)
|
||||
ISSUE_WEB_DOCS=true
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
echo ""
|
||||
@@ -677,7 +674,7 @@ while getopts ":hacfijmp:tuvsl" opt; do
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$#" == "0" ]; then
|
||||
if [[ "$#" == "0" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
@@ -685,9 +682,9 @@ fi
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
for arg; do
|
||||
if [ "$arg" == "release" ]; then
|
||||
if [[ "$arg" == "release" ]]; then
|
||||
ISSUE_RELEASE_BUILD=true
|
||||
elif [ "$arg" == "debug" ]; then
|
||||
elif [[ "$arg" == "debug" ]]; then
|
||||
ISSUE_DEBUG_BUILD=true
|
||||
else
|
||||
BUILD_CUSTOM_TARGETS="$BUILD_CUSTOM_TARGETS $arg"
|
||||
@@ -696,30 +693,30 @@ done
|
||||
|
||||
validate_build_command
|
||||
|
||||
if [ "$ISSUE_CLEAN" == "true" ]; then
|
||||
if [[ "$ISSUE_CLEAN" == "true" ]]; then
|
||||
build_clean
|
||||
fi
|
||||
|
||||
if [ "$GENERATE_TOOLCHAINS" == "true" ]; then
|
||||
generate_toolchains
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_DESKTOP_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_DESKTOP_BUILD" == "true" ]]; then
|
||||
build_desktop
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_ANDROID_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_ANDROID_BUILD" == "true" ]]; then
|
||||
build_android
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_IOS_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_IOS_BUILD" == "true" ]]; then
|
||||
build_ios
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
|
||||
if [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
|
||||
build_webgl
|
||||
fi
|
||||
|
||||
if [ "$RUN_TESTS" == "true" ]; then
|
||||
if [[ "$ISSUE_WEB_DOCS" == "true" ]]; then
|
||||
build_web_docs
|
||||
fi
|
||||
|
||||
if [[ "$RUN_TESTS" == "true" ]]; then
|
||||
run_tests
|
||||
fi
|
||||
|
||||
@@ -14,6 +14,8 @@ set -x
|
||||
UNAME=`echo $(uname)`
|
||||
LC_UNAME=`echo $UNAME | tr '[:upper:]' '[:lower:]'`
|
||||
|
||||
FILAMENT_ANDROID_CI_BUILD=true
|
||||
|
||||
# build-common.sh will generate the following variables:
|
||||
# $GENERATE_ARCHIVES
|
||||
# $BUILD_DEBUG
|
||||
|
||||
@@ -4,13 +4,34 @@
|
||||
CLANG_VERSION=7
|
||||
# version of libcxx and libcxxabi we want to use
|
||||
CXX_VERSION=7.0.0
|
||||
# version of CMake to use instead of the default one
|
||||
CMAKE_VERSION=3.13.4
|
||||
# version of ninja to use
|
||||
NINJA_VERSION=1.8.2
|
||||
|
||||
# Steps specific to our CI environment
|
||||
# CI runs on Ubuntu 14.04, we need to install clang-6.0 and the
|
||||
# CI runs on Ubuntu 14.04, we need to install clang-7.0 and the
|
||||
# appropriate libc++ ourselves
|
||||
if [ "$KOKORO_BUILD_ID" ]; then
|
||||
sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/asm
|
||||
|
||||
if [ "$FILAMENT_ANDROID_CI_BUILD" ]; then
|
||||
# Update NDK
|
||||
yes | $ANDROID_HOME/tools/bin/sdkmanager "ndk-bundle" > /dev/null
|
||||
|
||||
# Install CMake
|
||||
mkdir -p cmake
|
||||
cd cmake
|
||||
|
||||
sudo wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.sh
|
||||
sudo chmod +x ./cmake-$CMAKE_VERSION-Linux-x86_64.sh
|
||||
sudo ./cmake-$CMAKE_VERSION-Linux-x86_64.sh --skip-license > /dev/null
|
||||
sudo update-alternatives --install /usr/bin/cmake cmake `pwd`/bin/cmake 1000 --force
|
||||
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# Install clang
|
||||
# This may or may not be needed...
|
||||
# sudo apt-key adv --keyserver apt.llvm.org --recv-keys 15CF4D18AF4F7421
|
||||
sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-$CLANG_VERSION main"
|
||||
@@ -68,6 +89,6 @@ if [ "$KOKORO_BUILD_ID" ]; then
|
||||
export FILAMENT_REQUIRES_CXXABI=false
|
||||
fi
|
||||
|
||||
wget -q https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip
|
||||
wget -q https://github.com/ninja-build/ninja/releases/download/v$NINJA_VERSION/ninja-linux.zip
|
||||
unzip -q ninja-linux.zip
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
# this one not so much
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
|
||||
# architecture
|
||||
set(ARCH aarch64-linux-android)
|
||||
set(DIST_ARCH arm64-v8a)
|
||||
|
||||
# toolchain
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
set(TOOL_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
set(TOOL_SUFFIX ".exe")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
|
||||
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
|
||||
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
@@ -57,3 +65,9 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
|
||||
|
||||
set(ANDROID TRUE)
|
||||
|
||||
# we are compiling Android on Windows
|
||||
set(ANDROID_ON_WINDOWS FALSE)
|
||||
if(WIN32)
|
||||
set(ANDROID_ON_WINDOWS TRUE)
|
||||
endif()
|
||||
|
||||
@@ -20,21 +20,30 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
# this one not so much
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
|
||||
# architecture
|
||||
set(ARCH arm-linux-androideabi)
|
||||
set(ARCH armv7a-linux-androideabi)
|
||||
set(AR_ARCH arm-linux-androideabi)
|
||||
set(DIST_ARCH armeabi-v7a)
|
||||
|
||||
# toolchain
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
set(TOOL_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
set(TOOL_SUFFIX ".exe")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${AR_ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
|
||||
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${AR_ARCH}-ranlib${TOOL_SUFFIX})
|
||||
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${AR_ARCH}-strip${TOOL_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
@@ -69,3 +78,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,-
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(ANDROID TRUE)
|
||||
|
||||
# we are compiling Android on Windows
|
||||
set(ANDROID_ON_WINDOWS FALSE)
|
||||
if(WIN32)
|
||||
set(ANDROID_ON_WINDOWS TRUE)
|
||||
endif()
|
||||
|
||||
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
# this one not so much
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
|
||||
# architecture
|
||||
set(ARCH i686-linux-android)
|
||||
set(DIST_ARCH x86)
|
||||
|
||||
# toolchain
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
set(TOOL_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
set(TOOL_SUFFIX ".exe")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
|
||||
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
|
||||
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
@@ -54,3 +62,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-mismat
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(ANDROID TRUE)
|
||||
|
||||
# we are compiling Android on Windows
|
||||
set(ANDROID_ON_WINDOWS FALSE)
|
||||
if(WIN32)
|
||||
set(ANDROID_ON_WINDOWS TRUE)
|
||||
endif()
|
||||
|
||||
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
|
||||
# this one not so much
|
||||
set(CMAKE_SYSTEM_VERSION 1)
|
||||
|
||||
# android
|
||||
set(API_LEVEL 21)
|
||||
|
||||
# architecture
|
||||
set(ARCH x86_64-linux-android)
|
||||
set(DIST_ARCH x86_64)
|
||||
|
||||
# toolchain
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
|
||||
|
||||
# specify the cross compiler
|
||||
set(COMPILER_SUFFIX)
|
||||
set(TOOL_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
set(TOOL_SUFFIX ".exe")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
|
||||
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
|
||||
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
@@ -54,3 +62,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-mismat
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set(ANDROID TRUE)
|
||||
|
||||
# we are compiling Android on Windows
|
||||
set(ANDROID_ON_WINDOWS FALSE)
|
||||
if(WIN32)
|
||||
set(ANDROID_ON_WINDOWS TRUE)
|
||||
endif()
|
||||
|
||||
@@ -7,17 +7,21 @@ export PATH="$PWD:$PATH"
|
||||
|
||||
# The Kokoro machines have Python 3.6.3 installed. Let's verify that here, and install the
|
||||
# distributions required for web/docs.
|
||||
python --version
|
||||
python3 --version
|
||||
pip3 install mistletoe pygments jsbeautifier future_fstrings
|
||||
|
||||
# Install a typescript compiler to allow testing.
|
||||
npm install -g typescript
|
||||
sudo pip install certifi
|
||||
sudo /Applications/Python\ 2.7/Install\ Certificates.command
|
||||
|
||||
# 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
|
||||
emsdk/emsdk update
|
||||
emsdk/emsdk install sdk-1.38.11-64bit
|
||||
emsdk/emsdk activate sdk-1.38.11-64bit
|
||||
export EMSDK="$PWD/emsdk"
|
||||
# FIXME: kokoro machines have node and npm but currently they are symlinked to non-existent files
|
||||
# npm install -g typescript
|
||||
|
||||
# Install emscripten.
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/a77638d.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python emsdk install latest
|
||||
python emsdk activate latest
|
||||
|
||||
export EMSDK="$PWD"
|
||||
cd ..
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const puppeteer = require('puppeteer');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const cheerio = require("cheerio");
|
||||
|
||||
const markdeepScript = '<script src="https://casual-effects.com/markdeep/latest/markdeep.min.js"></script>';
|
||||
|
||||
async function domDump(url) {
|
||||
const browser = await puppeteer.launch({headless: true});
|
||||
const page = await browser.newPage();
|
||||
await page.goto(url, {waitUntil: 'networkidle0'});
|
||||
const html = await page.content();
|
||||
await browser.close();
|
||||
return html;
|
||||
}
|
||||
|
||||
var files = process.argv.slice(2);
|
||||
if (files.length < 2) {
|
||||
console.log("npx markdeep-rasterizer <file1> ... <output_dir>");
|
||||
console.log("Each file must be a .md.html file.");
|
||||
console.log("The output directory is mandatory.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var outputDir = path.join(process.cwd(), files[files.length - 1]);
|
||||
files = files.slice(0, files.length - 1);
|
||||
|
||||
files.forEach(function(file) {
|
||||
if (file.substring(file.length - '.md.html'.length, file.length) === '.md.html') {
|
||||
file = file.substring(0, file.length - '.md.html'.length);
|
||||
}
|
||||
|
||||
var markdeepFile = path.join(process.cwd(), file + '.md.html');
|
||||
var outputFile = path.basename(file + '.html');
|
||||
|
||||
domDump('file://' + markdeepFile + '?export').then(function(dom) {
|
||||
console.log('Processing ' + markdeepFile + '...');
|
||||
|
||||
// Parse the DOM
|
||||
var $ = cheerio.load(dom);
|
||||
// Because of ?export Markdeep generated the output in a <pre> tag
|
||||
dom = $('pre').text();
|
||||
// We must remove the remaining invocation of Markdeep
|
||||
dom = dom.replace(markdeepScript, '');
|
||||
// Now replace <pre> with its own content so we can preserve headers
|
||||
$('pre').replaceWith(dom);
|
||||
|
||||
fs.writeFile(path.join(outputDir, outputFile), $.html(), function(err) {
|
||||
if (err) console.log(err);
|
||||
});
|
||||
}).catch(function(e) {
|
||||
console.log('Could no process ' + markdeepFile + '!');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "markdeep-rasterizer",
|
||||
"version": "1.0.0",
|
||||
"description": "Rasterizes Markdeep files to HTML using puppeteer",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Romain Guy <romainguy@curious-creature.com>",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"markdeep-rasterizer": "./cli.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cheerio": "^1.0.0-rc.2",
|
||||
"puppeteer": "^1.12.2"
|
||||
}
|
||||
}
|
||||
@@ -1083,10 +1083,10 @@ D_{velvet}(v,h,\alpha) = \frac{1}{\pi(1 + 4\alpha^2)} (1 + 4 \frac{exp\left(\fra
|
||||
For the full specular BRDF, we also follow [#Neubelt13] and replace the traditional denominator with a smoother variant:
|
||||
|
||||
$$\begin{equation}\label{clothSpecularBRDF}
|
||||
f_{r}(v,h,\alpha) = \frac{F(v,h) D_{velvet}(v,h,\alpha)}{4(\NoL + \NoV - (\NoL)(\NoV))}
|
||||
f_{r}(v,h,\alpha) = \frac{D_{velvet}(v,h,\alpha)}{4(\NoL + \NoV - (\NoL)(\NoV))}
|
||||
\end{equation}$$
|
||||
|
||||
The implementation of the velvet NDF is presented in listing [clothBRDF], optimized to properly fit in half float formats and to avoid computing a costly cotangent, relying instead on trigonometric identities.
|
||||
The implementation of the velvet NDF is presented in listing [clothBRDF], optimized to properly fit in half float formats and to avoid computing a costly cotangent, relying instead on trigonometric identities. Note that we removed the Fresnel component from this BRDF.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
float D_Ashikhmin(float linearRoughness, float NoH) {
|
||||
@@ -1156,7 +1156,7 @@ The complete implementation of our cloth BRDF, including sheen color and optiona
|
||||
// specular BRDF
|
||||
float D = distributionCloth(linearRoughness, NoH);
|
||||
float V = visibilityCloth(NoV, NoL);
|
||||
vec3 F = fresnel(sheenColor, LoH);
|
||||
vec3 F = sheenColor;
|
||||
vec3 Fr = (D * V) * F;
|
||||
|
||||
// diffuse BRDF
|
||||
@@ -2014,7 +2014,7 @@ $$\begin{equation}
|
||||
I(f(n, v, \alpha)) \equiv \frac{1}{N}\sum_{\forall \, i \in image} f(l_i, n, v, \alpha) \left<\NoL\right>
|
||||
\end{equation}$$
|
||||
|
||||
However, in practice we're using _importance sampling_ which needs to take de $pdf$ of the distribution
|
||||
However, in practice we're using _importance sampling_ which needs to take the $pdf$ of the distribution
|
||||
into account and adds a term $\frac{\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
|
||||
See Importance Sampling For The IBL section:
|
||||
|
||||
@@ -2417,57 +2417,11 @@ Figure [anisotropicDirection] demonstrates this modified implementation in pract
|
||||
|
||||
### Cloth ###
|
||||
|
||||
The IBL implementation for the cloth material model is more complicated than for the other material models. The main difference stems from the use of a different NDF (Ashikhmin vs height-correlated Smith GGX). As described in this section, we use the split-sum approximation to compute the DFG term of the BRDF when computing an IBL. Since this DFG term is based on the wrong NDF, we must find a new approximation.
|
||||
The IBL implementation for the cloth material model is more complicated than for the other material models. The main difference stems from the use of a different NDF ("Charlie" vs height-correlated Smith GGX). As described in this section, we use the split-sum approximation to compute the DFG term of the BRDF when computing an IBL. This DFG term is designed for a different BRDF and cannot be used for the cloth BRDF. Since we designed our cloth BRDF to not need a Fresnel term, we can generate a single DG term in the 3rd channel of the DFG LUT. The result is shown in figure [dfgClothLUT].
|
||||
|
||||
The approximation we use is purely analytical and was manually fitted against a Monte-Carlo reference shown in figure [clothDFGReference] (using $2^{22}$ samples per data point instead of importance sampling). This visual comparison shows the significant impact the cloth NDF has on the BRDF. Using the standard DFG term would result in widely incorrect results.
|
||||
The DG term is generated using uniform sampling as recommended in [#Estevez17]. With uniform sampling the $pdf$ is simply $\frac{1}{2\pi}$ and we must still use the Jacobian $\frac{1}{\eft< 4 \VoH \right>}$.
|
||||
|
||||
![Figure [clothDFGReference]: DFG LUT (left) vs Ashikhmin DFG LUT (middle) vs "Charlie" DFG LUT (right)](images/ibl/dfg_cloth.png)
|
||||
|
||||
Manual fitting was performed in Mathematica (as shown in figure [clothManualFitting]) and while not perfect, the analytical approximation strikes a decent balance between correctness and runtime cost.
|
||||
|
||||
![Figure [clothManualFitting]: Manual fitting of the DFG term for the cloth NDF](images/ibl/cloth_dfg_approximation.png)
|
||||
|
||||
Listing [clothApprox] shows the implementation of the DFG approximation for the Ashikhmin NDF. We also provide the [Mathematica notebook](math/Cloth%20DFG%20Approximation.nb) containing the formulas of our approximation as well as comparisons to the reference LUT.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
vec2 PrefilteredDFG_Cloth_Ashikhmin(float roughness, float NoV) {
|
||||
const vec4 c0 = vec4(0.24, 0.93, 0.01, 0.20);
|
||||
const vec4 c1 = vec4(2.00, -1.30, 0.40, 0.03);
|
||||
|
||||
float s = 1.0 - NoV;
|
||||
float e = s - c0.y;
|
||||
float g = c0.x * exp2(-(e * e) / (2.0 * c0.z)) + s * c0.w;
|
||||
float n = roughness * c1.x + c1.y;
|
||||
float r = max(1.0 - n * n, c1.z) * g;
|
||||
|
||||
return vec2(r, r * c1.w);
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
[Listing [clothApprox]: GLSL implementation of the DFG approximation for the Ashikhmin cloth NDF]
|
||||
|
||||
Listing [clothCharlieApprox] shows the implementation of the DFG approximation for the "Charlie" NDF.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
vec2 PrefilteredDFG_Cloth_Charlie(float roughness, float NoV) {
|
||||
const vec3 c0 = vec3(0.95, 1250.0, 0.0095);
|
||||
const vec4 c1 = vec4(0.04, 0.2, 0.3, 0.2);
|
||||
|
||||
float a = 1.0 - NoV;
|
||||
float b = 1.0 - roughness;
|
||||
|
||||
float n = pow(c1.x + a, 64.0);
|
||||
float e = b - c0.x;
|
||||
float g = exp2(-(e * e) * c0.y);
|
||||
float f = b + c1.y;
|
||||
float a2 = a * a;
|
||||
float a3 = a2 * a;
|
||||
float c = n * g + c1.z * (a + c1.w) * roughness + f * f * a3 * a3 * a2;
|
||||
float r = min(c, 18.0);
|
||||
|
||||
return vec2(r, r * c0.z);
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
[Listing [clothCharlieApprox]: GLSL implementation of the DFG approximation for the "Charlie" cloth NDF]
|
||||
![Figure [dfgClothLUT]: DFG LUT with a 3rd channel encoding the DG term of the cloth BRDF](images/ibl/dfg_cloth.png)
|
||||
|
||||
The remainder of the image-based lighting implementation follows the same steps as the implementation of regular lights, including the optional subsurface scattering term and its wrap diffuse component. Just as with the clear coat IBL implementation, we cannot integrate over the hemisphere and use the view direction as the dominant light direction to compute the wrap diffuse component.
|
||||
|
||||
@@ -3621,13 +3575,13 @@ $$\begin{equation}
|
||||
The PDF of the BRDF can therefore be expressed as in equation $\ref{importantPDF}$:
|
||||
|
||||
$$\begin{equation}\label{importantPDF}
|
||||
p(\theta,\phi) = \frac{\alpha^2}{\pi(cos^2\theta (\alpha^2-1) + 1) cos\theta sin\theta}
|
||||
p(\theta,\phi) = \frac{\alpha^2}{\pi(cos^2\theta (\alpha^2-1) + 1)^2} cos\theta sin\theta
|
||||
\end{equation}$$
|
||||
|
||||
The term $sin\theta$ comes from the differential solid angle $sin\theta d\phi d\theta$ since we integrate over a sphere. We sample $\theta$ and $\phi$ independently:
|
||||
|
||||
$$\begin{align*}
|
||||
p(\theta) &= \int_0^{2\pi} p(\theta,\phi) d\phi = \frac{2\alpha^2}{cos^2\theta (\alpha^2-1) + 1} cos\theta sin\theta \\
|
||||
p(\theta) &= \int_0^{2\pi} p(\theta,\phi) d\phi = \frac{2\alpha^2}{(cos^2\theta (\alpha^2-1) + 1)^2} cos\theta sin\theta \\
|
||||
p(\phi) &= \frac{p(\theta,\phi)}{p(\phi)} = \frac{1}{2\pi}
|
||||
\end{align*}$$
|
||||
|
||||
@@ -4285,6 +4239,10 @@ void main() {
|
||||
|
||||
# Revisions
|
||||
|
||||
February 20, 2019: Cloth shading
|
||||
- Removed Fresnel term from the cloth BRDF
|
||||
- Removed cloth DFG approximations, replaced with a new channel in the DFG LUT
|
||||
|
||||
August 21, 2018: Multiscattering
|
||||
- Added section [Energy loss in specular reflectance] on how to compensate for energy loss in single scattering BRDFs
|
||||
|
||||
|
||||
@@ -436,9 +436,6 @@ Chromaticity information should instead be set on the sheen color. To create mor
|
||||
such as denim, cotton, etc. use the base color for chromaticity and use the default sheen color
|
||||
or set the sheen color to the luminance of the base color.
|
||||
|
||||
!!! Warning
|
||||
The cloth material model is more expensive than the standard material model.
|
||||
|
||||
!!! Tip
|
||||
To see the effect of the `roughness` parameter make sure the `sheenColor` is brighter than
|
||||
`baseColor`. This can be used to create a fuzz effect. Taking the luminance of `baseColor`
|
||||
@@ -1096,7 +1093,7 @@ Value
|
||||
|
||||
Description
|
||||
: Reduces specular aliasing by increasing roughness based on the local geometric curvature.
|
||||
This property is particularly effective if you only use MSAA.
|
||||
This property is particularly effective if you only use MSAA as your anti-aliasing method.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
@@ -1105,7 +1102,7 @@ material {
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
![Figure [curvatureToRoughness]: Close up of a glossy metallic surface rendered normally (left) and
|
||||
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.png)
|
||||
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.jpg)
|
||||
|
||||
### limitOverInterpolation
|
||||
|
||||
@@ -1128,6 +1125,31 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
### clearCoatIorChange
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `true`.
|
||||
|
||||
Description
|
||||
: When adding a clear coat layer, the change in index of refraction (IoR) is taken into account
|
||||
to modify the specular color of the base layer. This appears to darken `baseColor`. When this
|
||||
effect is disabled, `baseColor` is left unmodified. See figure [clearCoatIorChange] for an
|
||||
example of how this property can affect a red metallic base layer.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
clearCoatIorChange : false
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
![Figure [clearCoatIorChange]: The same rough metallic ball with a clear coat layer rendered
|
||||
with `clearCoatIorChange` enabled (left) and disabled
|
||||
(right).](images/screenshot_clear_coat_ior_change.jpg)
|
||||
|
||||
### variantFilter
|
||||
|
||||
Type
|
||||
|
||||
@@ -66,8 +66,8 @@
|
||||
<h1>Core Documentation</h1>
|
||||
<ul>
|
||||
<li><a href="https://github.com/google/filament/blob/master/README.md">Build Instructions</a></li>
|
||||
<li><a href="https://google.github.io/filament/Filament.md.html">Filament Design</a></li>
|
||||
<li><a href="https://google.github.io/filament/Materials.md.html">Materials Overview</a></li>
|
||||
<li><a href="https://google.github.io/filament/Filament.html">Filament Design</a></li>
|
||||
<li><a href="https://google.github.io/filament/Materials.html">Materials Overview</a></li>
|
||||
<li><a href="https://google.github.io/filament/Material%20Properties.pdf">Materials Ref Sheet</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 346 KiB |
@@ -26,7 +26,7 @@
|
||||
<pubDate>Tue, 30 Oct 2018 13:13:14 -0700</pubDate>
|
||||
|
||||
<guid>https://google.github.io/filament/webgl/</guid>
|
||||
<description> tutorials Triangle Tutorial Redball Tutorial Suzanne Tutorial demos parquet suzanne knotess other documentation JavaScript API reference WebGL Meetup Slides (2018) </description>
|
||||
<description> tutorials Triangle Tutorial Redball Tutorial Suzanne Tutorial demos parquet suzanne helmet knotess other documentation JavaScript API reference WebGL Meetup Slides (2018) </description>
|
||||
</item>
|
||||
|
||||
</channel>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 5.1 MiB After Width: | Height: | Size: 5.1 MiB |
|
Before Width: | Height: | Size: 806 KiB After Width: | Height: | Size: 806 KiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 5.4 MiB After Width: | Height: | Size: 5.4 MiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.5 MiB After Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 3.5 MiB After Width: | Height: | Size: 3.5 MiB |
|
Before Width: | Height: | Size: 4.4 MiB After Width: | Height: | Size: 4.4 MiB |
|
Before Width: | Height: | Size: 5.1 MiB After Width: | Height: | Size: 5.1 MiB |
|
Before Width: | Height: | Size: 737 KiB After Width: | Height: | Size: 737 KiB |
|
Before Width: | Height: | Size: 3.6 MiB After Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 4.3 MiB After Width: | Height: | Size: 4.3 MiB |
@@ -0,0 +1,154 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>FlightHelmet</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
|
||||
<link href="https://google.github.io/filament/favicon.png" rel="icon" type="image/x-icon" />
|
||||
<style>
|
||||
body { margin: 0; overflow: hidden; }
|
||||
canvas { touch-action: none; width: 100%; height: 100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<script src="filament.js"></script>
|
||||
<script src="gl-matrix-min.js"></script>
|
||||
<script src="https://unpkg.com/gltumble"></script>
|
||||
<script>
|
||||
|
||||
const ibl_suffix = Filament.getSupportedFormatSuffix('etc s3tc');
|
||||
|
||||
const env = 'syferfontein_18d_clear_2k';
|
||||
const ibl_url = `${env}/${env}_ibl${ibl_suffix}.ktx`;
|
||||
const sky_url = `${env}/${env}_skybox.ktx`;
|
||||
const helmet_filamat_url = 'helmet.filamat';
|
||||
const filamesh_url = 'helmet.filamesh';
|
||||
|
||||
Filament.init([
|
||||
'FlightHelmet_baseColor.png',
|
||||
'FlightHelmet_occlusionRoughnessMetallic.png',
|
||||
'FlightHelmet_normal.png',
|
||||
'FlightHelmet_baseColor1.png',
|
||||
'FlightHelmet_occlusionRoughnessMetallic1.png',
|
||||
'FlightHelmet_normal1.png',
|
||||
'FlightHelmet_baseColor2.png',
|
||||
'FlightHelmet_occlusionRoughnessMetallic2.png',
|
||||
'FlightHelmet_normal2.png',
|
||||
'FlightHelmet_baseColor3.png',
|
||||
'FlightHelmet_occlusionRoughnessMetallic3.png',
|
||||
'FlightHelmet_normal3.png',
|
||||
'FlightHelmet_baseColor4.png',
|
||||
'FlightHelmet_occlusionRoughnessMetallic4.png',
|
||||
'FlightHelmet_normal4.png',
|
||||
helmet_filamat_url, filamesh_url, ibl_url, sky_url
|
||||
], () => {
|
||||
window.Fov = Filament.Camera$Fov;
|
||||
window.LightType = Filament.LightManager$Type;
|
||||
window.app = new App(document.getElementsByTagName('canvas')[0]);
|
||||
});
|
||||
|
||||
class App {
|
||||
constructor(canvas) {
|
||||
this.canvas = canvas;
|
||||
const engine = this.engine = Filament.Engine.create(this.canvas);
|
||||
this.scene = engine.createScene();
|
||||
this.trackball = new Trackball(canvas, {startSpin: 0.035});
|
||||
|
||||
const sunlight = Filament.EntityManager.get().create();
|
||||
Filament.LightManager.Builder(LightType.SUN)
|
||||
.color([0.98, 0.92, 0.89])
|
||||
.intensity(100000.0)
|
||||
.direction([0.6, -1.0, -0.8])
|
||||
.castShadows(true)
|
||||
.sunAngularRadius(1.9)
|
||||
.sunHaloSize(10.0)
|
||||
.sunHaloFalloff(80.0)
|
||||
.build(engine, sunlight);
|
||||
this.scene.addEntity(sunlight);
|
||||
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
|
||||
this.scene.setIndirectLight(indirectLight);
|
||||
indirectLight.setIntensity(100000);
|
||||
|
||||
const skybox = engine.createSkyFromKtx(sky_url);
|
||||
this.scene.setSkybox(skybox);
|
||||
|
||||
const sampler = new Filament.TextureSampler(
|
||||
Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
|
||||
Filament.MagFilter.LINEAR,
|
||||
Filament.WrapMode.CLAMP_TO_EDGE);
|
||||
|
||||
const helmetMaterial = engine.createMaterial(helmet_filamat_url);
|
||||
|
||||
const setTextures = function(minstance, suffix) {
|
||||
const setParam = minstance.setTextureParameter.bind(minstance);
|
||||
const createTex = engine.createTextureFromPng.bind(engine);
|
||||
const baseColor = `FlightHelmet_baseColor${suffix}.png`;
|
||||
const orm = `FlightHelmet_occlusionRoughnessMetallic${suffix}.png`;
|
||||
const normal = `FlightHelmet_normal${suffix}.png`;
|
||||
setParam('baseColor', createTex(baseColor, {srgb: true}), sampler);
|
||||
setParam('occlusionRoughnessMetallic', createTex(orm), sampler);
|
||||
setParam('normalMap', createTex(normal), sampler);
|
||||
};
|
||||
|
||||
const GlassPlasticMat = helmetMaterial.createInstance();
|
||||
const LeatherPartsMat = helmetMaterial.createInstance();
|
||||
const LensesMat = helmetMaterial.createInstance();
|
||||
const MetalPartsMat = helmetMaterial.createInstance();
|
||||
const RubberWoodMat = helmetMaterial.createInstance();
|
||||
|
||||
setTextures(GlassPlasticMat, '');
|
||||
setTextures(LeatherPartsMat, '1');
|
||||
setTextures(LensesMat, '2');
|
||||
setTextures(MetalPartsMat, '3');
|
||||
setTextures(RubberWoodMat, '4');
|
||||
|
||||
const mats = { GlassPlasticMat, LeatherPartsMat, LensesMat, MetalPartsMat, RubberWoodMat };
|
||||
const mesh = engine.loadFilamesh(filamesh_url, null, mats);
|
||||
|
||||
let rm = engine.getRenderableManager();
|
||||
let renderable = rm.getInstance(mesh.renderable);
|
||||
rm.setCastShadows(renderable, true);
|
||||
rm.setReceiveShadows(renderable, true);
|
||||
|
||||
this.helmet = mesh.renderable;
|
||||
this.scene.addEntity(mesh.renderable);
|
||||
|
||||
this.swapChain = engine.createSwapChain();
|
||||
this.renderer = engine.createRenderer();
|
||||
this.camera = engine.createCamera();
|
||||
this.view = engine.createView();
|
||||
this.view.setCamera(this.camera);
|
||||
this.view.setScene(this.scene);
|
||||
this.resize();
|
||||
this.render = this.render.bind(this);
|
||||
this.resize = this.resize.bind(this);
|
||||
window.addEventListener('resize', this.resize);
|
||||
window.requestAnimationFrame(this.render);
|
||||
}
|
||||
|
||||
render() {
|
||||
const tcm = this.engine.getTransformManager();
|
||||
const inst = tcm.getInstance(this.helmet);
|
||||
tcm.setTransform(inst, this.trackball.getMatrix());
|
||||
inst.delete();
|
||||
this.renderer.render(this.swapChain, this.view);
|
||||
window.requestAnimationFrame(this.render);
|
||||
}
|
||||
|
||||
resize() {
|
||||
const dpr = window.devicePixelRatio;
|
||||
const width = this.canvas.width = window.innerWidth * dpr;
|
||||
const height = this.canvas.height = window.innerHeight * dpr;
|
||||
this.view.setViewport([0, 0, width, height]);
|
||||
const y = -0.125, eye = [0, y, 2], center = [0, y, 0], up = [0, 1, 0];
|
||||
this.camera.lookAt(eye, center, up);
|
||||
const aspect = width / height;
|
||||
const fov = aspect < 1 ? Fov.HORIZONTAL : Fov.VERTICAL;
|
||||
this.camera.setProjectionFov(30, aspect, 1.0, 10.0, fov);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -79,6 +79,7 @@
|
||||
<ul>
|
||||
<li><a href="https://google.github.io/filament/webgl/parquet.html">parquet</a></li>
|
||||
<li><a href="https://google.github.io/filament/webgl/suzanne.html">suzanne</a></li>
|
||||
<li><a href="https://google.github.io/filament/webgl/helmet.html">helmet</a></li>
|
||||
<li><a href="https://prideout.net/knotess/">knotess</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||