Compare commits

..

1 Commits

Author SHA1 Message Date
Run Yu
d105dc01b1 This is a test for pushing branch to github 2025-10-17 16:16:15 -04:00
1273 changed files with 24301 additions and 202035 deletions

View File

@@ -15,7 +15,7 @@ runs:
uses: actions/cache@v4 # Use a specific version
with:
path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-20251211
key: ${{ runner.os }}-brew-20250424
- name: Install Mac Prerequisites
shell: bash
run: |

View File

@@ -0,0 +1,25 @@
name: Android
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64

29
.github/workflows/ios-continuous.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: iOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous

26
.github/workflows/linux-continuous.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Linux
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz

29
.github/workflows/mac-continuous.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: macOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include

View File

@@ -1,59 +0,0 @@
name: 'Postsubmit Tasks'
on:
push:
branches:
- main
jobs:
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install tifffile numpy
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}

View File

@@ -1,115 +1,58 @@
name: 'Postsubmit CI'
name: 'Post-submit tasks'
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install tifffile numpy
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}

View File

@@ -1,4 +1,4 @@
name: 'Presubmit CI'
name: Presubmit
on:
push:
@@ -19,7 +19,7 @@ jobs:
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh presubmit-with-test
cd build/mac && printf "y" | ./build.sh presubmit
- name: Test material parser
run: |
out/cmake-release/filament/test/test_material_parser
@@ -134,17 +134,18 @@ jobs:
env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
ls ./gltf/Models
TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh
set -eux
start_
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py)
bash ${TEST_DIR}/generate.sh
python3 ${TEST_DIR}/src/golden_manager.py \
bash ${TEST_DIR}/generate.sh && \
python3 ${TEST_DIR}/src/golden_manager.py \
--branch=${GOLDEN_BRANCH} \
--output=${GOLDEN_OUTPUT_DIR}
# Note that we need to upload the output even if comparison fails, so we undo `set -eux`
set +eux
# Note that we need to upload the output even if comparison fails, so we undo `set -ex`
end_
python3 ${TEST_DIR}/src/compare.py \
--src=${GOLDEN_OUTPUT_DIR} \
@@ -157,7 +158,6 @@ jobs:
cat compare_output.txt >> "$GITHUB_OUTPUT"
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
fi
shell: bash
- uses: actions/upload-artifact@v4
with:
name: presubmit-renderdiff-result
@@ -179,7 +179,7 @@ jobs:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: ./build.sh -W debug test_filamat filament gltf_viewer
run: ./build.sh -W debug test_filamat filament
- name: Run test
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
@@ -203,23 +203,3 @@ jobs:
./build.sh -p desktop debug gltf_viewer
- name: Run test
run: bash test/code-correctness/test.sh
test-backend:
name: test-backend
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- uses: ./.github/actions/get-mesa
- uses: ./.github/actions/get-vulkan-sdk
- name: Prerequisites
run: |
# Must have at least clang-16 for a webgpu/dawn build.
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
shell: bash
- name: Run backend tests
shell: bash
run: |
bash test/backend/test.sh

27
.github/workflows/web-continuous.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Web
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz

View File

@@ -0,0 +1,24 @@
name: Windows
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz

View File

@@ -62,11 +62,6 @@ force a clean build by adding the `-c` flag in that case.
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
The script offers more features described by executing `build.sh -h`.
For more specialized options, please also consider the following pages:
- `-d`: [`matdbg`](https://google.github.io/filament/dup/matdbg.html)
- `-t`: [`fgviewer`](https://google.github.io/filament/dup/fgviewer.html)
- `-b` and `-y`: [ASAN/UBSAN builds](https://google.github.io/filament/notes/asan_ubsan.html)
### Filament-specific CMake Options
The following CMake options are boolean options specific to Filament:
@@ -242,12 +237,6 @@ foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
#### Easy Android build
The easiest way to build Filament for Android is to use `build.sh` and the
@@ -257,45 +246,8 @@ The easiest way to build Filament for Android is to use `build.sh` and the
./build.sh -p android release
```
To build a sample (such as `android/samples/sample-hello-triangle`) for an ARM 64-bit phone, you would run
```shell
./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
```
The output APK can be found in `android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk`
Run `build.sh -h` for more information.
#### Android Studio
You must use the latest stable release of Android Studio.
The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.
Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script
```shell
./build.sh -p android release -q arm64-v8a
```
Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.
Now we are ready to compile the apps. To open the project, point Studio to the `android` folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (`-q arm64-v8a` ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (`-q x86_64`) in the above step.
#### Manual builds
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands

View File

@@ -56,10 +56,6 @@ option(FILAMENT_ENABLE_FGVIEWER "Enable the frame graph viewer" OFF)
option(FILAMENT_USE_ABSEIL_LOGGING "Use Abseil to log, may increase binary size" OFF)
option(FILAMENT_ENABLE_EXPERIMENTAL_GCC_SUPPORT "Enable GCC support (unsupported)" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support for Filament (builds libwebp when ON)" OFF)
# This is to disable GTAO for the short-term while we investigate a way to better manage size increases.
# On the regular filament build (where size is of less concern), we enable GTAO by default.
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
@@ -299,10 +295,15 @@ set(TOOLS ${CMAKE_CURRENT_SOURCE_DIR}/tools)
# ==================================================================================================
set(MIN_CLANG_VERSION "6.0")
set(FILAMENT_USING_GCC OFF)
if (CMAKE_C_COMPILER_ID MATCHES "GNU" AND FILAMENT_ENABLE_EXPERIMENTAL_GCC_SUPPORT)
set(FILAMENT_USING_GCC ON)
elseif (CMAKE_C_COMPILER_ID MATCHES "Clang")
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
if (CMAKE_C_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
message(FATAL_ERROR "Detected C compiler Clang ${CMAKE_C_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
endif()
elseif (NOT MSVC)
message(FATAL_ERROR "Detected C compiler ${CMAKE_C_COMPILER_ID} is unsupported")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
message(FATAL_ERROR "Detected CXX compiler Clang ${CMAKE_CXX_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
endif()
@@ -343,11 +344,7 @@ if (MSVC)
set(CXX_STANDARD "/std:c++latest")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} /W0 /Zc:__cplusplus")
else()
if(FILAMENT_USING_GCC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -Wno-changes-meaning -Wno-return-type -Wno-attributes -Wno-unknown-pragmas -Wno-class-memaccess -Wno-multichar -Wno-deprecated-declarations -Wno-subobject-linkage -Wno-invalid-constexpr")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function -Wno-deprecated-declarations")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function -Wno-deprecated-declarations")
if (APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nullability-extension")
endif()
@@ -367,23 +364,11 @@ endif()
if (LINUX)
option(USE_STATIC_LIBCXX "Link against the static runtime libraries." ON)
# Add this step to support both glibc-based Linux distributions (e.g., Ubuntu, Debian)
# and musl-based distributions (e.g., Alpine).
include(CheckSymbolExists)
check_symbol_exists(__GLIBC__ "features.h" CLANG_WITH_GLIBC)
if (${USE_STATIC_LIBCXX})
if (FILAMENT_USING_GCC)
link_libraries("-static-libgcc -static-libstdc++")
elseif (CLANG_WITH_GLIBC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
endif()
# Only linux, clang doesn't want to use a shared library that is not PIC.
@@ -408,8 +393,8 @@ if (MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE")
endif()
# Add colors to ninja builds (when not using gcc)
if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja" AND NOT FILAMENT_USING_GCC)
# Add colors to ninja builds
if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
endif()
@@ -481,7 +466,7 @@ endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
if (FILAMENT_ENABLE_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -Wno-pass-failed")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
endif()
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
@@ -571,10 +556,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
# Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
@@ -767,61 +748,12 @@ function(combine_static_libs TARGET OUTPUT DEPS)
endfunction()
# ==================================================================================================
# Configuration importing/exporting prebuilt "/tools" executables
# Configuration for CMAKE_CROSSCOMPILING.
# ==================================================================================================
# In certain cases, we want the ability to separate the build type/flags (release, debug) of tools
# (matc, resgen, etc...) from filament. Cross compilation is one such case (e.g. building material
# with matc running on host while building filament for Android) [1]. Another example is when client
# wants to enable ASAN for filament but not the tool [2].
#
# Here are the varibles that are used to determine behavior is such flows:
# - CMAKE_CROSSCOMPILING : Set by cmake to indicate the build's target platform is different
# from the host platform.
# - IMPORT_EXECUTABLES_DIR : This is the directory containing the /ImportExecutables-type.cmake
# which are then included in other CMakeLists.txt to enable finding targets that have been
# prebuilt. This is set by the client in their `cmake` invocation.
# - IMPORT_EXECUTABLES : Path to a file to for 1) exporting the prebuilt targets or 2)
# importing a previously exported targets. (Used internally and should not be set by client).
# - FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR : A path set by the client to indicate that
# they wish to export the tools as prebuilts, and the corresponding targets will be recorded
# in a cmake file (i.e IMPORT_EXECUTABLES). IMPORT_EXECUTABLES will be set relative to the the
# given path. This will set FILAMENT_EXPORT_PREBUILT_EXECUTABLES=ON.
# - FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR : A path set by the client to indicate that they wish
# to import the tools as prebuilts from a .cmake file. The location (IMPORT_EXECUTABLES) of the
# file is relative to the path given. This will set FILAMENT_IMPORT_PREBUILT_EXECUTABLES=ON.
# - IMPORT_PREBUILT_EXECUTABLES and EXPORT_PREBUILT_EXECUTABLES are internal booleans set to
# ON based on the prescence of FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR and
# FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR.
#
# In conclusion, for cases
# - [1] (crosscompiling), the client must set IMPORT_EXECUTABLES_DIR for both when they are building
# the tools and when they are building the target-platform filament.
# - [2] (all other instances), the client must set FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR in
# the prebuilt exporting step, and set FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR in the importing
# step.
# TODO: Fold the cross compilation case into the more general FILAMENT_IMPORT/EXPORT variables.
if (FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR)
set(FILAMENT_EXPORT_PREBUILT_EXECUTABLES ON)
set(IMPORT_EXECUTABLES_DIR ${FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR})
endif()
if (FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR)
set(FILAMENT_IMPORT_PREBUILT_EXECUTABLES ON)
set(IMPORT_EXECUTABLES_DIR ${FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR})
endif()
if (WEBGL)
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake)
else()
if (FILAMENT_EXPORT_PREBUILT_EXECUTABLES OR FILAMENT_IMPORT_PREBUILT_EXECUTABLES)
set(IMPORT_EXECUTABLES_BUILD_TYPE Prebuilt)
else()
set(IMPORT_EXECUTABLES_BUILD_TYPE ${CMAKE_BUILD_TYPE})
endif()
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${IMPORT_EXECUTABLES_BUILD_TYPE}.cmake)
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${CMAKE_BUILD_TYPE}.cmake)
endif()
# ==================================================================================================
@@ -884,9 +816,7 @@ add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/abseil/tnt)
# Add zstd before basisu to force it to use the external zstd target,
# preventing a duplicate symbol conflict with its bundled version.
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
@@ -900,8 +830,7 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/perfetto/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
add_subdirectory(${EXTERNAL}/zstd/tnt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
add_subdirectory(${LIBRARIES}/geometry)
@@ -925,10 +854,6 @@ if (FILAMENT_ENABLE_FGVIEWER)
add_subdirectory(${LIBRARIES}/fgviewer)
endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_subdirectory(${EXTERNAL}/libwebp/tnt)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
add_subdirectory(${LIBRARIES}/bluevk)
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
@@ -984,10 +909,9 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color)
add_subdirectory(${TOOLS}/uberz)
add_subdirectory(${TOOLS}/specgen)
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
if ((NOT CMAKE_CROSSCOMPILING AND NOT FILAMENT_IMPORT_PREBUILT_EXECUTABLES) OR FILAMENT_EXPORT_PREBUILT_EXECUTABLES)
if (NOT CMAKE_CROSSCOMPILING)
export(TARGETS matc cmgen filamesh mipgen resgen uberz glslminifier FILE ${IMPORT_EXECUTABLES})
endif()

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.68.5'
implementation 'com.google.android.filament:filament-android:1.66.0'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.68.5'
pod 'Filament', '~> 1.66.0'
```
## Documentation

View File

@@ -7,47 +7,6 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.68.5
- engine: "native" Streams are officially deprecated. Use "acquired" streams instead.
- engine: add "engine.skip_frame_when_cpu_ahead_of_display" feature [b/474599530]
## v1.68.4
- gltfio: Add optional support for webp textures (EXT_texture_webp), controlled via FILAMENT_SUPPORTS_WEBP_TEXTURES cmake option
## v1.68.3
- materials: added support for the glTF `KHR_materials_dispersion` extension, which adds dispersion for refractive objects
## v1.68.2
- Support `setPresentationTime` with the Metal backend.
## v1.68.1
## v1.68.0
- engine: add `View::getLastDynamicResolutionScale()` (b/457753622)
- Metal: report GPU errors to the platform via `debugUpdateStat` (b/431665753).
- materials: Make Material Instances' UBO descriptor use dynamic offsets. [⚠️ **Recompile Materials**]
## v1.67.1
- Metal: Add support for the `SwapChain::CONFIG_MSAA_4_SAMPLES` flag.
- third_party: Optionally add libwebp to build
- controlled by cmake flag FILAMENT_SUPPORTS_WEBP_TEXTURES, defaults to OFF
- actual webp texture support for libs/gltfio coming in subsequent change
## v1.67.0
- materials: Add a new API getParameterTransformName that will return the value of the transformName field of a sampler
parameter. [⚠️ **Recompile Materials**]
## v1.66.2
## v1.66.1
- filamat: Removed a dependency on Glslang's deprecated SPIR-V remapper.

View File

@@ -100,7 +100,7 @@ buildscript {
'kotlin': '2.0.21',
'kotlin_coroutines': '1.9.0',
'buildTools': '35.0.0',
'ndk': '29.0.14206865',
'ndk': '27.0.11718014',
'androidx_core': '1.13.1',
'androidx_annotations': '1.9.0'
]
@@ -124,7 +124,6 @@ buildscript {
ext.cmakeArgs = [
"--no-warn-unused-cli",
"-DANDROID_WEAK_API_DEFS=ON",
"-DANDROID_PIE=ON",
"-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static",

View File

@@ -335,13 +335,6 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefract
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderReflectionMode(JNIEnv* env,
jclass, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->reflectionMode((MaterialBuilder::ReflectionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
jclass, jlong nativeBuilder, jint type) {

View File

@@ -177,11 +177,6 @@ public class MaterialBuilder {
SCREEN_SPACE
}
public enum ReflectionMode {
DEFAULT,
SCREEN_SPACE
}
public enum RefractionType {
SOLID,
THIN
@@ -408,12 +403,6 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder reflectionMode(ReflectionMode mode) {
nMaterialBuilderReflectionMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder refractionType(RefractionType type) {
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
@@ -615,7 +604,6 @@ public class MaterialBuilder {
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
float threshold);
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderReflectionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);

View File

@@ -51,6 +51,10 @@ add_library(bluevk STATIC IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(vkshaders STATIC IMPORTED)
set_target_properties(vkshaders PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libvkshaders.a)
if (FILAMENT_SUPPORTS_WEBGPU)
add_library(webgpu_dawn STATIC IMPORTED)
set_target_properties(webgpu_dawn PROPERTIES IMPORTED_LOCATION
@@ -134,7 +138,6 @@ target_include_directories(filament-jni PRIVATE
../../filament/backend/include
../../third_party/robin-map
../../third_party/perfetto
../../libs/bluevk/include
../../libs/utils/include)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
@@ -162,15 +165,10 @@ target_link_libraries(filament-jni
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
)
# Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
if (FILAMENT_SUPPORTS_VULKAN)
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=1)
else()
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=0)
endif()

View File

@@ -557,8 +557,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
jboolean disableHandleUseAfterFreeCheck,
jint preferredShaderLanguage,
jboolean forceGLES2Context, jboolean assertNativeWindowIsValid,
jint gpuContextPriority,
jlong sharedUboInitialSizeInBytes) {
jint gpuContextPriority) {
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
Engine::Config config = {
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
@@ -577,7 +576,6 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
.forceGLES2Context = (bool) forceGLES2Context,
.assertNativeWindowIsValid = (bool) assertNativeWindowIsValid,
.gpuContextPriority = (Engine::GpuContextPriority) gpuContextPriority,
.sharedUboInitialSizeInBytes = (uint32_t) sharedUboInitialSizeInBytes,
};
builder->config(&config);
}

View File

@@ -25,7 +25,7 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality, jint uboBatchingMode) {
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size);
auto builder = Material::Builder();
@@ -33,7 +33,6 @@ Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
builder.sphericalHarmonicsBandCount(shBandCount);
}
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
builder.uboBatching((Material::UboBatchingMode)uboBatchingMode);
Material* material = builder
.package(buffer.getData(), buffer.getSize())
.build(*engine);
@@ -280,17 +279,6 @@ Java_com_google_android_filament_Material_nHasParameter(JNIEnv* env, jclass,
return (jboolean) hasParameter;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_Material_nGetParameterTransformName(JNIEnv* env, jclass,
jlong nativeMaterial, jstring samplerName_) {
Material* material = (Material*) nativeMaterial;
const char* samplerName = env->GetStringUTFChars(samplerName_, 0);
const char* transformName = material->getParameterTransformName(samplerName);
jstring transformName_ = env->NewStringUTF(transformName ? transformName : "");
env->ReleaseStringUTFChars(samplerName_, samplerName);
return transformName_;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Material_nCompile(JNIEnv *env, jclass clazz,

View File

@@ -63,14 +63,6 @@ Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
builder->color({r, g, b, a});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nBuilderPriority(JNIEnv *, jclass,
jlong nativeSkyBoxBuilder, jint priority) {
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
builder->priority(uint8_t(priority));
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeSkyBoxBuilder, jlong nativeEngine) {

View File

@@ -21,11 +21,6 @@
#ifdef __ANDROID__
#include <android/bitmap.h>
#include <android/hardware_buffer_jni.h>
#include <backend/platforms/PlatformEGLAndroid.h>
# if FILAMENT_SUPPORTS_VULKAN
# include <backend/platforms/VulkanPlatformAndroid.h>
# endif
#endif
#include <filament/Engine.h>
@@ -393,57 +388,6 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon
texture->setExternalImage(*engine, (void*)eglImage);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nSetExternalImageByAHB(JNIEnv *env, jclass clazz,
jlong nativeTexture, jlong nativeEngine, jobject ahb) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
#ifdef __ANDROID__
Platform* platform = engine->getPlatform();
AHardwareBuffer* nativeBuffer = nullptr;
if (__builtin_available(android 26, *)) {
nativeBuffer = AHardwareBuffer_fromHardwareBuffer(env, ahb);
}
if (!nativeBuffer) {
// either we're not on Android 26, or ahb wasn't a AHardwareBuffer
return JNI_FALSE;
}
if (engine->getBackend() == Backend::OPENGL) {
// CAVEAT: we assume that Backend::OPENGL on Android implies PlatformEGLAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<PlatformEGLAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* eglPlatform = (PlatformEGLAndroid*) platform;
auto ref = eglPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#if FILAMENT_SUPPORTS_VULKAN
else if (engine->getBackend() == Backend::VULKAN) {
// CAVEAT: we assume that Backend::VULKAN on Android implies VulkanPlatformAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<VulkanPlatformAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* vulkanPlatform = (VulkanPlatformAndroid*) platform;
auto ref = vulkanPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#endif // FILAMENT_SUPPORTS_VULKAN
// success!
return JNI_TRUE;
#else
// other platforms could come here
return JNI_FALSE;
#endif // __ANDROID__
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
@@ -663,4 +607,3 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
}
#endif

View File

@@ -147,15 +147,6 @@ Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jcla
view->setDynamicResolutionOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nGetLastDynamicResolutionScale(JNIEnv *env, jclass, jlong nativeView, jfloatArray out_) {
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
View *view = (View *) nativeView;
math::float2 result = view->getLastDynamicResolutionScale();
std::copy_n(result.v, 2, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
View* view = (View*) nativeView;

View File

@@ -99,15 +99,6 @@ final class Asserts {
}
}
@NonNull @Size(min = 2)
static float[] assertFloat2(@Nullable float[] out) {
if (out == null) out = new float[2];
else if (out.length < 2) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 2");
}
return out;
}
@NonNull @Size(min = 4)
static float[] assertFloat4(@Nullable float[] out) {
if (out == null) out = new float[4];

View File

@@ -264,8 +264,7 @@ public class Engine {
config.disableHandleUseAfterFreeCheck,
config.preferredShaderLanguage.ordinal(),
config.forceGLES2Context, config.assertNativeWindowIsValid,
config.gpuContextPriority.ordinal(),
config.sharedUboInitialSizeInBytes);
config.gpuContextPriority.ordinal());
return this;
}
@@ -526,16 +525,6 @@ public class Engine {
* GPU context priority level. Controls GPU work scheduling and preemption.
*/
public GpuContextPriority gpuContextPriority = GpuContextPriority.DEFAULT;
/**
* The initial size in bytes of the shared uniform buffer used for material instance batching.
*
* If the buffer runs out of space during a frame, it will be automatically reallocated
* with a larger capacity. Setting an appropriate initial size can help avoid runtime
* reallocations, which can cause a minor performance stutter, at the cost of higher
* initial memory usage.
*/
public long sharedUboInitialSizeInBytes = 256 * 64;
}
private Engine(long nativeEngine, Config config) {
@@ -1540,8 +1529,7 @@ public class Engine {
boolean disableHandleUseAfterFreeCheck,
int preferredShaderLanguage,
boolean forceGLES2Context, boolean assertNativeWindowIsValid,
int gpuContextPriority,
long sharedUboInitialSizeInBytes);
int gpuContextPriority);
private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal);
private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext);
private static native void nSetBuilderPaused(long nativeBuilder, boolean paused);

View File

@@ -261,20 +261,6 @@ public class Material {
LOW
}
/**
* Defines whether a material instance should use UBO batching or not.
*/
public enum UboBatchingMode {
/**
* For default, it follows the engine settings.
* If UBO batching is enabled on the engine and the material domain is SURFACE, it
* turns on the UBO batching. Otherwise, it turns off the UBO batching.
*/
DEFAULT,
/** Disable the Ubo Batching for this material */
DISABLED
}
public static class UserVariantFilterBit {
/** Directional lighting */
public static int DIRECTIONAL_LIGHTING = 0x01;
@@ -386,7 +372,6 @@ public class Material {
private int mSize;
private int mShBandCount = 0;
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
private UboBatchingMode mUboBatchingMode = UboBatchingMode.DEFAULT;
/**
@@ -431,17 +416,6 @@ public class Material {
return this;
}
/**
* Set the batching mode of the instances created from this material.
* @param uboBatchingMode
* @return Reference to this Builder for chaining calls.
*/
@NonNull
public Builder uboBatching(UboBatchingMode mode) {
mUboBatchingMode = mode;
return this;
}
/**
* Creates and returns the Material object.
*
@@ -454,7 +428,7 @@ public class Material {
@NonNull
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal(), mUboBatchingMode.ordinal());
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal());
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial);
}
@@ -813,21 +787,6 @@ public class Material {
return nHasParameter(getNativeObject(), name);
}
/**
*
* Returns the name of the transform parameter associated with the given sampler parameter.
* In the case the parameter doesn't have a transform name field, it will return an empty string.
*
* @param samplerName the name of the sampler parameter to query.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:parameters">
* General: parameters</a>
*/
public String getParameterTransformName(@NonNull String samplerName) {
return nGetParameterTransformName(getNativeObject(), samplerName);
}
/**
* Sets the value of a bool parameter on this material's default instance.
*
@@ -1120,7 +1079,7 @@ public class Material {
mNativeObject = 0;
}
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality, int uboBatchingMode);
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);
@@ -1152,5 +1111,4 @@ public class Material {
private static native int nGetRequiredAttributes(long nativeMaterial);
private static native boolean nHasParameter(long nativeMaterial, @NonNull String name);
private static native String nGetParameterTransformName(long nativeMaterial, @NonNull String samplerName);
}

View File

@@ -155,24 +155,6 @@ public class Skybox {
return this;
}
/**
* Set the rendering priority of the Skybox. By default, it is set to the lowest
* priority (7) such that the Skybox is always rendered after the opaque objects,
* to reduce overdraw when depth culling is enabled.
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see RenderableManager.Builder#priority
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/**
* Creates a <code>Skybox</code> object
*
@@ -280,7 +262,6 @@ public class Skybox {
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a);
private static native void nBuilderPriority(long nativeSkyboxBuilder, int priority);
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
private static native int nGetLayerMask(long nativeSkybox);

View File

@@ -71,16 +71,6 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
*/
public class Texture {
private static Class<?> HardwareBufferClass = null;
static {
try {
HardwareBufferClass = Class.forName("android.hardware.HardwareBuffer");
} catch (ClassNotFoundException ignored) {
}
}
private static final Sampler[] sSamplerValues = Sampler.values();
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
@@ -1182,38 +1172,6 @@ public class Texture {
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
}
/**
* Specifies the external image to associate with this <code>Texture</code>.
*
* <p>Typically, the external image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:</p>
* <ul>
* <li> only the level of detail (lod) 0 can be specified</li>
* <li> only nearest or linear filtering is supported</li>
* <li> the size and format of the texture is defined by the external image</li>
* <li> only the CLAMP_TO_EDGE wrap mode is supported</li>
* </ul>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
* @param externalImageRef An OS specific Object. On Android it must be a
* <code>android.hardware.HardwareBuffer</code>
*/
public void setExternalImage(@NonNull Engine engine, Object externalImageRef) {
if (HardwareBufferClass != null) {
if (!HardwareBufferClass.isInstance(externalImageRef)) {
throw new IllegalArgumentException("externalImageRef must be a AHardwareBuffer");
}
if (!nSetExternalImageByAHB(getNativeObject(), engine.getNativeObject(), externalImageRef)) {
throw new IllegalStateException("Error setting AHardwareBuffer as external image");
}
} else {
throw new UnsupportedOperationException(
"setExternalImage(Engine, Object) not supported on this platform");
}
}
/**
* Specifies the external stream to associate with this <code>Texture</code>.
*
@@ -1406,8 +1364,6 @@ public class Texture {
private static native void nSetExternalImage(
long nativeObject, long nativeEngine, long eglImage);
private static native boolean nSetExternalImageByAHB(long nativeTexture, long nativeObject, Object ahb);
private static native void nSetExternalStream(long nativeTexture,
long nativeEngine, long nativeStream);

View File

@@ -294,8 +294,8 @@ public class TextureSampler {
/**
* This controls anisotropic filtering.
*
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 1.
* The maximum permissible value is 128.
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 0.
* The maximum permissible value is 7.
*/
public void setAnisotropy(float anisotropy) {
mSampler = nSetAnisotropy(mSampler, anisotropy);

View File

@@ -25,6 +25,7 @@ import java.util.EnumSet;
import static com.google.android.filament.Asserts.assertFloat3In;
import static com.google.android.filament.Asserts.assertFloat4In;
import static com.google.android.filament.Colors.LinearColor;
import com.google.android.filament.proguard.UsedByNative;
@@ -673,21 +674,6 @@ public class View {
return mDynamicResolution;
}
/**
* Returns the last dynamic resolution scale factor used by this view. This value is updated
* when Renderer::render(View*) is called
* @param out A 2-float array where the value will be stored, or null in which case the array is
* allocated.
* @return A 2-float array containing the horizontal and the vertical scale factors
* @see Renderer#render(View)
*/
@NonNull @Size(min = 2)
public float[] getLastDynamicResolutionScale(@Nullable @Size(min = 2) float[] out) {
out = Asserts.assertFloat2(out);
nGetLastDynamicResolutionScale(getNativeObject(), out);
return out;
}
/**
* Sets the rendering quality for this view (e.g. color precision).
*
@@ -1331,7 +1317,6 @@ public class View {
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 minScale, float maxScale, float sharpness, int quality);
private static native void nGetLastDynamicResolutionScale(long nativeView, float[] out);
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetShadowType(long nativeView, int type);
@@ -2041,6 +2026,10 @@ public class View {
* use an AABB neighborhood
*/
AABB,
/**
* use the variance of the neighborhood (not recommended)
*/
VARIANCE,
/**
* use both AABB and variance
*/
@@ -2071,7 +2060,7 @@ public class View {
}
/**
* @deprecated has no effect.
* reconstruction filter width typically between 1 (sharper) and 2 (smoother)
*/
public float filterWidth = 1.0f;
/**
@@ -2091,9 +2080,9 @@ public class View {
*/
public boolean enabled = false;
/**
* Upscaling factor. Disables Dynamic Resolution. [BETA]
* 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
*/
public float upscaling = 1.0f;
public boolean upscaling = false;
/**
* whether to filter the history buffer
*/
@@ -2106,10 +2095,6 @@ public class View {
* whether to use the YcoCg color-space for history rejection
*/
public boolean useYCoCg = false;
/**
* set to true for HDR content
*/
public boolean hdr = true;
/**
* type of color gamut box
*/

View File

@@ -16,9 +16,6 @@
package com.google.android.filament.utils
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.view.Surface
import android.view.SurfaceView
@@ -29,7 +26,6 @@ import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
import java.nio.ByteBuffer
private const val kNearPlane = 0.05f // 5 cm
private const val kFarPlane = 1000.0f // 1 km
@@ -123,8 +119,6 @@ class ModelViewer(
private val target = DoubleArray(3)
private val upward = DoubleArray(3)
private var debugFrameCallback: ((Bitmap) -> Unit)? = null
init {
renderer = engine.createRenderer()
scene = engine.createScene()
@@ -311,39 +305,10 @@ class ModelViewer(
// Render the scene, unless the renderer wants to skip the frame.
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
debugFrameCallback?.let {
val viewport = view.viewport
val bitmap = Bitmap.createBitmap(viewport.width, viewport.height,
Bitmap.Config.ARGB_8888)
val buffer = ByteBuffer.allocateDirect(viewport.width * viewport.height * 4)
val handler = Handler(Looper.getMainLooper())
val pixelBufferDescriptor = Texture.PixelBufferDescriptor(buffer,
Texture.Format.RGBA, Texture.Type.UBYTE, 1, 0, 0, 0, handler) {
buffer.rewind()
bitmap.copyPixelsFromBuffer(buffer)
it(bitmap)
}
renderer.readPixels(viewport.left, viewport.bottom, viewport.width,
viewport.height, pixelBufferDescriptor)
debugFrameCallback = null
}
renderer.endFrame()
}
}
/*
* Sets a callback that will be invoked with the next rendered frame as a Bitmap. Note that this
* is a one-time callback.
*
* @param callback callback to be invoked with a rendered frame as [Bitmap]
*/
fun debugGetNextFrameCallback(callback: (Bitmap) -> Unit) {
debugFrameCallback = callback
}
private fun populateScene(asset: FilamentAsset) {
val rcm = engine.renderableManager
var count = 0

View File

@@ -40,21 +40,7 @@ fun loadTexture(engine: Engine, resources: Resources, resourceId: Int, type: Tex
options.inPremultiplied = type == TextureType.COLOR
val bitmap = BitmapFactory.decodeResource(resources, resourceId, options)
return buildTexture(engine, bitmap, type)
}
fun loadTexture(engine: Engine, bytes: ByteArray, type: TextureType, offset: Int = 0, length: Int = bytes.size): Texture {
val options = BitmapFactory.Options()
// Color is the only type of texture we want to pre-multiply with the alpha channel
// Pre-multiplication is the default behavior, so we need to turn it off here
options.inPremultiplied = type == TextureType.COLOR
val bitmap = BitmapFactory.decodeByteArray(bytes, offset, length, options)
return buildTexture(engine, bitmap, type)
}
private fun buildTexture(engine: Engine, bitmap: Bitmap, type: TextureType): Texture {
val texture = Texture.Builder()
.width(bitmap.width)
.height(bitmap.height)

View File

@@ -22,7 +22,6 @@ object Utils {
/**
* Initializes the utils JNI layer. Must be called before using any utils functionality.
*/
@JvmStatic
fun init() {
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
Filament.init()

View File

@@ -6,7 +6,6 @@ option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support on Android" OFF)
set(CMAKE_CXX_STANDARD 20)
@@ -31,12 +30,6 @@ add_library(stb STATIC IMPORTED)
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_library(webpdecoder STATIC IMPORTED)
set_target_properties(webpdecoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libwebpdecoder.a)
endif()
add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
@@ -88,10 +81,6 @@ set(GLTFIO_INCLUDE_DIRS
../../libs/ktxreader/include
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
list(APPEND GLTFIO_INCLUDE_DIRS ../../third_party/libwebp/src)
endif()
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
@@ -118,6 +107,3 @@ target_link_libraries(gltfio-jni
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE log # needed only when perfetto above is used
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
target_link_libraries(gltfio-jni PRIVATE webpdecoder)
endif()

View File

@@ -128,18 +128,6 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEn
return (jlong) createKtx2Provider(engine);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nIsWebpSupported(JNIEnv*, jclass) {
return (jboolean) isWebpSupported();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateWebpProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createWebpProvider(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
jlong nativeProvider) {

View File

@@ -37,7 +37,6 @@ public class ResourceLoader {
private final long mNativeObject;
private final long mNativeStbProvider;
private final long mNativeKtx2Provider;
private final long mNativeWebpProvider;
/**
* Constructs a resource loader tied to the given Filament engine.
@@ -51,17 +50,9 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -77,17 +68,9 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -97,9 +80,6 @@ public class ResourceLoader {
nDestroyResourceLoader(mNativeObject);
nDestroyTextureProvider(mNativeStbProvider);
nDestroyTextureProvider(mNativeKtx2Provider);
if (nIsWebpSupported()) {
nDestroyTextureProvider(mNativeWebpProvider);
}
}
/**
@@ -211,9 +191,6 @@ public class ResourceLoader {
private static native long nCreateStbProvider(long nativeEngine);
private static native long nCreateKtx2Provider(long nativeEngine);
private static native boolean nIsWebpSupported();
private static native long nCreateWebpProvider(long nativeEngine);
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
private static native void nDestroyTextureProvider(long nativeProvider);
}

View File

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

View File

@@ -80,12 +80,54 @@ frame and the external texture are perfectly synchronized.
![Stream Test](../../docs/images/samples/sample_stream_test.jpg)
## Building Samples
## Prerequisites
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
compile Filament's native library and Filament's AAR for this project. The easiest way to proceed
is to install all the required dependencies and to run the following commands at the root of the
source tree.
source tree:
To build the samples, please follow the steps described in [BUILDING.md](../../BUILDING.md#android)
```shell
./build.sh -p desktop -i release
./build.sh -p android release
```
This will build all the native components and the AAR required by this sample application.
If you do not use the build script, you must set the `filament_tools_dir` property when invoking
Gradle, either from the command line or from `local.properties`. This property must point to the
distribution/install directory for desktop (produced by make/ninja install). This directory must
contain `bin/matc` and `bin/cmgen`.
Example:
```shell
./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
```
## Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
## Compiling
### Android Studio
You must use the latest stable release of Android Studio. To open the project, point Studio to the
`android` folder. After opening the project and syncing to gradle, select the sample of your choice
using the drop-down widget in the toolbar.
To compile and run each sample make sure you have selected the appropriate build variant
(arm7, arm8, x86 or x86_64). If you are not sure you can simply select the "universal"
variant which includes all the other ones.
### Command Line
From the `android` directory in the project root:
```shell
./gradlew :samples:sample-hello-triangle:installDebug
```
Replace `sample-hello-triangle` with your preferred project.

View File

@@ -17,20 +17,12 @@ filamentTools {
}
// don't forget to update MainACtivity.kt when/if changing this.
tasks.register('copyDamagedHelmetGltf', Copy) {
from file("../../../third_party/models/DamagedHelmet/DamagedHelmet.glb")
into file("src/main/assets/models")
rename {String fileName -> "helmet.glb"}
}
// don't forget to update MainACtivity.kt when/if changing this.
tasks.register('copyBusterGltf', Copy) {
tasks.register('copyMesh', Copy) {
from "../../../third_party/models/BusterDrone"
into "src/main/assets/models"
}
preBuild.dependsOn copyDamagedHelmetGltf
preBuild.dependsOn copyBusterGltf
preBuild.dependsOn copyMesh
clean.doFirst {
delete "src/main/assets"

View File

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

View File

@@ -1,52 +0,0 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}
clean.doFirst {
delete "src/main/assets"
}
android {
namespace 'com.google.android.filament.materialinstancestress'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.materialinstancestress"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {
includeInApk = false
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<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:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,532 +0,0 @@
/*
* Copyright (C) 2025 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.materialinstancestress
import android.animation.ValueAnimator
import android.app.Activity
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
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()
}
private const val NUM_CUBES = 1000
private const val GRID_SIZE = 10
private const val SPACING = 2.5f
}
// 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
// DisplayHelper is provided by Filament to manage the display
private lateinit var displayHelper: DisplayHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
private lateinit var material: Material
private lateinit var vertexBuffer: VertexBuffer
private lateinit var indexBuffer: IndexBuffer
// Filament entity representing a renderable object
@Entity private val renderables = IntArray(NUM_CUBES)
private val materialInstances = arrayOfNulls<MaterialInstance>(NUM_CUBES)
private val translationMatrices = Array(NUM_CUBES) { FloatArray(16) }
@Entity private var light = 0
// A swap chain is Filament's representation of a surface
private var swapChain: SwapChain? = null
private var cameraRadius = 42.7f // Initial distance (calculated from original 15Y, 40Z)
private var cameraTheta = 0.0f // Azimuth (horizontal) in radians
private var cameraPhi = 0.358f // Elevation (vertical) in radians (from original 15Y, 40Z)
private var mLastX = 0.0f
private var mLastY = 0.0f
private val DRAG_SPEED = 0.005f
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private val animatorListener = object : ValueAnimator.AnimatorUpdateListener {
// Pre-allocate matrix to avoid GC churn
private val transformMatrix = FloatArray(16)
override fun onAnimationUpdate(a: ValueAnimator) {
val tcm = engine.transformManager
val time = a.animatedFraction // 0.0 to 1.0
// Calculate the sine wave scale factor.
// sin(time * 2 * PI) oscillates between -1.0 and 1.0.
// We multiply by 0.5f (so it's -0.5 to 0.5) and add 1.0f.
// This makes the final 'scale' oscillate between 0.5 and 1.5.
val scale = 1.0f + sin(time * 2.0 * Math.PI).toFloat() * 0.5f
val localScale = (scale - 0.5f) * 0.5f + 0.5f
for (i in 0 until NUM_CUBES) {
val inst = tcm.getInstance(renderables[i])
val materialInst = materialInstances[i] ?: continue
// Get the cube's base position from its stored matrix
// The translation is in elements 12 (x), 13 (y), and 14 (z)
val baseX = translationMatrices[i][12]
val baseY = translationMatrices[i][13]
val baseZ = translationMatrices[i][14]
// Set the transformMatrix to a new translation matrix,
// scaled from the center (0,0,0)
Matrix.setIdentityM(transformMatrix, 0)
Matrix.translateM(transformMatrix, 0,
baseX * scale,
baseY * scale,
baseZ * scale)
Matrix.scaleM(transformMatrix, 0, localScale, localScale, localScale)
tcm.setTransform(inst, transformMatrix)
// Vary roughness
val roughness = 0.5f + 0.5f * sin(time * 2.0 * Math.PI + i * 0.1).toFloat()
materialInst.setParameter("roughness", roughness)
// Vary color (using linear RGB)
val r = 0.5f + 0.5f * cos(time * 2.0 * Math.PI + i * 0.5).toFloat()
val g = 0.5f + 0.5f * sin(time * 2.0 * Math.PI + i * 0.3).toFloat()
val b = 0.5f + 0.5f * cos(time * 2.0 * Math.PI + i * 0.1).toFloat()
materialInst.setParameter("baseColor", Colors.RgbType.LINEAR, r, g, b)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
surfaceView.setOnTouchListener(touchListener)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this)
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine)
view.camera = camera
view.scene = scene
}
private fun setupScene() {
loadMaterial()
createMesh()
val tcm = engine.transformManager
val center = (GRID_SIZE - 1) * 0.5f
for (i in 0 until NUM_CUBES) {
// Calculate grid position
val x = (i % GRID_SIZE) - center
val y = ((i / GRID_SIZE) % GRID_SIZE) - center
val z = (i / (GRID_SIZE * GRID_SIZE)) - center
val posX = x * SPACING
val posY = y * SPACING
val posZ = z * SPACING
// Create material instance for this cube
materialInstances[i] = material.createInstance()
// Set initial parameters (will be overwritten by animator, but good practice)
materialInstances[i]?.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
materialInstances[i]?.setParameter("metallic", 0.0f)
materialInstances[i]?.setParameter("roughness", 0.3f)
// Create the renderable entity
renderables[i] = EntityManager.get().create()
// Create the renderable component
RenderableManager.Builder(1)
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f))
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 6 * 6)
.material(0, materialInstances[i]!!)
.build(engine, renderables[i])
// Add to scene
scene.addEntity(renderables[i])
// Set its initial transform
// Store the base translation matrix
Matrix.setIdentityM(translationMatrices[i], 0)
Matrix.translateM(translationMatrices[i], 0, posX, posY, posZ)
// Get the transform component instance
val inst = tcm.getInstance(renderables[i])
tcm.setTransform(inst, translationMatrices[i])
}
// We now need a light, let's create a directional light
light = EntityManager.get().create()
val (r, g, b) = Colors.cct(5_500.0f)
LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(r, g, b)
.intensity(110_000.0f)
.direction(0.0f, -0.5f, -1.0f)
.castShadows(true)
.build(engine, light)
scene.addEntity(light)
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
updateCamera()
startAnimation()
}
private fun loadMaterial() {
readUncompressedAsset("materials/lit.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
private fun createMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + 4 * floatSize
// A vertex is a position + a tangent frame:
// 3 floats for XYZ position, 4 floats for normal+tangents (quaternion)
@Suppress("ArrayInDataClass")
data class Vertex(val x: Float, val y: Float, val z: Float, val tangents: FloatArray)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
v.tangents.forEach { putFloat(it) }
return this
}
// 6 faces, 4 vertices per face
val vertexCount = 6 * 4
// Create tangent frames, one per face
val tfPX = FloatArray(4)
val tfNX = FloatArray(4)
val tfPY = FloatArray(4)
val tfNY = FloatArray(4)
val tfPZ = FloatArray(4)
val tfNZ = FloatArray(4)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, tfPX)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, tfNX)
MathUtils.packTangentFrame(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, tfPY)
MathUtils.packTangentFrame(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, tfNY)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, tfPZ)
MathUtils.packTangentFrame( 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, tfNZ)
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
// It is important to respect the native byte order
.order(ByteOrder.nativeOrder())
// Face -Z
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNZ))
.put(Vertex(-1.0f, 1.0f, -1.0f, tfNZ))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfNZ))
.put(Vertex( 1.0f, -1.0f, -1.0f, tfNZ))
// Face +X
.put(Vertex( 1.0f, -1.0f, -1.0f, tfPX))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfPX))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPX))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfPX))
// Face +Z
.put(Vertex(-1.0f, -1.0f, 1.0f, tfPZ))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfPZ))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPZ))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfPZ))
// Face -X
.put(Vertex(-1.0f, -1.0f, 1.0f, tfNX))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfNX))
.put(Vertex(-1.0f, 1.0f, -1.0f, tfNX))
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNX))
// Face -Y
.put(Vertex(-1.0f, -1.0f, 1.0f, tfNY))
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNY))
.put(Vertex( 1.0f, -1.0f, -1.0f, tfNY))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfNY))
// Face +Y
.put(Vertex(-1.0f, 1.0f, -1.0f, tfPY))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfPY))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPY))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfPY))
// Make sure the cursor is pointing in the right place in the byte buffer
.flip()
// Declare the layout of our mesh
vertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
// Because we interleave position and color data we must specify offset and stride
// We could use de-interleaved data by declaring two buffers and giving each
// attribute a different buffer index
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.TANGENTS, 0, AttributeType.FLOAT4, 3 * floatSize, vertexSize)
.build(engine)
// Feed the vertex data to the mesh
// We only set 1 buffer because the data is interleaved
vertexBuffer.setBufferAt(engine, 0, vertexData)
// Create the indices
val indexData = ByteBuffer.allocate(6 * 2 * 3 * shortSize)
.order(ByteOrder.nativeOrder())
repeat(6) {
val i = (it * 4).toShort()
indexData
.putShort(i).putShort((i + 1).toShort()).putShort((i + 2).toShort())
.putShort(i).putShort((i + 2).toShort()).putShort((i + 3).toShort())
}
indexData.flip()
// 6 faces, 2 triangles per face,
indexBuffer = IndexBuffer.Builder()
.indexCount(vertexCount * 2)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
indexBuffer.setBuffer(engine, indexData)
}
private fun updateCamera() {
// Calculate eye position from spherical coordinates
val eyeY = cameraRadius * sin(cameraPhi)
val horizontalRadius = cameraRadius * cos(cameraPhi)
val eyeX = horizontalRadius * sin(cameraTheta)
val eyeZ = horizontalRadius * cos(cameraTheta)
// Point the camera at the center (0,0,0)
camera.lookAt(eyeX.toDouble(), eyeY.toDouble(), eyeZ.toDouble(), // eye
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.0) // up
}
private val touchListener = object : android.view.View.OnTouchListener {
override fun onTouch(v: android.view.View?, event: android.view.MotionEvent?): Boolean {
if (event == null) return false
when (event.action) {
android.view.MotionEvent.ACTION_DOWN -> {
mLastX = event.x
mLastY = event.y
return true
}
android.view.MotionEvent.ACTION_MOVE -> {
val dx = event.x - mLastX
val dy = event.y - mLastY
cameraTheta -= dx * DRAG_SPEED
cameraPhi += dy * DRAG_SPEED
// Clamp vertical angle to avoid flipping over
cameraPhi = cameraPhi.coerceIn(-1.5f, 1.5f)
updateCamera()
mLastX = event.x
mLastY = event.y
return true
}
}
return v?.onTouchEvent(event) ?: false
}
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 6000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener(animatorListener)
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()
// Stop the animation and any pending frame
choreographer.removeFrameCallback(frameScheduler)
animator.cancel();
// Always detach the surface before destroying the engine
uiHelper.detach()
// Cleanup all resources
engine.destroyEntity(light)
// Destroy all 1000 entities and material instances
for (i in 0 until NUM_CUBES) {
engine.destroyEntity(renderables[i])
materialInstances[i]?.let { engine.destroyMaterialInstance(it) }
}
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(vertexBuffer)
engine.destroyIndexBuffer(indexBuffer)
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
for (entity in renderables) {
entityManager.destroy(entity)
}
entityManager.destroy(camera.entity)
// 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!!, frameTimeNanos)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
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, 100.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
}

View File

@@ -1,53 +0,0 @@
// Simple lit material that defines 3 parameters:
// - baseColor
// - roughness
// - metallic
//
// These parameters can be used by the application to change the appearance of the material.
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -o app/src/main/assets/lit.filamat app/src/materials/lit.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.
material {
name : lit,
// Dynamic lighting is enabled on this material
shadingModel : lit,
// We don't need to declare a "requires" array, lit materials
// always requires the "tangents" vertex attribute (the normal
// is required for lighting, tangent/bitangent for normal mapping
// and anisotropy)
// List of parameters exposed by this material
parameters : [
// The color must be passed in linear space, not sRGB
{
type : float3,
name : baseColor
},
{
type : float,
name : roughness
},
{
type : float,
name : metallic
}
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// Nothing fancy here, we simply copy the parameters
material.baseColor.rgb = materialParams.baseColor;
material.roughness = materialParams.roughness;
material.metallic = materialParams.metallic;
}
}

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

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

View File

@@ -1,3 +0,0 @@
<resources>
<string name="app_name">Material Instance Stress</string>
</resources>

View File

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

View File

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

View File

@@ -1,53 +0,0 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}
clean.doFirst {
delete "src/main/assets"
}
android {
namespace 'com.google.android.filament.texturetarget'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.texturetarget"
minSdkVersion 26
targetSdkVersion versions.targetSdk
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {
includeInApk = false
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<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:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,449 +0,0 @@
/*
* Copyright (C) 2024 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.texturetarget
import android.animation.ValueAnimator
import android.app.Activity
import android.hardware.HardwareBuffer
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
companion object {
init {
Filament.init()
}
}
private lateinit var surfaceView: SurfaceView
private lateinit var uiHelper: UiHelper
private lateinit var displayHelper: DisplayHelper
private lateinit var choreographer: Choreographer
private lateinit var engine: Engine
private lateinit var renderer: Renderer
private lateinit var scene: Scene
private lateinit var view: View
private lateinit var camera: Camera
private lateinit var triangleMaterial: Material
private lateinit var texturedMaterial: Material
private lateinit var triangleVertexBuffer: VertexBuffer
private lateinit var triangleIndexBuffer: IndexBuffer
private lateinit var quadVertexBuffer: VertexBuffer
private lateinit var quadIndexBuffer: IndexBuffer
@Entity private var triangleRenderable = 0
@Entity private var quadRenderable = 0
private var swapChain: SwapChain? = null
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private var hardwareBuffer: HardwareBuffer? = null
private var texture: Texture? = null
private var renderTarget: RenderTarget? = null
private var useExternalTexture = true
private lateinit var offscreenView: View
private lateinit var offscreenCamera: Camera
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// To use set this flag with adb, run
// adb shell am start -n com.google.android.filament.texturetarget/.MainActivity --ez useExternalTexture false
useExternalTexture = intent.getBooleanExtra("useExternalTexture", true)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this)
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera(engine.entityManager.create())
offscreenView = engine.createView()
offscreenCamera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
scene.skybox = Skybox.Builder()
.priority(0)
.color(0.0f, 0.0f, 1.0f, 1.0f).build(engine)
// This is the view that will be drawn on screen.
view.camera = camera
view.scene = scene
view.isPostProcessingEnabled = false
// This is the view that will be rendered off-screen.
offscreenView.camera = offscreenCamera
offscreenView.scene = scene
offscreenView.isPostProcessingEnabled = false
}
private fun setupScene() {
loadMaterials()
createTriangleMesh()
createQuadMesh()
// layer 1: skybox
// layer 2: triangle
// layer 3: quad
triangleMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
texturedMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
// The triangle is a regular renderable.
triangleRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, triangleVertexBuffer, triangleIndexBuffer, 0, 3)
.material(0, triangleMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 2)
.build(engine, triangleRenderable)
// The quad is a regular renderable.
quadRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, quadVertexBuffer, quadIndexBuffer, 0, 6)
.material(0, texturedMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 4)
.build(engine, quadRenderable)
// We only want to render the triangle in the offscreen view.
offscreenView.setVisibleLayers(7, 3) // render skybox + triangle
// We only want to render the quad in the on-screen view.
view.setVisibleLayers(7, 4) // render quad only
scene.addEntity(triangleRenderable)
scene.addEntity(quadRenderable)
startAnimation()
}
private fun loadMaterials() {
readUncompressedAsset("materials/baked_color.filamat").let {
triangleMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
if (useExternalTexture) {
readUncompressedAsset("materials/texturedExternal.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
} else {
readUncompressedAsset("materials/textured.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
}
private fun createTriangleMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + intSize
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
.flip()
triangleVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
.normalized(VertexAttribute.COLOR)
.build(engine)
triangleVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
triangleIndexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
triangleIndexBuffer.setBuffer(engine, indexData)
}
private fun createQuadMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = (2 * floatSize) + (2 * floatSize) // position + UV
data class Vertex(val x: Float, val y: Float, val u: Float, val v: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.u)
putFloat(v.v)
return this
}
val vertexCount = 4
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(-1.0f, -1.0f, 0.0f, 0.0f))
.put(Vertex( 1.0f, -1.0f, 1.0f, 0.0f))
.put(Vertex( 1.0f, 1.0f, 1.0f, 1.0f))
.put(Vertex(-1.0f, 1.0f, 0.0f, 1.0f))
.flip()
quadVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT2, 0, vertexSize)
.attribute(VertexAttribute.UV0, 0, AttributeType.FLOAT2, 2 * floatSize, vertexSize)
.build(engine)
quadVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(6 * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0).putShort(1).putShort(2)
.putShort(0).putShort(2).putShort(3)
.flip()
quadIndexBuffer = IndexBuffer.Builder()
.indexCount(6)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
quadIndexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val transformMatrix = FloatArray(16)
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(triangleRenderable), transformMatrix)
}
animator.start()
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
uiHelper.detach()
// Destroy all renderables.
scene.remove(triangleRenderable)
scene.remove(quadRenderable)
// Destroy all resources.
engine.destroyEntity(triangleRenderable)
engine.destroyEntity(quadRenderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(triangleVertexBuffer)
engine.destroyIndexBuffer(triangleIndexBuffer)
engine.destroyVertexBuffer(quadVertexBuffer)
engine.destroyIndexBuffer(quadIndexBuffer)
engine.destroyMaterial(triangleMaterial)
engine.destroyMaterial(texturedMaterial)
engine.destroyView(view)
engine.destroyView(offscreenView)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
engine.destroyCameraComponent(offscreenCamera.entity)
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
val entityManager = EntityManager.get()
entityManager.destroy(triangleRenderable)
entityManager.destroy(quadRenderable)
entityManager.destroy(camera.entity)
entityManager.destroy(offscreenCamera.entity)
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
if (uiHelper.isReadyToRender) {
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
// Render the triangle to the texture.
renderer.render(offscreenView)
// Render the quad to the screen.
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
// On-screen camera
val zoom = 1.0
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO, -aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
// Off-screen camera
val offscreenZoom = 1.5
offscreenCamera.setProjection(Camera.Projection.ORTHO,
-aspect * offscreenZoom, aspect * offscreenZoom,
-offscreenZoom, offscreenZoom, 0.0, 10.0)
offscreenView.viewport = Viewport(0, 0, width, height)
// If we have a render target, destroy it.
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
if (useExternalTexture) {
// Create a new render target.
hardwareBuffer = HardwareBuffer.create(width, height,
HardwareBuffer.RGBA_8888, 1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT)
texture = Texture.Builder()
.width(width)
.height(height)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.sampler(Texture.Sampler.SAMPLER_EXTERNAL)
.format(Texture.InternalFormat.RGBA8)
.external()
.build(engine)
texture!!.setExternalImage(engine, hardwareBuffer!!)
} else {
texture = Texture.Builder()
.width(width)
.height(height)
.levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA8)
.build(engine)
}
renderTarget = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, texture!!)
.build(engine)
offscreenView.renderTarget = renderTarget
// Set the texture on the quad material.
texturedMaterial.defaultInstance.setParameter("texture", texture!!,
TextureSampler(TextureSampler.MinFilter.LINEAR, TextureSampler.MagFilter.LINEAR,
TextureSampler.WrapMode.CLAMP_TO_EDGE))
FilamentHelper.synchronizePendingFrames(engine)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
}

View File

@@ -1,18 +0,0 @@
material {
name : baked_color,
shadingModel : unlit,
requires : [
color
]
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}

View File

@@ -1,20 +0,0 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

@@ -1,20 +0,0 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : samplerExternal,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

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

View File

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

View File

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

View File

@@ -12,12 +12,10 @@ include ':samples:sample-image-based-lighting'
include ':samples:sample-lit-cube'
include ':samples:sample-live-wallpaper'
include ':samples:sample-material-builder'
include ':samples:sample-material-instance-stress'
include ':samples:sample-multi-view'
include ':samples:sample-page-curl'
include ':samples:sample-stream-test'
include ':samples:sample-texture-view'
include ':samples:sample-texture-target'
include ':samples:sample-textured-object'
include ':samples:sample-transparent-view'

View File

@@ -77,10 +77,6 @@ function print_help {
echo " meant for building the samples."
echo " -P"
echo " Enable perfetto traces on Android. Disabled by default on the Release build, enabled otherwise."
echo " -y build_type"
echo " Build the filament dependent tools (matc, resgen) separately from the project. This will set"
echo " the tools as prebuilts that filament target will then use to build. The built_type option"
echo " (debug|release) is meant to indicate the type of build of the resulting prebuilts."
echo ""
echo "Build types:"
echo " release"
@@ -158,7 +154,7 @@ function print_fgviewer_help {
}
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")}
# Internal variables
ISSUE_CLEAN=false
@@ -221,11 +217,6 @@ OSMESA_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
ISSUE_SPLIT_BUILD=false
SPLIT_BUILD_TYPE=""
PREBUILT_TOOLS_DIR=""
IMPORT_EXECUTABLES_DIR_OPTION="-DIMPORT_EXECUTABLES_DIR=out"
BUILD_GENERATOR=Ninja
BUILD_COMMAND=ninja
BUILD_CUSTOM_TARGETS=
@@ -251,37 +242,6 @@ function build_clean_aggressive {
git clean -qfX android
}
function build_tools_for_split_build {
local build_type_arg=$1
local lc_build_type=$(echo "${build_type_arg}" | tr '[:upper:]' '[:lower:]')
PREBUILT_TOOLS_DIR="out/prebuilt-tools-${lc_build_type}"
echo "Building tools for split build (${lc_build_type}) in ${PREBUILT_TOOLS_DIR}..."
mkdir -p "${PREBUILT_TOOLS_DIR}"
pushd "${PREBUILT_TOOLS_DIR}" > /dev/null
local lc_name=$(echo "${UNAME}" | tr '[:upper:]' '[:lower:]')
local architectures=""
if [[ "${lc_name}" == "darwin" ]]; then
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
architectures="-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"
fi
fi
cmake \
-G "${BUILD_GENERATOR}" \
-DFILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR=${PREBUILT_TOOLS_DIR} \
-DCMAKE_BUILD_TYPE="${build_type_arg}" \
${WEBGPU_OPTION} \
${architectures} \
../..
${BUILD_COMMAND} ${WEB_HOST_TOOLS}
popd > /dev/null
}
function build_desktop_target {
local lc_target=$(echo "$1" | tr '[:upper:]' '[:lower:]')
local build_targets=$2
@@ -305,7 +265,7 @@ function build_desktop_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
${EGL_ON_LINUX_OPTION} \
@@ -371,7 +331,7 @@ function build_webgl_with_target {
source "${EMSDK}/emsdk_env.sh"
cmake \
-G "${BUILD_GENERATOR}" \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_TOOLCHAIN_FILE="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../webgl-${lc_target}/filament" \
@@ -444,7 +404,7 @@ function build_android_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DFILAMENT_NDK_VERSION="${FILAMENT_NDK_VERSION}" \
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
@@ -556,14 +516,11 @@ function build_android {
archive_android "Release"
fi
local root_dir=$(pwd)
pushd android > /dev/null
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -576,7 +533,6 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleDebug
@@ -585,7 +541,6 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleDebug
@@ -618,7 +573,6 @@ function build_android {
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -631,7 +585,6 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleRelease
@@ -640,7 +593,6 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleRelease
@@ -686,7 +638,7 @@ function build_ios_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../ios-${lc_target}/filament" \
-DIOS_ARCH="${arch}" \
@@ -858,7 +810,7 @@ function check_debug_release_build {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
case ${opt} in
h)
print_help
@@ -1027,20 +979,6 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
;;
X) OSMESA_OPTION="-DFILAMENT_OSMESA_PATH=${OPTARG}"
;;
y)
ISSUE_SPLIT_BUILD=true
SPLIT_BUILD_TYPE=${OPTARG}
case $(echo "${SPLIT_BUILD_TYPE}" | tr '[:upper:]' '[:lower:]') in
debug|release)
;;
*)
echo "Unknown build type for -y: ${SPLIT_BUILD_TYPE}"
echo "Build type must be one of [debug|release]"
echo ""
exit 1
;;
esac
;;
\?)
echo "Invalid option: -${OPTARG}" >&2
echo ""
@@ -1075,13 +1013,6 @@ done
validate_build_command
if [[ "${ISSUE_SPLIT_BUILD}" == "true" ]]; then
# Capitalize first letter of SPLIT_BUILD_TYPE
SPLIT_BUILD_TYPE_CAPITALIZED="$(echo ${SPLIT_BUILD_TYPE:0:1} | tr '[:lower:]' '[:upper:]')${SPLIT_BUILD_TYPE:1}"
build_tools_for_split_build "${SPLIT_BUILD_TYPE_CAPITALIZED}"
IMPORT_EXECUTABLES_DIR_OPTION="-DFILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR=${PREBUILT_TOOLS_DIR}"
fi
if [[ "${ISSUE_CLEAN}" == "true" ]]; then
build_clean
fi

View File

@@ -18,8 +18,8 @@ if [[ "$GITHUB_WORKFLOW" ]]; then
fi
fi
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=$(cat `dirname $0`/../common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g)
# Unless explicitly specified, NDK version will be set to match exactly the required one
FILAMENT_NDK_VERSION=${GITHUB_NDK_VERSION:-27.0.11718014}
(! grep "${FILAMENT_NDK_VERSION}" `dirname $0`/../../android/build.gradle > /dev/null) &&
echo "Mismatch of NDK versions: want ${FILAMENT_NDK_VERSION} and not found in android/build.gradle" &&

View File

@@ -34,11 +34,6 @@ if [[ "$TARGET" == "presubmit" ]]; then
BUILD_RELEASE=release
fi
if [[ "$TARGET" == "presubmit-with-test" ]]; then
BUILD_RELEASE=release
RUN_TESTS=-u
fi
if [[ "$TARGET" == "debug" ]]; then
BUILD_DEBUG=debug
GENERATE_ARCHIVES=-a

View File

@@ -1,5 +1,6 @@
libs/viewer/test_settings
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100:RenderingTest.*
filament/test/test_material_parser
libs/math/test_math
libs/image/test_image compare libs/image/tests/reference/
libs/utils/test_utils

View File

@@ -3,7 +3,7 @@ GITHUB_CMAKE_VERSION=3.22.1
GITHUB_NINJA_VERSION=1.10.2
GITHUB_MESA_VERSION=24.2.1
GITHUB_LLVM_VERSION=16
GITHUB_NDK_VERSION=29.0.14206865
GITHUB_NDK_VERSION=27.0.11718014
GITHUB_EMSDK_VERSION=3.1.60
GITHUB_VULKANSDK_VERSION=1.4.321.0
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f

View File

@@ -75,7 +75,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# C_FLAGS += -Wl,-pie
# CXX_FLAGS += -lstdc++
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -march=armv8-a -mtune=cortex-a78" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -mcpu=cortex-a57" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")

View File

@@ -87,7 +87,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# for hardfp: CFLAGS must have -mhard-float
# LDFLAGS must have -Wl,--no-warn-mismatch
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mcpu=cortex-a15 -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++ -fPIE -pie" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")

View File

@@ -97,7 +97,6 @@ in table [standardProperties].
**transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is
**ior** | Index of refraction, either for refractive objects or as an alternative to reflectance
**microThickness** | Thickness of the thin layer of refractive objects
**dispersion** | Strength of the dispersion effect for refractive objects, specified as 20/Abbe number
**bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality
**shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material
[Table [standardProperties]: Properties of the standard model]
@@ -127,7 +126,6 @@ The type and range of each property is described in table [standardPropertiesTyp
**absorption** | float3 | [0..n] |
**microThickness** | float | [0..n] |
**thickness** | float | [0..n] |
**dispersion** | float | [0..n] | Realistic values are between [0, 1], with the exception of Rutile, which has a value of 2.04
[Table [standardPropertiesTypes]: Range and type of the standard model's properties]
@@ -155,14 +153,13 @@ The type and range of each property is described in table [standardPropertiesTyp
as-is, which can lead to physically impossible materials, however, this might be desirable
for artistic reasons.
!!! Note: About `thickness`, `microThickness` and `dispersion` for refraction
!!! Note: About `thickness` and `microThickness` for refraction
`thickness` represents the thickness of solid objects in the direction of the normal, for
satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per
vertex. `microThickness` represent the thickness of the thin layer of an object, and can
generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m,
would have a `thickness` of 1 and a `microThickness` of 0.001. Dispersion controls the angular
separation of colors transmitting through a volume, and can be set by a constant value.
Currently `thickness` and `dispersion` are not used when `refractionType` is set to `thin`.
would have a `thickness` of 1 and a `microThickness` of 0.001. Currently `thickness` is not
used when `refractionType` is set to `thin`.
### Base color
@@ -654,26 +651,6 @@ the `refractionType` is set to `solid` and `absorption` coefficients are set.
![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the
bottom of the prism](images/material_thickness.png)
### Dispersion
The dispersion property controls the angular separation of colors transmitting through a relatively
clear volume. It can only be used when `refractionType` is set to `volume`.
Its value is specified as 20/Abbe number. When the value is zero, no dispersion is used.
Table [commonMatDispersion] describes acceptable dispersion values for various types of materials.
Material | Abbe Number (V) | Dispersion (20/V)
--------------------------:|:------------------:|:-----------------
Rutile | 9.8 | 2.04
Polycarbonate | 32 | 0.625
Diamond | 55 | 0.36
Water | 55 | 0.36
Crown Glass | 59 | 0.33
[Table [commonMatDispersion]: Dispersion of common materials]
![Figure [dispersionProperty]: `dispersion` varying from 0.0
(left) to 5.0 (right)](images/materials/dispersion.png)
## Subsurface model
### Thickness
@@ -2299,7 +2276,6 @@ struct MaterialInputs {
float3 absorption; // default float3(0.0, 0.0, 0.0)
float ior; // default: 1.5
float microThickness; // default: 0.0, not available with refractionType "solid"
float dispersion; // default: 0.0, not available with refractionType "thin"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2480,9 +2456,9 @@ type aliases:
**uint2** | uvec2 | A vector of 2 unsigned integers
**uint3** | uvec3 | A vector of 3 unsigned integers
**uint4** | uvec4 | A vector of 4 unsigned integers
**float2** | vec2 | A vector of 2 floats
**float3** | vec3 | A vector of 3 floats
**float4** | vec4 | A vector of 4 floats
**float2** | float2 | A vector of 2 floats
**float3** | float3 | A vector of 3 floats
**float4** | float4 | A vector of 4 floats
**float4x4** | mat4 | A 4x4 float matrix
**float3x3** | mat3 | A 3x3 float matrix

View File

@@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Maven - Filament</title>
<title>Maven Release - Filament</title>
<!-- Custom HTML head -->
@@ -165,8 +165,8 @@ Portal</a>.</p>
<p>To publish under the <code>com.google.android</code> namespace, you'll also need to email
<code>central-support@sonatype.com</code> with your account information to request access.</p>
<p>Then, generate a user token through the Sonatype website. Navigate to
<a href="https://central.sonatype.com/usertoken">https://central.sonatype.com/usertoken</a>
and select <strong>Generate User Token</strong>.</p>
<a href="https://central.sonatype.com/account">https://central.sonatype.com/account</a> and select <strong>Generate
User Token</strong>.</p>
<p>Finally, add the generated token credentials to <code>~/.gradle/gradle.properties</code>. (Note: these are
different from the credentials used to log into your Sonatype account):</p>
<pre><code class="language-gradle"># Generated Sonatype token
@@ -218,11 +218,11 @@ the <strong>Publish</strong> button to publish the artifacts. It typically takes
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../release/cocoapods.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../release/guide.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -232,11 +232,11 @@ the <strong>Publish</strong> button to publish the artifacts. It typically takes
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../release/cocoapods.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../release/guide.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Android on Windows - Filament</title>
<title>Build for Android on Windows - Filament</title>
<!-- Custom HTML head -->
@@ -273,7 +273,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../build/maven_release.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -287,7 +287,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../build/maven_release.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -180,7 +180,7 @@ rm -r Vulkan-Headers-1.3.232 v1.3.232.zip
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/fgviewer.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/filamat.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -194,7 +194,7 @@ rm -r Vulkan-Headers-1.3.232 v1.3.232.zip
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/fgviewer.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/filamat.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -200,12 +200,6 @@ inside the Filament source tree.</p>
force a clean build by adding the <code>-c</code> flag in that case.</p>
<p>To install the libraries and executables in <code>out/debug/</code> and <code>out/release/</code>, add the <code>-i</code> flag.
The script offers more features described by executing <code>build.sh -h</code>.</p>
<p>For more specialized options, please also consider the following pages:</p>
<ul>
<li><code>-d</code>: <a href="https://google.github.io/filament/dup/matdbg.html"><code>matdbg</code></a></li>
<li><code>-t</code>: <a href="https://google.github.io/filament/dup/fgviewer.html"><code>fgviewer</code></a></li>
<li><code>-b</code> and <code>-y</code>: <a href="https://google.github.io/filament/notes/asan_ubsan.html">ASAN/UBSAN builds</a></li>
</ul>
<h3 id="filament-specific-cmake-options"><a class="header" href="#filament-specific-cmake-options">Filament-specific CMake Options</a></h3>
<p>The following CMake options are boolean options specific to Filament:</p>
<ul>
@@ -327,41 +321,12 @@ host tools are required to successfully build for Android.</p>
<p>Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
foremost for <code>arm64-v8a</code>.</p>
<p>To build Android on Windows machines, see <a href="android/Windows.html">android/Windows.md</a>.</p>
<h4 id="important-sdk-location"><a class="header" href="#important-sdk-location">Important: SDK location</a></h4>
<p>Either ensure your <code>ANDROID_HOME</code> environment variable is set or make sure the root project
contains a <code>local.properties</code> file with the <code>sdk.dir</code> property pointing to your installation of
the Android SDK.</p>
<h4 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h4>
<p>The easiest way to build Filament for Android is to use <code>build.sh</code> and the
<code>-p android</code> flag. For instance to build the release target:</p>
<pre><code class="language-shell">./build.sh -p android release
</code></pre>
<p>To build a sample (such as <code>android/samples/sample-hello-triangle</code>) for an ARM 64-bit phone, you would run</p>
<pre><code class="language-shell">./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
</code></pre>
<p>The output APK can be found in <code>android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk</code></p>
<p>Run <code>build.sh -h</code> for more information.</p>
<h4 id="android-studio"><a class="header" href="#android-studio">Android Studio</a></h4>
<p>You must use the latest stable release of Android Studio.</p>
<p>The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.</p>
<p>Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script</p>
<pre><code class="language-shell">./build.sh -p android release -q arm64-v8a
</code></pre>
<p>Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.</p>
<p>Now we are ready to compile the apps. To open the project, point Studio to the <code>android</code> folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (<code>-q arm64-v8a</code> ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (<code>-q x86_64</code>) in the above step.</p>
<h4 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h4>
<p>Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
below show how to build Filament for ARM 64-bit (<code>aarch64</code>).</p>

View File

@@ -209,7 +209,7 @@ as possible. The current external dependencies of the runtime library include:</
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/maven_release.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -223,7 +223,7 @@ as possible. The current external dependencies of the runtime library include:</
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/maven_release.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

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