Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15424c85b5 |
@@ -65,6 +65,4 @@ SpacesInParentheses: false
|
|||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
PackConstructorInitializers: Never
|
PackConstructorInitializers: Never
|
||||||
ConstructorInitializerIndentWidth: 8
|
|
||||||
IndentWrappedFunctionNames: true
|
|
||||||
@@ -1,53 +1,43 @@
|
|||||||
# This action retrieves the latest commit message from a push or pull_request event
|
|
||||||
# and makes it available as an output variable named 'msg'.
|
|
||||||
name: 'Get commit message'
|
name: 'Get commit message'
|
||||||
outputs:
|
outputs:
|
||||||
msg:
|
msg:
|
||||||
value: ${{ steps.action_output.outputs.msg }}
|
value: ${{ steps.action_output.outputs.msg }}
|
||||||
hash:
|
|
||||||
value: ${{ steps.action_output.outputs.hash }}
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Find commit message (on push)
|
- name: Find commit message (on push)
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
shell: bash
|
shell: bash
|
||||||
env:
|
|
||||||
COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
|
|
||||||
run: |
|
run: |
|
||||||
AUTHOR_NAME="${{ github.event.head_commit.author.name }}"
|
AUTHOR_NAME="${{ github.event.head_commit.author.name }}"
|
||||||
AUTHOR_EMAIL="${{ github.event.head_commit.author.email }}"
|
AUTHOR_EMAIL="${{ github.event.head_commit.author.email }}"
|
||||||
TSTAMP="${{ github.event.head_commit.timestamp }}"
|
TSTAMP="${{ github.event.head_commit.timestamp }}"
|
||||||
HASH="${{ github.event.head_commit.id }}"
|
echo "commit ${{ github.event.head_commit.id }}" >> /tmp/commit_msg.txt
|
||||||
echo "commit $HASH" >> /tmp/commit_msg.txt
|
|
||||||
echo "Author: ${AUTHOR_NAME}<${AUTHOR_EMAIL}>" >> /tmp/commit_msg.txt
|
echo "Author: ${AUTHOR_NAME}<${AUTHOR_EMAIL}>" >> /tmp/commit_msg.txt
|
||||||
echo "Date: ${TSTAMP}" >> /tmp/commit_msg.txt
|
echo "Date: ${TSTAMP}" >> /tmp/commit_msg.txt
|
||||||
echo "" >> /tmp/commit_msg.txt
|
echo "" >> /tmp/commit_msg.txt
|
||||||
echo "$COMMIT_MESSAGE" >> /tmp/commit_msg.txt
|
echo "${{ github.event.head_commit.message }}" >> /tmp/commit_msg.txt
|
||||||
echo "$HASH" > /tmp/commit_hash.txt
|
|
||||||
- name: Find commit message (PR)
|
- name: Find commit message (PR)
|
||||||
shell: bash
|
shell: bash
|
||||||
id: checkout_code
|
id: checkout_code
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
run: |
|
run: |
|
||||||
BEFORE_HASH=$(git rev-parse HEAD)
|
echo "+++++ head commit message +++++"
|
||||||
echo "hash=$BEFORE_HASH" >> "$GITHUB_OUTPUT"
|
echo "$(git log -1 --no-merges)"
|
||||||
# Next we will checkout the actual head (not the merge commits) of the PR
|
echo "+++++++++++++++++++++++++++++++"
|
||||||
AFTER_HASH="${{ github.event.pull_request.head.sha }}"
|
echo "hash=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||||
git checkout $AFTER_HASH
|
git checkout ${{ github.event.pull_request.head.sha }}
|
||||||
COMMIT_MESSAGE=$(git log -1 --no-merges)
|
echo "$(git log -1 --no-merges)" >> /tmp/commit_msg.txt
|
||||||
echo "$COMMIT_MESSAGE" > /tmp/commit_msg.txt
|
|
||||||
echo "$AFTER_HASH" > /tmp/commit_hash.txt
|
|
||||||
- shell: bash
|
- shell: bash
|
||||||
id: action_output
|
id: action_output
|
||||||
run: |
|
run: |
|
||||||
# Get the commit message
|
|
||||||
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
||||||
echo "msg<<$DELIMITER" >> "$GITHUB_OUTPUT"
|
echo "msg<<$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||||
cat /tmp/commit_msg.txt >> "$GITHUB_OUTPUT"
|
cat /tmp/commit_msg.txt >> "$GITHUB_OUTPUT"
|
||||||
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||||
# Get the commit hash
|
echo "----- got commit message ---"
|
||||||
echo "hash=$(cat /tmp/commit_hash.txt)" >> "$GITHUB_OUTPUT"
|
cat /tmp/commit_msg.txt
|
||||||
|
echo "----------------------------"
|
||||||
- name: Cleanup Find commit message (PR)
|
- name: Cleanup Find commit message (PR)
|
||||||
shell: bash
|
shell: bash
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ runs:
|
|||||||
uses: actions/cache@v4 # Use a specific version
|
uses: actions/cache@v4 # Use a specific version
|
||||||
with:
|
with:
|
||||||
path: ~/Library/Caches/Homebrew
|
path: ~/Library/Caches/Homebrew
|
||||||
key: ${{ runner.os }}-brew-20251211
|
key: ${{ runner.os }}-brew-20250424
|
||||||
- name: Install Mac Prerequisites
|
- name: Install Mac Prerequisites
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
name: 'Renderdiff Generate'
|
|
||||||
description: 'Sets up prerequisites and runs the generate script for renderdiff'
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- uses: ./.github/actions/mac-prereq
|
|
||||||
- uses: ./.github/actions/get-gltf-assets
|
|
||||||
- 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: Generate images
|
|
||||||
run: |
|
|
||||||
TEST_DIR=test/renderdiff
|
|
||||||
source ${TEST_DIR}/src/preamble.sh
|
|
||||||
set -eux
|
|
||||||
bash ${TEST_DIR}/generate.sh
|
|
||||||
set +eux
|
|
||||||
shell: bash
|
|
||||||
- name: Build diffimg tool
|
|
||||||
run: |
|
|
||||||
./build.sh release diffimg
|
|
||||||
shell: bash
|
|
||||||
@@ -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-32core'
|
||||||
|
|
||||||
|
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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
name: 'Postsubmit Tasks'
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
# Update the renderdiff goldens in filament-assets. This will add or merge the new goldens from
|
|
||||||
# a branch on filament-assets.
|
|
||||||
update-renderdiff-goldens:
|
|
||||||
name: update-renderdiff-goldens
|
|
||||||
runs-on: 'macos-14-xlarge'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- id: get_commit_msg
|
|
||||||
uses: ./.github/actions/get-commit-msg
|
|
||||||
- name: Check if accepting new goldens
|
|
||||||
id: check_accept
|
|
||||||
env:
|
|
||||||
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
|
|
||||||
run: |
|
|
||||||
if echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py --mode=accept_new_goldens; then
|
|
||||||
echo "accept=true" >> "$GITHUB_OUTPUT"
|
|
||||||
else
|
|
||||||
echo "accept=false" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
- name: Renderdiff Generate for new goldens
|
|
||||||
if: steps.check_accept.outputs.accept == 'true'
|
|
||||||
uses: ./.github/actions/renderdiff-generate
|
|
||||||
- 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 }}"
|
|
||||||
|
|
||||||
git config --global user.email "filament.bot@gmail.com"
|
|
||||||
git config --global user.name "Filament Bot"
|
|
||||||
git config --global credential.helper cache
|
|
||||||
|
|
||||||
if [[ "${{ steps.check_accept.outputs.accept }}" == "true" ]]; then
|
|
||||||
SHORT_HASH="${COMMIT_HASH:0:8}"
|
|
||||||
GOLDEN_BRANCH="accept-goldens-${SHORT_HASH}"
|
|
||||||
echo "Generating new goldens for branch ${GOLDEN_BRANCH}"
|
|
||||||
python3 test/renderdiff/src/update_golden.py \
|
|
||||||
--branch=${GOLDEN_BRANCH} \
|
|
||||||
--source=$(pwd)/out/renderdiff/renders \
|
|
||||||
--commit-msg="Auto-update goldens from ${COMMIT_HASH}" \
|
|
||||||
--push-to-remote \
|
|
||||||
--golden-repo-token=${GH_TOKEN}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
|
|
||||||
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 the /docs (offiicla github-hosted Filament site) if necessary
|
|
||||||
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}
|
|
||||||
|
|
||||||
# Produce a json that describes the android artifact sizes, and will push that json to a folder in
|
|
||||||
# filament-assets
|
|
||||||
update-sizeguard:
|
|
||||||
name: update-sizeguard
|
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4.1.6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: ./.github/actions/linux-prereq
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: 'temurin'
|
|
||||||
java-version: '17'
|
|
||||||
- id: get_commit_msg
|
|
||||||
uses: ./.github/actions/get-commit-msg
|
|
||||||
- name: Build and generate size report
|
|
||||||
run: |
|
|
||||||
cd build/android && printf "y" | ./build.sh release all
|
|
||||||
cd ../..
|
|
||||||
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
|
|
||||||
python3 test/sizeguard/dump_artifact_size.py out/*.tgz out/*.aar > "${COMMIT_HASH}.json"
|
|
||||||
- name: Push to filament-assets
|
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
|
|
||||||
run: |
|
|
||||||
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 clone https://x-access-token:${GH_TOKEN}@github.com/google/filament-assets.git filament-assets
|
|
||||||
mkdir -p filament-assets/sizeguard
|
|
||||||
mv "${COMMIT_HASH}.json" filament-assets/sizeguard/
|
|
||||||
cd filament-assets
|
|
||||||
git add sizeguard/"${COMMIT_HASH}.json"
|
|
||||||
git commit -m "Update sizeguard for filament@${COMMIT_HASH}" || echo "No changes to commit"
|
|
||||||
git push https://x-access-token:${GH_TOKEN}@github.com/google/filament-assets.git main
|
|
||||||
@@ -1,115 +1,58 @@
|
|||||||
name: 'Postsubmit CI'
|
name: 'Post-submit tasks'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- release
|
|
||||||
- rc/**
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-android:
|
update-renderdiff-goldens:
|
||||||
name: build-android
|
name: update-renderdiff-goldens
|
||||||
# We intentially use a larger runner here to enable larger disk space
|
runs-on: 'ubuntu-24.04-4core'
|
||||||
# (standard linux runner will fail on disk space and faster build time).
|
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: ./.github/actions/linux-prereq
|
- uses: ./.github/actions/linux-prereq
|
||||||
- name: Run Android Continuous
|
- id: get_commit_msg
|
||||||
uses: ./.github/actions/android-continuous
|
uses: ./.github/actions/get-commit-msg
|
||||||
with:
|
- name: Prerequisites
|
||||||
build-abi: armeabi-v7a,arm64-v8a,x86_64
|
run: pip install tifffile numpy
|
||||||
|
- name: Run update script
|
||||||
build-ios:
|
env:
|
||||||
name: build-ios
|
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
|
||||||
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: |
|
run: |
|
||||||
cd build/ios && printf "y" | ./build.sh continuous
|
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 test/renderdiff/src/commit_msg.py)
|
||||||
- uses: actions/upload-artifact@v4
|
COMMIT_HASH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | head -n 1 | sed "s/commit //g")
|
||||||
with:
|
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
|
||||||
name: filament-ios
|
git config --global user.email "filament.bot@gmail.com"
|
||||||
path: out/filament-release-ios.tgz
|
git config --global user.name "Filament Bot"
|
||||||
- name: Build iOS samples
|
git config --global credential.helper cache
|
||||||
run: |
|
echo "branch==${GOLDEN_BRANCH}"
|
||||||
cd build/ios && ./build-samples.sh continuous
|
echo "hash==${COMMIT_HASH}"
|
||||||
|
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
|
||||||
build-linux:
|
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
|
||||||
name: build-linux
|
fi
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
|
||||||
|
|
||||||
|
update-docs:
|
||||||
|
name: update-docs
|
||||||
|
runs-on: 'ubuntu-24.04-4core'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: ./.github/actions/linux-prereq
|
- 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: |
|
run: |
|
||||||
cd build/linux && printf "y" | ./build.sh continuous
|
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
|
||||||
- uses: actions/upload-artifact@v4
|
COMMIT_HASH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | head -n 1 | sed "s/commit //g")
|
||||||
with:
|
git config --global user.email "filament.bot@gmail.com"
|
||||||
name: filament-linux
|
git config --global user.name "Filament Bot"
|
||||||
path: out/filament-release-linux.tgz
|
git config --global credential.helper cache
|
||||||
|
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}
|
||||||
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
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: 'Presubmit CI'
|
name: Presubmit
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -19,14 +19,14 @@ jobs:
|
|||||||
- uses: ./.github/actions/mac-prereq
|
- uses: ./.github/actions/mac-prereq
|
||||||
- name: Run build script
|
- name: Run build script
|
||||||
run: |
|
run: |
|
||||||
cd build/mac && printf "y" | ./build.sh presubmit-with-test
|
cd build/mac && printf "y" | ./build.sh presubmit
|
||||||
- name: Test material parser
|
- name: Test material parser
|
||||||
run: |
|
run: |
|
||||||
out/cmake-release/filament/test/test_material_parser
|
out/cmake-release/filament/test/test_material_parser
|
||||||
|
|
||||||
build-desktop-linux:
|
build-desktop-linux:
|
||||||
name: build-linux
|
name: build-linux
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
runs-on: ubuntu-22.04-16core
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
with:
|
with:
|
||||||
@@ -67,16 +67,7 @@ jobs:
|
|||||||
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||||
# Continuous builds will build everything
|
# Continuous builds will build everything
|
||||||
run: |
|
run: |
|
||||||
pushd .
|
cd build/android && printf "y" | ./build.sh presubmit arm64-v8a
|
||||||
cd build/android && printf "y" | ./build.sh presubmit-with-archive arm64-v8a
|
|
||||||
popd
|
|
||||||
- name: Check artifact sizes
|
|
||||||
run: |
|
|
||||||
python3 test/sizeguard/dump_artifact_size.py out/*.aar > current_size.json
|
|
||||||
python3 test/sizeguard/check_size.py current_size.json \
|
|
||||||
--target-branch origin/main \
|
|
||||||
--threshold 20480 \
|
|
||||||
--artifacts filament-android-release.aar/jni/arm64-v8a/libfilament-jni.so
|
|
||||||
|
|
||||||
build-ios:
|
build-ios:
|
||||||
name: build-iOS
|
name: build-iOS
|
||||||
@@ -117,7 +108,8 @@ jobs:
|
|||||||
uses: ./.github/actions/get-commit-msg
|
uses: ./.github/actions/get-commit-msg
|
||||||
- name: Check for manual edits to /docs
|
- name: Check for manual edits to /docs
|
||||||
run: |
|
run: |
|
||||||
bash docs_src/build/presubmit_check.sh ${{ steps.get_commit_msg.outputs.hash }}
|
COMMIT_ID=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | head -n 1 | sed "s/commit //g")
|
||||||
|
bash docs_src/build/presubmit_check.sh ${COMMIT_ID}
|
||||||
|
|
||||||
test-renderdiff:
|
test-renderdiff:
|
||||||
name: test-renderdiff
|
name: test-renderdiff
|
||||||
@@ -126,46 +118,38 @@ jobs:
|
|||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- uses: ./.github/actions/mac-prereq
|
||||||
|
- uses: ./.github/actions/get-gltf-assets
|
||||||
|
- uses: ./.github/actions/get-mesa
|
||||||
|
- uses: ./.github/actions/get-vulkan-sdk
|
||||||
- id: get_commit_msg
|
- id: get_commit_msg
|
||||||
uses: ./.github/actions/get-commit-msg
|
uses: ./.github/actions/get-commit-msg
|
||||||
- name: Check if accepting new goldens
|
- name: Prerequisites
|
||||||
id: check_accept
|
|
||||||
env:
|
|
||||||
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
|
|
||||||
run: |
|
run: |
|
||||||
if echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py --mode=accept_new_goldens; then
|
pip install tifffile numpy
|
||||||
echo "accept=true" >> "$GITHUB_OUTPUT"
|
# Must have at least clang-16 for a webgpu/dawn build.
|
||||||
else
|
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
||||||
echo "accept=false" >> "$GITHUB_OUTPUT"
|
|
||||||
fi
|
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Renderdiff Generate
|
|
||||||
if: steps.check_accept.outputs.accept != 'true'
|
|
||||||
uses: ./.github/actions/renderdiff-generate
|
|
||||||
- name: Render and compare
|
- name: Render and compare
|
||||||
if: steps.check_accept.outputs.accept != 'true'
|
|
||||||
id: render_compare
|
id: render_compare
|
||||||
env:
|
|
||||||
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
|
|
||||||
run: |
|
run: |
|
||||||
|
ls ./gltf/Models
|
||||||
TEST_DIR=test/renderdiff
|
TEST_DIR=test/renderdiff
|
||||||
source ${TEST_DIR}/src/preamble.sh
|
source ${TEST_DIR}/src/preamble.sh
|
||||||
set -eux
|
start_
|
||||||
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py)
|
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 ${TEST_DIR}/src/commit_msg.py)
|
||||||
|
bash ${TEST_DIR}/generate.sh && \
|
||||||
python3 ${TEST_DIR}/src/golden_manager.py \
|
python3 ${TEST_DIR}/src/golden_manager.py \
|
||||||
--branch=${GOLDEN_BRANCH} \
|
--branch=${GOLDEN_BRANCH} \
|
||||||
--output=${GOLDEN_OUTPUT_DIR}
|
--output=${GOLDEN_OUTPUT_DIR}
|
||||||
|
|
||||||
# Note that we need to upload the output even if comparison fails, so we undo `set -eux`
|
# Note that we need to upload the output even if comparison fails, so we undo `set -ex`
|
||||||
set +eux
|
end_
|
||||||
|
|
||||||
python3 ${TEST_DIR}/src/compare.py \
|
python3 ${TEST_DIR}/src/compare.py \
|
||||||
--src=${GOLDEN_OUTPUT_DIR} \
|
--src=${GOLDEN_OUTPUT_DIR} \
|
||||||
--dest=${RENDER_OUTPUT_DIR} \
|
--dest=${RENDER_OUTPUT_DIR} \
|
||||||
--out=${DIFF_OUTPUT_DIR} \
|
--out=${DIFF_OUTPUT_DIR} 2>&1 | tee compare_output.txt
|
||||||
--diffimg="$(pwd)/out/cmake-release/tools/diffimg/diffimg" \
|
|
||||||
--test="${TEST_DIR}/tests/presubmit.json" 2>&1 | tee compare_output.txt
|
|
||||||
|
|
||||||
if grep "Failed" compare_output.txt > /dev/null; then
|
if grep "Failed" compare_output.txt > /dev/null; then
|
||||||
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
DELIMITER="EOF_FILE_CONTENT_$(date +%s)" # Using timestamp to make it more unique
|
||||||
@@ -173,14 +157,11 @@ jobs:
|
|||||||
cat compare_output.txt >> "$GITHUB_OUTPUT"
|
cat compare_output.txt >> "$GITHUB_OUTPUT"
|
||||||
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
shell: bash
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
if: steps.check_accept.outputs.accept != 'true'
|
|
||||||
with:
|
with:
|
||||||
name: presubmit-renderdiff-result
|
name: presubmit-renderdiff-result
|
||||||
path: ./out/renderdiff
|
path: ./out/renderdiff
|
||||||
- name: Compare result
|
- name: Compare result
|
||||||
if: steps.check_accept.outputs.accept != 'true'
|
|
||||||
run: |
|
run: |
|
||||||
ERROR_STR="${{ steps.render_compare.outputs.err }}"
|
ERROR_STR="${{ steps.render_compare.outputs.err }}"
|
||||||
if [ -n "${ERROR_STR}" ]; then
|
if [ -n "${ERROR_STR}" ]; then
|
||||||
@@ -190,14 +171,14 @@ jobs:
|
|||||||
|
|
||||||
validate-wgsl-webgpu:
|
validate-wgsl-webgpu:
|
||||||
name: validate-wgsl-webgpu
|
name: validate-wgsl-webgpu
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
runs-on: 'ubuntu-24.04-8core'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4.1.6
|
- uses: actions/checkout@v4.1.6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: ./.github/actions/linux-prereq
|
- uses: ./.github/actions/linux-prereq
|
||||||
- name: Run build script
|
- 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
|
- name: Run test
|
||||||
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
|
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
|
||||||
|
|
||||||
@@ -221,23 +202,3 @@ jobs:
|
|||||||
./build.sh -p desktop debug gltf_viewer
|
./build.sh -p desktop debug gltf_viewer
|
||||||
- name: Run test
|
- name: Run test
|
||||||
run: bash test/code-correctness/test.sh
|
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
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build-linux:
|
build-linux:
|
||||||
name: build-linux
|
name: build-linux
|
||||||
runs-on: 'ubuntu-24.04-16core'
|
runs-on: ubuntu-22.04-32core
|
||||||
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -163,7 +163,9 @@ jobs:
|
|||||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||||
mv out/filament-android-release-linux.tgz out/filament-${TAG}-android-native.tgz
|
cd out/android-release/filament
|
||||||
|
tar -czf ../../filament-${TAG}-android-native.tgz .
|
||||||
|
cd ../../..
|
||||||
- name: Sign sample-gltf-viewer
|
- name: Sign sample-gltf-viewer
|
||||||
run: |
|
run: |
|
||||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||||
@@ -243,8 +245,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||||
run: |
|
run: |
|
||||||
@REMARK 'call' is required to ensure control returns to this script after the batch file finishes.
|
build\windows\build-github.bat release
|
||||||
call build\windows\build-github.bat release
|
|
||||||
echo on
|
echo on
|
||||||
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
|
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -18,9 +18,3 @@ test*.json
|
|||||||
results
|
results
|
||||||
/compile_commands.json
|
/compile_commands.json
|
||||||
/.cache
|
/.cache
|
||||||
|
|
||||||
# For /test/renderdiff dependencies
|
|
||||||
/mesa
|
|
||||||
/gltf
|
|
||||||
/filament-assets
|
|
||||||
/venv
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Building Filament
|
## Building Filament
|
||||||
|
|
||||||
## Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
To build Filament, you must first install the following tools:
|
To build Filament, you must first install the following tools:
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ To build Filament for Android you must also install the following:
|
|||||||
- Android NDK 25.1 or higher
|
- Android NDK 25.1 or higher
|
||||||
- Java 17
|
- Java 17
|
||||||
|
|
||||||
## Environment variables
|
### Environment variables
|
||||||
|
|
||||||
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
|
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
|
||||||
location of your Android SDK.
|
location of your Android SDK.
|
||||||
@@ -30,7 +30,7 @@ When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#web
|
|||||||
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
|
||||||
in CLion to obtain a usable project.
|
in CLion to obtain a usable project.
|
||||||
|
|
||||||
## Easy build
|
### Easy build
|
||||||
|
|
||||||
Once the required OS specific dependencies listed below are installed, you can use the script
|
Once the required OS specific dependencies listed below are installed, you can use the script
|
||||||
located in `build.sh` to build Filament easily on macOS and Linux.
|
located in `build.sh` to build Filament easily on macOS and Linux.
|
||||||
@@ -62,12 +62,7 @@ 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.
|
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`.
|
The script offers more features described by executing `build.sh -h`.
|
||||||
|
|
||||||
For more specialized options, please also consider the following pages:
|
### Filament-specific CMake Options
|
||||||
- `-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:
|
The following CMake options are boolean options specific to Filament:
|
||||||
|
|
||||||
@@ -89,7 +84,7 @@ cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
|
|||||||
|
|
||||||
Options can also be set with the CMake GUI.
|
Options can also be set with the CMake GUI.
|
||||||
|
|
||||||
## Linux
|
### Linux
|
||||||
|
|
||||||
Make sure you've installed the following dependencies:
|
Make sure you've installed the following dependencies:
|
||||||
|
|
||||||
@@ -148,7 +143,7 @@ ninja
|
|||||||
|
|
||||||
This will build Filament, its tests and samples, and various host tools.
|
This will build Filament, its tests and samples, and various host tools.
|
||||||
|
|
||||||
## macOS
|
### macOS
|
||||||
|
|
||||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||||
make sure the command line tools are setup by running:
|
make sure the command line tools are setup by running:
|
||||||
@@ -169,7 +164,7 @@ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/fila
|
|||||||
ninja
|
ninja
|
||||||
```
|
```
|
||||||
|
|
||||||
## iOS
|
### iOS
|
||||||
|
|
||||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||||
`-p ios` flag. For instance to build the debug target:
|
`-p ios` flag. For instance to build the debug target:
|
||||||
@@ -180,9 +175,9 @@ The easiest way to build Filament for iOS is to use `build.sh` and the
|
|||||||
|
|
||||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||||
|
|
||||||
## Windows
|
### Windows
|
||||||
|
|
||||||
### Building on Windows with Visual Studio 2019 or later
|
#### Building on Windows with Visual Studio 2019 or later
|
||||||
|
|
||||||
Install the following components:
|
Install the following components:
|
||||||
|
|
||||||
@@ -225,7 +220,7 @@ You can also use CMake to invoke the build without opening Visual Studio. For ex
|
|||||||
cmake --build . --target gltf_viewer --config Release
|
cmake --build . --target gltf_viewer --config Release
|
||||||
```
|
```
|
||||||
|
|
||||||
## Android
|
### Android
|
||||||
|
|
||||||
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
Before building Filament for Android, make sure to build Filament for your host. Some of the
|
||||||
host tools are required to successfully build for Android.
|
host tools are required to successfully build for Android.
|
||||||
@@ -242,13 +237,7 @@ foremost for `arm64-v8a`.
|
|||||||
|
|
||||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||||
|
|
||||||
### Important: SDK location
|
#### Easy Android build
|
||||||
|
|
||||||
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
|
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||||
`-p android` flag. For instance to build the release target:
|
`-p android` flag. For instance to build the release target:
|
||||||
@@ -257,46 +246,9 @@ The easiest way to build Filament for Android is to use `build.sh` and the
|
|||||||
./build.sh -p android release
|
./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.
|
Run `build.sh -h` for more information.
|
||||||
|
|
||||||
### Android Studio
|
#### Manual builds
|
||||||
|
|
||||||
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
|
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 (`aarch64`).
|
below show how to build Filament for ARM 64-bit (`aarch64`).
|
||||||
@@ -324,7 +276,7 @@ This will generate Filament's Android binaries in `out/android-release`. This lo
|
|||||||
to build the Android Studio projects located in `filament/android`. After install, the library
|
to build the Android Studio projects located in `filament/android`. After install, the library
|
||||||
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
|
||||||
|
|
||||||
### AAR
|
#### AAR
|
||||||
|
|
||||||
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
|
||||||
as explained in the sections above. You must have the following ABIs built in
|
as explained in the sections above. You must have the following ABIs built in
|
||||||
@@ -356,7 +308,7 @@ Alternatively you can build the AAR from the command line by executing the follo
|
|||||||
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
|
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
|
||||||
directory (it must match the CMake install prefix used in the previous steps).
|
directory (it must match the CMake install prefix used in the previous steps).
|
||||||
|
|
||||||
### Using Filament's AAR
|
#### Using Filament's AAR
|
||||||
|
|
||||||
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
|
||||||
sure to add the newly created module as a dependency to your application.
|
sure to add the newly created module as a dependency to your application.
|
||||||
@@ -397,7 +349,7 @@ productFlavors {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## WebAssembly
|
### WebAssembly
|
||||||
|
|
||||||
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
|
||||||
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
started, follow the instructions for building Filament on your platform ([macOS](#macos) or
|
||||||
@@ -439,7 +391,7 @@ Alternatively, if you have node installed you can use the
|
|||||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||||
web page when it detects a change.
|
web page when it detects a change.
|
||||||
|
|
||||||
Each sample app has its own handwritten html file. Additionally, the server folder contains assets
|
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||||
such as meshes, textures, and materials.
|
such as meshes, textures, and materials.
|
||||||
|
|
||||||
## Running the native samples
|
## Running the native samples
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ cmake_minimum_required(VERSION 3.22.1)
|
|||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
# Toolchain configuration
|
# Toolchain configuration
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
# On iOS, the deployment target is set inside third_party/clang/ios.cmake
|
|
||||||
if (APPLE AND NOT IOS)
|
if (APPLE AND NOT IOS)
|
||||||
# This must be set before project() is called
|
# This must be set before project() is called
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "")
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "")
|
||||||
@@ -57,16 +56,10 @@ 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_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.
|
# 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.
|
# On the regular filament build (where size is of less concern), we enable GTAO by default.
|
||||||
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
|
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
|
||||||
|
|
||||||
option(FILAMENT_BUILD_TESTING "Build tests" ON)
|
|
||||||
|
|
||||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||||
"Android NDK version or version prefix to be used when building for Android."
|
"Android NDK version or version prefix to be used when building for Android."
|
||||||
)
|
)
|
||||||
@@ -302,10 +295,15 @@ set(TOOLS ${CMAKE_CURRENT_SOURCE_DIR}/tools)
|
|||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
set(MIN_CLANG_VERSION "6.0")
|
set(MIN_CLANG_VERSION "6.0")
|
||||||
|
|
||||||
set(FILAMENT_USING_GCC OFF)
|
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
if (CMAKE_C_COMPILER_ID MATCHES "GNU" AND FILAMENT_ENABLE_EXPERIMENTAL_GCC_SUPPORT)
|
if (CMAKE_C_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
|
||||||
set(FILAMENT_USING_GCC ON)
|
message(FATAL_ERROR "Detected C compiler Clang ${CMAKE_C_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
|
||||||
elseif (CMAKE_C_COMPILER_ID MATCHES "Clang")
|
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)
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS MIN_CLANG_VERSION)
|
||||||
message(FATAL_ERROR "Detected CXX compiler Clang ${CMAKE_CXX_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
|
message(FATAL_ERROR "Detected CXX compiler Clang ${CMAKE_CXX_COMPILER_VERSION} < ${MIN_CLANG_VERSION}")
|
||||||
endif()
|
endif()
|
||||||
@@ -346,18 +344,14 @@ if (MSVC)
|
|||||||
set(CXX_STANDARD "/std:c++latest")
|
set(CXX_STANDARD "/std:c++latest")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} /W0 /Zc:__cplusplus")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} /W0 /Zc:__cplusplus")
|
||||||
else()
|
else()
|
||||||
if(FILAMENT_USING_GCC)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_STANDARD} -fstrict-aliasing -Wno-unknown-pragmas -Wno-unused-function -Wno-deprecated-declarations")
|
||||||
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()
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nullability-extension")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-nullability-extension")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (FILAMENT_USE_EXTERNAL_GLES3)
|
if (FILAMENT_USE_EXTERNAL_GLES3)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_EXTERNAL_GLES3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||||
@@ -370,23 +364,11 @@ endif()
|
|||||||
|
|
||||||
if (LINUX)
|
if (LINUX)
|
||||||
option(USE_STATIC_LIBCXX "Link against the static runtime libraries." ON)
|
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 (${USE_STATIC_LIBCXX})
|
||||||
if (FILAMENT_USING_GCC)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
link_libraries("-static-libgcc -static-libstdc++")
|
link_libraries("-static-libgcc -static-libstdc++")
|
||||||
elseif (CLANG_WITH_GLIBC)
|
link_libraries(libc++.a)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
link_libraries(libc++abi.a)
|
||||||
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()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Only linux, clang doesn't want to use a shared library that is not PIC.
|
# Only linux, clang doesn't want to use a shared library that is not PIC.
|
||||||
@@ -411,8 +393,8 @@ if (MSVC)
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add colors to ninja builds (when not using gcc)
|
# Add colors to ninja builds
|
||||||
if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja" AND NOT FILAMENT_USING_GCC)
|
if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
|
||||||
endif()
|
endif()
|
||||||
@@ -484,7 +466,7 @@ endif()
|
|||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
|
||||||
|
|
||||||
if (FILAMENT_ENABLE_COVERAGE)
|
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()
|
endif()
|
||||||
|
|
||||||
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
|
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
|
||||||
@@ -574,10 +556,6 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
|||||||
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
|
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
|
|
||||||
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Build with Metal support on non-WebGL Apple platforms.
|
# Build with Metal support on non-WebGL Apple platforms.
|
||||||
if (APPLE AND NOT WEBGL)
|
if (APPLE AND NOT WEBGL)
|
||||||
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
|
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
|
||||||
@@ -589,7 +567,7 @@ if (FILAMENT_SUPPORTS_METAL)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Building filamat increases build times and isn't required for web, so turn it off by default.
|
# Building filamat increases build times and isn't required for web, so turn it off by default.
|
||||||
if (NOT WEBGL)
|
if (NOT WEBGL AND NOT IOS)
|
||||||
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" ON)
|
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" ON)
|
||||||
else()
|
else()
|
||||||
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
|
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
|
||||||
@@ -770,61 +748,12 @@ function(combine_static_libs TARGET OUTPUT DEPS)
|
|||||||
endfunction()
|
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)
|
if (WEBGL)
|
||||||
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake)
|
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake)
|
||||||
else()
|
else()
|
||||||
if (FILAMENT_EXPORT_PREBUILT_EXECUTABLES OR FILAMENT_IMPORT_PREBUILT_EXECUTABLES)
|
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${CMAKE_BUILD_TYPE}.cmake)
|
||||||
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)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ==================================================================================================
|
# ==================================================================================================
|
||||||
@@ -879,7 +808,6 @@ add_subdirectory(${LIBRARIES}/gltfio)
|
|||||||
add_subdirectory(${LIBRARIES}/ibl)
|
add_subdirectory(${LIBRARIES}/ibl)
|
||||||
add_subdirectory(${LIBRARIES}/iblprefilter)
|
add_subdirectory(${LIBRARIES}/iblprefilter)
|
||||||
add_subdirectory(${LIBRARIES}/image)
|
add_subdirectory(${LIBRARIES}/image)
|
||||||
add_subdirectory(${LIBRARIES}/imagediff)
|
|
||||||
add_subdirectory(${LIBRARIES}/ktxreader)
|
add_subdirectory(${LIBRARIES}/ktxreader)
|
||||||
add_subdirectory(${LIBRARIES}/math)
|
add_subdirectory(${LIBRARIES}/math)
|
||||||
add_subdirectory(${LIBRARIES}/mathio)
|
add_subdirectory(${LIBRARIES}/mathio)
|
||||||
@@ -888,9 +816,7 @@ add_subdirectory(${LIBRARIES}/utils)
|
|||||||
add_subdirectory(${LIBRARIES}/viewer)
|
add_subdirectory(${LIBRARIES}/viewer)
|
||||||
add_subdirectory(${FILAMENT}/shaders)
|
add_subdirectory(${FILAMENT}/shaders)
|
||||||
add_subdirectory(${EXTERNAL}/abseil/tnt)
|
add_subdirectory(${EXTERNAL}/abseil/tnt)
|
||||||
# Add zstd before basisu to force it to use the external zstd target,
|
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||||
# preventing a duplicate symbol conflict with its bundled version.
|
|
||||||
add_subdirectory(${EXTERNAL}/zstd/tnt)
|
|
||||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||||
add_subdirectory(${EXTERNAL}/robin-map/tnt)
|
add_subdirectory(${EXTERNAL}/robin-map/tnt)
|
||||||
@@ -904,10 +830,7 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
|||||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||||
add_subdirectory(${EXTERNAL}/getopt)
|
add_subdirectory(${EXTERNAL}/getopt)
|
||||||
add_subdirectory(${EXTERNAL}/perfetto/tnt)
|
add_subdirectory(${EXTERNAL}/perfetto/tnt)
|
||||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
add_subdirectory(${EXTERNAL}/zstd/tnt)
|
||||||
|
|
||||||
# imageio-lite is needed for viewer
|
|
||||||
add_subdirectory(${LIBRARIES}/imageio-lite)
|
|
||||||
|
|
||||||
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
|
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
|
||||||
add_subdirectory(${LIBRARIES}/geometry)
|
add_subdirectory(${LIBRARIES}/geometry)
|
||||||
@@ -931,10 +854,6 @@ if (FILAMENT_ENABLE_FGVIEWER)
|
|||||||
add_subdirectory(${LIBRARIES}/fgviewer)
|
add_subdirectory(${LIBRARIES}/fgviewer)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
|
|
||||||
add_subdirectory(${EXTERNAL}/libwebp/tnt)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (FILAMENT_SUPPORTS_VULKAN)
|
if (FILAMENT_SUPPORTS_VULKAN)
|
||||||
add_subdirectory(${LIBRARIES}/bluevk)
|
add_subdirectory(${LIBRARIES}/bluevk)
|
||||||
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
|
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
|
||||||
@@ -976,7 +895,6 @@ if (IS_HOST_PLATFORM)
|
|||||||
|
|
||||||
add_subdirectory(${TOOLS}/cmgen)
|
add_subdirectory(${TOOLS}/cmgen)
|
||||||
add_subdirectory(${TOOLS}/cso-lut)
|
add_subdirectory(${TOOLS}/cso-lut)
|
||||||
add_subdirectory(${TOOLS}/diffimg)
|
|
||||||
add_subdirectory(${TOOLS}/filamesh)
|
add_subdirectory(${TOOLS}/filamesh)
|
||||||
add_subdirectory(${TOOLS}/glslminifier)
|
add_subdirectory(${TOOLS}/glslminifier)
|
||||||
add_subdirectory(${TOOLS}/matc)
|
add_subdirectory(${TOOLS}/matc)
|
||||||
@@ -991,10 +909,9 @@ if (IS_HOST_PLATFORM)
|
|||||||
add_subdirectory(${TOOLS}/roughness-prefilter)
|
add_subdirectory(${TOOLS}/roughness-prefilter)
|
||||||
add_subdirectory(${TOOLS}/specular-color)
|
add_subdirectory(${TOOLS}/specular-color)
|
||||||
add_subdirectory(${TOOLS}/uberz)
|
add_subdirectory(${TOOLS}/uberz)
|
||||||
add_subdirectory(${TOOLS}/specgen)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
|
# 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})
|
export(TARGETS matc cmgen filamesh mipgen resgen uberz glslminifier FILE ${IMPORT_EXECUTABLES})
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ The guiding principles of the filament code style and code formatting can be res
|
|||||||
- class access modifiers are not indented
|
- class access modifiers are not indented
|
||||||
- last line of `.cpp` or `.h` file must be an empty line
|
- last line of `.cpp` or `.h` file must be an empty line
|
||||||
|
|
||||||
```c++
|
```
|
||||||
for (int i = 0; i < max; i++) {
|
for (int i = 0; i < max; i++) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,24 +73,12 @@ src/data.inc
|
|||||||
- `public` class attributes *are not* prefixed
|
- `public` class attributes *are not* prefixed
|
||||||
- class attributes and methods are lower camelcase
|
- class attributes and methods are lower camelcase
|
||||||
|
|
||||||
```c++
|
```
|
||||||
extern int gGlobalWarming;
|
extern int gGlobalWarming;
|
||||||
|
|
||||||
class FooBar {
|
class FooBar {
|
||||||
public:
|
public:
|
||||||
FooBar(int attributeName, int sizeInBytes)
|
void methodName();
|
||||||
: mAttributeName(attributeName),
|
|
||||||
sizeInBytes(sizeInBytes) {}
|
|
||||||
|
|
||||||
void reallyLongMethodNameWithLotsOfArguments(bool argument1,
|
|
||||||
int someSecondArgument, int bestArgument) {
|
|
||||||
std::pair<bool, int> pair = {
|
|
||||||
argument1,
|
|
||||||
argument2,
|
|
||||||
};
|
|
||||||
// etc
|
|
||||||
}
|
|
||||||
|
|
||||||
int sizeInBytes;
|
int sizeInBytes;
|
||||||
private:
|
private:
|
||||||
int mAttributeName;
|
int mAttributeName;
|
||||||
@@ -109,7 +97,7 @@ private:
|
|||||||
- always include the copyright notice at the top of every file
|
- always include the copyright notice at the top of every file
|
||||||
- make sure the date is correct
|
- make sure the date is correct
|
||||||
|
|
||||||
```c++
|
```
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
*
|
*
|
||||||
@@ -151,7 +139,7 @@ conversely containers and algorithms are not allowed. There are exceptions such
|
|||||||
|
|
||||||
*Sorting the headers is important to help catching missing `#include` directives.*
|
*Sorting the headers is important to help catching missing `#include` directives.*
|
||||||
|
|
||||||
```c++
|
```
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
*
|
*
|
||||||
@@ -195,7 +183,7 @@ conversely containers and algorithms are not allowed. There are exceptions such
|
|||||||
### Misc
|
### Misc
|
||||||
|
|
||||||
- Use `auto` only when the type appears on the same line or with iterators and lambdas.
|
- Use `auto` only when the type appears on the same line or with iterators and lambdas.
|
||||||
```c++
|
```
|
||||||
auto foo = new Foo();
|
auto foo = new Foo();
|
||||||
for (auto& i : collection) { }
|
for (auto& i : collection) { }
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
# Filament Release Notes log
|
# Filament Release Notes log
|
||||||
|
|
||||||
**If you are merging a PR into main**: please add the release note below, under the *Release notes
|
**If you are merging a PR into main**: please add the release note below, under the *Release notes
|
||||||
|
We are chaning the way Vulkan buffers are handled. We need to switch over to a managed (or view-based) model where the data stored inside the object is a proxy to a Vulkan object that can dynamically be swapped around.
|
||||||
|
|
||||||
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
|
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
|
||||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||||
|
|
||||||
## Release notes for next branch cut
|
## Release notes for next branch cut
|
||||||
|
|
||||||
- engine: fix crash when using variance shadow maps
|
|
||||||
- materials: better shadow normal-bias calculations [⚠️ **New Material Version**]
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.google.android.filament:filament-android:1.69.4'
|
implementation 'com.google.android.filament:filament-android:1.65.0'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -39,18 +39,19 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
|||||||
|
|
||||||
| Artifact | Description |
|
| Artifact | Description |
|
||||||
| ------------- | ------------- |
|
| ------------- | ------------- |
|
||||||
| [](https://mvnrepository.com/artifact/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
|
||||||
| [](https://mvnrepository.com/artifact/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
|
||||||
| [](https://mvnrepository.com/artifact/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||||
| [](https://mvnrepository.com/artifact/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||||
| [](https://mvnrepository.com/artifact/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||||
|
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
|
|
||||||
iOS projects can use CocoaPods to install the latest release:
|
iOS projects can use CocoaPods to install the latest release:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
pod 'Filament', '~> 1.69.4'
|
pod 'Filament', '~> 1.65.0'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
@@ -88,8 +89,7 @@ pod 'Filament', '~> 1.69.4'
|
|||||||
- OpenGL ES 3.0+ for Android and iOS
|
- OpenGL ES 3.0+ for Android and iOS
|
||||||
- Metal for macOS and iOS
|
- Metal for macOS and iOS
|
||||||
- Vulkan 1.0 for Android, Linux, macOS, and Windows
|
- Vulkan 1.0 for Android, Linux, macOS, and Windows
|
||||||
- WebGPU for Android, Linux, macOS, and Windows
|
- WebGL 2.0 for all platforms
|
||||||
- WebGL 2.0 for all browsers supporting it
|
|
||||||
|
|
||||||
### Rendering
|
### Rendering
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ pod 'Filament', '~> 1.69.4'
|
|||||||
|
|
||||||
- HDR bloom
|
- HDR bloom
|
||||||
- Depth of field bokeh
|
- Depth of field bokeh
|
||||||
- Multiple tone mappers: PBR Neutral, AgX, generic (customizable), ACES, filmic, etc.
|
- Multiple tone mappers: generic (customizable), ACES, filmic, etc.
|
||||||
- Color and tone management: luminance scaling, gamut mapping
|
- Color and tone management: luminance scaling, gamut mapping
|
||||||
- Color grading: exposure, night adaptation, white balance, channel mixer,
|
- Color grading: exposure, night adaptation, white balance, channel mixer,
|
||||||
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
|
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
|
||||||
@@ -158,16 +158,15 @@ pod 'Filament', '~> 1.69.4'
|
|||||||
- [x] KHR_draco_mesh_compression
|
- [x] KHR_draco_mesh_compression
|
||||||
- [x] KHR_lights_punctual
|
- [x] KHR_lights_punctual
|
||||||
- [x] KHR_materials_clearcoat
|
- [x] KHR_materials_clearcoat
|
||||||
- [x] KHR_materials_dispersion
|
|
||||||
- [x] KHR_materials_emissive_strength
|
- [x] KHR_materials_emissive_strength
|
||||||
- [x] KHR_materials_ior
|
- [x] KHR_materials_ior
|
||||||
- [x] KHR_materials_pbrSpecularGlossiness
|
- [x] KHR_materials_pbrSpecularGlossiness
|
||||||
- [x] KHR_materials_sheen
|
- [x] KHR_materials_sheen
|
||||||
- [x] KHR_materials_specular
|
|
||||||
- [x] KHR_materials_transmission
|
- [x] KHR_materials_transmission
|
||||||
- [x] KHR_materials_unlit
|
- [x] KHR_materials_unlit
|
||||||
- [x] KHR_materials_variants
|
- [x] KHR_materials_variants
|
||||||
- [x] KHR_materials_volume
|
- [x] KHR_materials_volume
|
||||||
|
- [x] KHR_materials_specular
|
||||||
- [x] KHR_mesh_quantization
|
- [x] KHR_mesh_quantization
|
||||||
- [x] KHR_texture_basisu
|
- [x] KHR_texture_basisu
|
||||||
- [x] KHR_texture_transform
|
- [x] KHR_texture_transform
|
||||||
@@ -332,7 +331,7 @@ and tools.
|
|||||||
- `filamesh`: Mesh converter
|
- `filamesh`: Mesh converter
|
||||||
- `glslminifier`: Minifies GLSL source code
|
- `glslminifier`: Minifies GLSL source code
|
||||||
- `matc`: Material compiler
|
- `matc`: Material compiler
|
||||||
- `matedit`: Material editor for compiled materials
|
- `filament-matp`: Material parser
|
||||||
- `matinfo` Displays information about materials compiled with `matc`
|
- `matinfo` Displays information about materials compiled with `matc`
|
||||||
- `mipgen` Generates a series of miplevels from a source image
|
- `mipgen` Generates a series of miplevels from a source image
|
||||||
- `normal-blending`: Tool to blend normal maps
|
- `normal-blending`: Tool to blend normal maps
|
||||||
|
|||||||
@@ -7,88 +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
|
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||||
|
|
||||||
## v1.69.5
|
|
||||||
|
|
||||||
- engine: fix crash when using variance shadow maps
|
|
||||||
|
|
||||||
## v1.69.4
|
|
||||||
|
|
||||||
|
|
||||||
## v1.69.3
|
|
||||||
|
|
||||||
|
|
||||||
## v1.69.2
|
|
||||||
|
|
||||||
- engine: fix shader compilation failure in TAA material
|
|
||||||
- engine: fix stereo & parallel shader compilation
|
|
||||||
|
|
||||||
## v1.69.1
|
|
||||||
|
|
||||||
|
|
||||||
## v1.69.0
|
|
||||||
|
|
||||||
- engine: Support custom attributes morphing, and allow for omitting position and/or normal data. [⚠️ **Recompile Materials**]
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
The functionality is already implemented by calling the CanonicalizeIds pass
|
|
||||||
in the SPIRV-Tools, and should be a non-functional change.
|
|
||||||
|
|
||||||
## v1.66.0
|
|
||||||
|
|
||||||
- materials: include default values of spec constants in material metadata [⚠️ **Recompile Materials**]
|
|
||||||
|
|
||||||
## v1.65.4
|
|
||||||
|
|
||||||
|
|
||||||
## v1.65.3
|
|
||||||
|
|
||||||
|
|
||||||
## v1.65.2
|
|
||||||
|
|
||||||
|
|
||||||
## v1.65.1
|
## v1.65.1
|
||||||
|
|
||||||
- `setFrameScheduledCallback` now works on all backends (frame presentation scheduling is still only
|
- `setFrameScheduledCallback` now works on all backends (frame presentation scheduling is still only
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ buildscript {
|
|||||||
'kotlin': '2.0.21',
|
'kotlin': '2.0.21',
|
||||||
'kotlin_coroutines': '1.9.0',
|
'kotlin_coroutines': '1.9.0',
|
||||||
'buildTools': '35.0.0',
|
'buildTools': '35.0.0',
|
||||||
'ndk': '29.0.14206865',
|
'ndk': '27.0.11718014',
|
||||||
'androidx_core': '1.13.1',
|
'androidx_core': '1.13.1',
|
||||||
'androidx_annotations': '1.9.0'
|
'androidx_annotations': '1.9.0'
|
||||||
]
|
]
|
||||||
@@ -124,7 +124,6 @@ buildscript {
|
|||||||
|
|
||||||
ext.cmakeArgs = [
|
ext.cmakeArgs = [
|
||||||
"--no-warn-unused-cli",
|
"--no-warn-unused-cli",
|
||||||
"-DANDROID_WEAK_API_DEFS=ON",
|
|
||||||
"-DANDROID_PIE=ON",
|
"-DANDROID_PIE=ON",
|
||||||
"-DANDROID_PLATFORM=21",
|
"-DANDROID_PLATFORM=21",
|
||||||
"-DANDROID_STL=c++_static",
|
"-DANDROID_STL=c++_static",
|
||||||
@@ -194,7 +193,7 @@ subprojects {
|
|||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name.startsWith("sample") && name != "filament-tools") {
|
if (!name.startsWith("sample")) {
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
# Filament Tools Gradle Plugin
|
|
||||||
|
|
||||||
## About
|
|
||||||
|
|
||||||
The **Filament Tools Gradle Plugin** helps integrate Filament into your Android project. It
|
|
||||||
automates the use of Filament's command-line tools (`matc`, `cmgen`, and `filamesh`).
|
|
||||||
|
|
||||||
This plugin handles:
|
|
||||||
- **Material Compilation**: Compiles `.mat` material definitions into `.filamat` binaries.
|
|
||||||
- **IBL Generation**: Generates Image-Based Lighting assets from HDR environment maps.
|
|
||||||
- **Mesh Compilation**: Converts models into Filament's efficient `.filamesh` binary format. *Note:
|
|
||||||
This tool is no longer recommended; instead, use glTF and Filament's `gltfio` library for model
|
|
||||||
loading.*
|
|
||||||
|
|
||||||
The plugin hooks directly into the Android build lifecycle (via `preBuild`) and supports incremental
|
|
||||||
builds, so assets are only recompiled when source files change.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Apply the plugin in your module's `build.gradle` file and configure the `filament` block. You can
|
|
||||||
specify inputs and outputs for any combination of materials, IBLs, or meshes. If a path is not
|
|
||||||
configured, the corresponding task will be disabled.
|
|
||||||
|
|
||||||
### Example Configuration
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
plugins {
|
|
||||||
id 'filament-plugin'
|
|
||||||
}
|
|
||||||
|
|
||||||
filament {
|
|
||||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
|
||||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
|
||||||
|
|
||||||
iblInputFile = project.layout.projectDirectory.file("path/to/environment.hdr")
|
|
||||||
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
|
||||||
|
|
||||||
meshInputFile = project.layout.projectDirectory.file("path/to/model.obj")
|
|
||||||
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration Details
|
|
||||||
|
|
||||||
- **materialInputDir**: The directory containing your source material definitions (`.mat` files).
|
|
||||||
- **materialOutputDir**: The directory where the compiled material files (`.filamat`) will be
|
|
||||||
generated.
|
|
||||||
- **iblInputFile**: The source high-dynamic-range image file (e.g., `.hdr` or `.exr`) used to
|
|
||||||
generate Image Based Lighting assets.
|
|
||||||
- **iblOutputDir**: The directory where the generated IBL assets (typically `.ktx` files) will be
|
|
||||||
placed.
|
|
||||||
- **meshInputFile**: The source mesh file (e.g., `.obj`) to be compiled.
|
|
||||||
- **meshOutputDir**: The directory where the compiled mesh file (`.filamesh`) will be generated.
|
|
||||||
|
|
||||||
Automatically adds tasks to your Android build to compile materials, generate an IBL, and compile a
|
|
||||||
mesh. The plugin hooks into `preBuild` to ensure assets are generated before the application is
|
|
||||||
built.
|
|
||||||
|
|
||||||
### Configuration Flags
|
|
||||||
|
|
||||||
You can control specific compilation options using Gradle properties (e.g., in `gradle.properties`
|
|
||||||
or via command line `-P`).
|
|
||||||
|
|
||||||
- **`com.google.android.filament.exclude-vulkan`** When set to `true`, the Vulkan backend is
|
|
||||||
excluded from the compiled materials. This can be useful to reduce the size of the generated
|
|
||||||
assets if your application does not target Vulkan. *Default: `false` (Vulkan is included)*
|
|
||||||
|
|
||||||
- **`com.google.android.filament.include-webgpu`** When set to `true`, the WebGPU backend is
|
|
||||||
included in the compiled materials. Use this if you intend to use the materials in a context
|
|
||||||
supporting WebGPU. *Default: `false`*
|
|
||||||
|
|
||||||
## Tools Configuration
|
|
||||||
|
|
||||||
The Filament Tools plugin requires some binary tools to be available: `matc`, `cmgen`, and
|
|
||||||
`filamesh`.
|
|
||||||
|
|
||||||
There are three ways to configure Filament tools:
|
|
||||||
|
|
||||||
1. **Point to a local path directly**
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
filament {
|
|
||||||
matc {
|
|
||||||
path = "/path/to/matc"
|
|
||||||
}
|
|
||||||
|
|
||||||
cmgen {
|
|
||||||
path = "/path/to/cmgen"
|
|
||||||
}
|
|
||||||
|
|
||||||
filamesh {
|
|
||||||
path = "/path/to/filamesh"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Point to a Maven artifact**
|
|
||||||
|
|
||||||
```groovy
|
|
||||||
filament {
|
|
||||||
matc {
|
|
||||||
// The minor version (the middle number) must match the Filament dependency's.
|
|
||||||
artifact = 'com.google.android.filament:matc:1.68.5'
|
|
||||||
}
|
|
||||||
|
|
||||||
cmgen {
|
|
||||||
artifact = 'com.google.android.filament:cmgen:1.68.5'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
*Note that the `filamesh` artifact is not hosted on Maven Central, so it must be provided locally or
|
|
||||||
via another mechanism if needed.*
|
|
||||||
|
|
||||||
Gradle will automatically handle downloading the tool appropriate for your machine (MacOS/Linux/Windows) from Maven.
|
|
||||||
|
|
||||||
3. **Set the `com.google.android.filament.tools-dir` Gradle property**
|
|
||||||
|
|
||||||
This will override any other configuration. Gradle will attempt to locate the tools under
|
|
||||||
`<tools-dir>/bin` (e.g., `.../bin/matc`, `.../bin/cmgen`, `.../bin/filamesh`).
|
|
||||||
@@ -4,18 +4,13 @@ plugins {
|
|||||||
|
|
||||||
gradlePlugin {
|
gradlePlugin {
|
||||||
plugins {
|
plugins {
|
||||||
create("filament-plugin") {
|
create("filament-tools-plugin") {
|
||||||
id = "filament-plugin"
|
id = "filament-tools-plugin"
|
||||||
implementationClass = "com.google.android.filament.gradle.FilamentPlugin"
|
implementationClass = "FilamentToolsPlugin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation "com.google.gradle:osdetector-gradle-plugin:1.7.3"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,359 @@
|
|||||||
|
// This plugin accepts the following parameters:
|
||||||
|
//
|
||||||
|
// com.google.android.filament.tools-dir
|
||||||
|
// Path to the Filament distribution/install directory for desktop.
|
||||||
|
// This directory must contain bin/matc.
|
||||||
|
//
|
||||||
|
// com.google.android.filament.exclude-vulkan
|
||||||
|
// When set, support for Vulkan will be excluded.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// ./gradlew -Pcom.google.android.filament.tools-dir=../../dist-release assembleDebug
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.GradleException
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.provider.ProviderFactory
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.file.FileSystemOperations
|
||||||
|
import org.gradle.api.file.FileType
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
import org.gradle.api.logging.Logger
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.InputDirectory
|
||||||
|
import org.gradle.api.tasks.InputFile
|
||||||
|
import org.gradle.api.tasks.Optional
|
||||||
|
import org.gradle.api.tasks.OutputDirectory
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.api.tasks.incremental.InputFileDetails
|
||||||
|
import org.gradle.api.model.ObjectFactory
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
import org.gradle.work.ChangeType
|
||||||
|
import org.gradle.work.Incremental
|
||||||
|
import org.gradle.work.InputChanges
|
||||||
|
|
||||||
|
import java.nio.file.Paths
|
||||||
|
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
abstract class TaskWithBinary extends DefaultTask {
|
||||||
|
private final String binaryName
|
||||||
|
private Property<String> binaryPath = null
|
||||||
|
|
||||||
|
TaskWithBinary(String name) {
|
||||||
|
binaryName = name
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject abstract ObjectFactory getObjects()
|
||||||
|
@Inject abstract ProviderFactory getProviders()
|
||||||
|
|
||||||
|
@Input
|
||||||
|
Property<String> getBinary() {
|
||||||
|
if (binaryPath == null) {
|
||||||
|
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
|
||||||
|
def fullPath = tool.collect { path ->
|
||||||
|
def filamentToolsPath = providers
|
||||||
|
.gradleProperty("com.google.android.filament.tools-dir")
|
||||||
|
.forUseAtConfigurationTime().get()
|
||||||
|
def directory = objects.fileProperty()
|
||||||
|
.fileValue(new File(filamentToolsPath)).getAsFile().get()
|
||||||
|
Paths.get(directory.absolutePath, path).toFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
binaryPath = objects.property(String.class)
|
||||||
|
binaryPath.set(
|
||||||
|
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
|
||||||
|
}
|
||||||
|
return binaryPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LogOutputStream extends ByteArrayOutputStream {
|
||||||
|
private final Logger logger
|
||||||
|
private final LogLevel level
|
||||||
|
|
||||||
|
LogOutputStream(Logger logger, LogLevel level) {
|
||||||
|
this.logger = logger
|
||||||
|
this.level = level
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void flush() {
|
||||||
|
logger.log(level, toString())
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom task to compile material files using matc
|
||||||
|
// This task handles incremental builds
|
||||||
|
abstract class MaterialCompiler extends TaskWithBinary {
|
||||||
|
@Incremental
|
||||||
|
@InputDirectory
|
||||||
|
abstract DirectoryProperty getInputDir()
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
abstract DirectoryProperty getOutputDir()
|
||||||
|
|
||||||
|
@Inject abstract FileSystemOperations getFs()
|
||||||
|
@Inject abstract ExecOperations getExec()
|
||||||
|
@Inject abstract ObjectFactory getObjects()
|
||||||
|
@Inject abstract ProviderFactory getProviders()
|
||||||
|
|
||||||
|
MaterialCompiler() {
|
||||||
|
super("matc")
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
void execute(InputChanges inputs) {
|
||||||
|
if (!inputs.incremental) {
|
||||||
|
fs.delete({
|
||||||
|
delete(objects.fileTree().from(outputDir).matching { include '*.filamat' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs.getFileChanges(inputDir).each { InputFileDetails change ->
|
||||||
|
if (change.fileType == FileType.DIRECTORY) return
|
||||||
|
|
||||||
|
def file = change.file
|
||||||
|
|
||||||
|
if (change.changeType == ChangeType.REMOVED) {
|
||||||
|
getOutputFile(file).delete()
|
||||||
|
} else {
|
||||||
|
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||||
|
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||||
|
|
||||||
|
def header = ("Compiling material " + file + "\n").getBytes()
|
||||||
|
out.write(header)
|
||||||
|
out.flush()
|
||||||
|
|
||||||
|
if (!new File(binary.get()).exists()) {
|
||||||
|
throw new GradleException("Could not find ${binary.get()}." +
|
||||||
|
" Ensure Filament has been built/installed before building this app.")
|
||||||
|
}
|
||||||
|
|
||||||
|
def matcArgs = []
|
||||||
|
def exclude_vulkan = providers
|
||||||
|
.gradleProperty("com.google.android.filament.exclude-vulkan")
|
||||||
|
.forUseAtConfigurationTime().present
|
||||||
|
if (!exclude_vulkan) {
|
||||||
|
matcArgs += ['-a', 'vulkan']
|
||||||
|
}
|
||||||
|
def include_webgpu = providers
|
||||||
|
.gradleProperty("com.google.android.filament.include-webgpu")
|
||||||
|
.forUseAtConfigurationTime().present
|
||||||
|
if (include_webgpu) {
|
||||||
|
matcArgs += ['-a', 'webgpu', '--variant-filter=stereo']
|
||||||
|
}
|
||||||
|
|
||||||
|
def mat_no_opt = providers
|
||||||
|
.gradleProperty("com.google.android.filament.matnopt")
|
||||||
|
.forUseAtConfigurationTime().present
|
||||||
|
if (mat_no_opt) {
|
||||||
|
matcArgs += ['-g']
|
||||||
|
}
|
||||||
|
|
||||||
|
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
|
||||||
|
|
||||||
|
exec.exec {
|
||||||
|
standardOutput out
|
||||||
|
errorOutput err
|
||||||
|
executable "${binary.get()}"
|
||||||
|
args matcArgs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File getOutputFile(final File file) {
|
||||||
|
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamat').get().asFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom task to process IBLs using cmgen
|
||||||
|
// This task handles incremental builds
|
||||||
|
abstract class IblGenerator extends TaskWithBinary {
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
abstract Property<String> getCmgenArgs()
|
||||||
|
|
||||||
|
@Incremental
|
||||||
|
@InputFile
|
||||||
|
abstract RegularFileProperty getInputFile()
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
abstract DirectoryProperty getOutputDir()
|
||||||
|
|
||||||
|
@Inject abstract FileSystemOperations getFs()
|
||||||
|
@Inject abstract ExecOperations getExec()
|
||||||
|
@Inject abstract ObjectFactory getObjects()
|
||||||
|
|
||||||
|
IblGenerator() {
|
||||||
|
super("cmgen")
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
void execute(InputChanges inputs) {
|
||||||
|
if (!inputs.incremental) {
|
||||||
|
fs.delete({
|
||||||
|
delete(objects.fileTree().from(outputDir).matching { include '*' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
|
||||||
|
if (change.fileType == FileType.DIRECTORY) return
|
||||||
|
|
||||||
|
def file = change.file
|
||||||
|
|
||||||
|
if (change.changeType == ChangeType.REMOVED) {
|
||||||
|
getOutputFile(file).delete()
|
||||||
|
} else {
|
||||||
|
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||||
|
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||||
|
|
||||||
|
def header = ("Generating IBL " + file + "\n").getBytes()
|
||||||
|
out.write(header)
|
||||||
|
out.flush()
|
||||||
|
|
||||||
|
if (!new File(binary.get()).exists()) {
|
||||||
|
throw new GradleException("Could not find ${binary.get()}." +
|
||||||
|
" Ensure Filament has been built/installed before building this app.")
|
||||||
|
}
|
||||||
|
|
||||||
|
def outputPath = outputDir.get().asFile
|
||||||
|
def commandArgs = cmgenArgs.getOrNull()
|
||||||
|
if (commandArgs == null) {
|
||||||
|
commandArgs =
|
||||||
|
'-q -x ' + outputPath + ' --format=rgb32f ' +
|
||||||
|
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
||||||
|
}
|
||||||
|
commandArgs = commandArgs + " " + file
|
||||||
|
|
||||||
|
exec.exec {
|
||||||
|
standardOutput out
|
||||||
|
errorOutput err
|
||||||
|
executable "${binary.get()}"
|
||||||
|
args(commandArgs.split())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File getOutputFile(final File file) {
|
||||||
|
return outputDir.file(file.name[0..file.name.lastIndexOf('.') - 1]).get().asFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom task to compile mesh files using filamesh
|
||||||
|
// This task handles incremental builds
|
||||||
|
abstract class MeshCompiler extends TaskWithBinary {
|
||||||
|
@Incremental
|
||||||
|
@InputFile
|
||||||
|
abstract RegularFileProperty getInputFile()
|
||||||
|
|
||||||
|
@OutputDirectory
|
||||||
|
abstract DirectoryProperty getOutputDir()
|
||||||
|
|
||||||
|
@Inject abstract FileSystemOperations getFs()
|
||||||
|
@Inject abstract ExecOperations getExec()
|
||||||
|
|
||||||
|
MeshCompiler() {
|
||||||
|
super("filamesh")
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
void execute(InputChanges inputs) {
|
||||||
|
if (!inputs.incremental) {
|
||||||
|
fs.delete({
|
||||||
|
delete(objects.fileTree().from(outputDir).matching { include '*.filamesh' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
|
||||||
|
if (change.fileType == FileType.DIRECTORY) return
|
||||||
|
|
||||||
|
def file = change.file
|
||||||
|
|
||||||
|
if (change.changeType == ChangeType.REMOVED) {
|
||||||
|
getOutputFile(file).delete()
|
||||||
|
} else {
|
||||||
|
def out = new LogOutputStream(logger, LogLevel.LIFECYCLE)
|
||||||
|
def err = new LogOutputStream(logger, LogLevel.ERROR)
|
||||||
|
|
||||||
|
def header = ("Compiling mesh " + file + "\n").getBytes()
|
||||||
|
out.write(header)
|
||||||
|
out.flush()
|
||||||
|
|
||||||
|
if (!new File(binary.get()).exists()) {
|
||||||
|
throw new GradleException("Could not find ${binary.get()}." +
|
||||||
|
" Ensure Filament has been built/installed before building this app.")
|
||||||
|
}
|
||||||
|
|
||||||
|
exec.exec {
|
||||||
|
standardOutput out
|
||||||
|
errorOutput err
|
||||||
|
executable "${binary.get()}"
|
||||||
|
args(file, getOutputFile(file))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File getOutputFile(final File file) {
|
||||||
|
return outputDir.file(file.name[0..file.name.lastIndexOf('.')] + 'filamesh').get().asFile
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilamentToolsPluginExtension {
|
||||||
|
DirectoryProperty materialInputDir
|
||||||
|
DirectoryProperty materialOutputDir
|
||||||
|
|
||||||
|
String cmgenArgs
|
||||||
|
RegularFileProperty iblInputFile
|
||||||
|
DirectoryProperty iblOutputDir
|
||||||
|
|
||||||
|
RegularFileProperty meshInputFile
|
||||||
|
DirectoryProperty meshOutputDir
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilamentToolsPlugin implements Plugin<Project> {
|
||||||
|
void apply(Project project) {
|
||||||
|
def extension = project.extensions.create('filamentTools', FilamentToolsPluginExtension)
|
||||||
|
extension.materialInputDir = project.objects.directoryProperty()
|
||||||
|
extension.materialOutputDir = project.objects.directoryProperty()
|
||||||
|
extension.iblInputFile = project.objects.fileProperty()
|
||||||
|
extension.iblOutputDir = project.objects.directoryProperty()
|
||||||
|
extension.meshInputFile = project.objects.fileProperty()
|
||||||
|
extension.meshOutputDir = project.objects.directoryProperty()
|
||||||
|
|
||||||
|
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
|
||||||
|
enabled =
|
||||||
|
extension.materialInputDir.isPresent() &&
|
||||||
|
extension.materialOutputDir.isPresent()
|
||||||
|
inputDir.set(extension.materialInputDir.getOrNull())
|
||||||
|
outputDir.set(extension.materialOutputDir.getOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
project.preBuild.dependsOn "filamentCompileMaterials"
|
||||||
|
|
||||||
|
project.tasks.register("filamentGenerateIbl", IblGenerator) {
|
||||||
|
enabled = extension.iblInputFile.isPresent() && extension.iblOutputDir.isPresent()
|
||||||
|
cmgenArgs = extension.cmgenArgs
|
||||||
|
inputFile = extension.iblInputFile.getOrNull()
|
||||||
|
outputDir = extension.iblOutputDir.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
project.preBuild.dependsOn "filamentGenerateIbl"
|
||||||
|
|
||||||
|
project.tasks.register("filamentCompileMesh", MeshCompiler) {
|
||||||
|
enabled = extension.meshInputFile.isPresent() && extension.meshOutputDir.isPresent()
|
||||||
|
inputFile = extension.meshInputFile.getOrNull()
|
||||||
|
outputDir = extension.meshOutputDir.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
project.preBuild.dependsOn "filamentCompileMesh"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.Action
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.file.DirectoryProperty
|
|
||||||
import org.gradle.api.file.RegularFileProperty
|
|
||||||
import org.gradle.api.provider.Property
|
|
||||||
|
|
||||||
class FilamentExtension {
|
|
||||||
final ToolsLocator tools
|
|
||||||
final DirectoryProperty materialInputDir
|
|
||||||
final DirectoryProperty materialOutputDir
|
|
||||||
final Property<String> cmgenArgs
|
|
||||||
final RegularFileProperty iblInputFile
|
|
||||||
final DirectoryProperty iblOutputDir
|
|
||||||
final RegularFileProperty meshInputFile
|
|
||||||
final DirectoryProperty meshOutputDir
|
|
||||||
|
|
||||||
FilamentExtension(Project project) {
|
|
||||||
this.tools = new ToolsLocator(project)
|
|
||||||
this.materialInputDir = project.objects.directoryProperty()
|
|
||||||
this.materialOutputDir = project.objects.directoryProperty()
|
|
||||||
this.cmgenArgs = project.objects.property(String)
|
|
||||||
this.iblInputFile = project.objects.fileProperty()
|
|
||||||
this.iblOutputDir = project.objects.directoryProperty()
|
|
||||||
this.meshInputFile = project.objects.fileProperty()
|
|
||||||
this.meshOutputDir = project.objects.directoryProperty()
|
|
||||||
}
|
|
||||||
|
|
||||||
void matc(Action<ToolsLocator.ToolConfig> action) {
|
|
||||||
action.execute(tools.matc)
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmgen(Action<ToolsLocator.ToolConfig> action) {
|
|
||||||
action.execute(tools.cmgen)
|
|
||||||
}
|
|
||||||
|
|
||||||
void filamesh(Action<ToolsLocator.ToolConfig> action) {
|
|
||||||
action.execute(tools.filamesh)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.Plugin
|
|
||||||
import org.gradle.api.Project
|
|
||||||
|
|
||||||
class FilamentPlugin implements Plugin<Project> {
|
|
||||||
@Override
|
|
||||||
void apply(Project project) {
|
|
||||||
project.pluginManager.apply("com.google.osdetector")
|
|
||||||
|
|
||||||
FilamentExtension extension = project.extensions.create("filament", FilamentExtension, project)
|
|
||||||
|
|
||||||
project.afterEvaluate {
|
|
||||||
extension.tools.resolve(project)
|
|
||||||
|
|
||||||
project.tasks.register("filamentCompileMaterials", MaterialCompileTask) {
|
|
||||||
enabled = extension.materialInputDir.isPresent() && extension.materialOutputDir.isPresent()
|
|
||||||
inputDir.set(extension.materialInputDir.getOrNull())
|
|
||||||
outputDir.set(extension.materialOutputDir.getOrNull())
|
|
||||||
matcTool.from(extension.tools.matcToolFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
project.tasks.register("filamentGenerateIbl", IblGenerateTask) {
|
|
||||||
enabled = extension.iblInputFile.isPresent() && extension.iblOutputDir.isPresent()
|
|
||||||
cmgenArgs = extension.cmgenArgs
|
|
||||||
inputFile.set(extension.iblInputFile.getOrNull())
|
|
||||||
outputDir.set(extension.iblOutputDir.getOrNull())
|
|
||||||
cmgenTool.from(extension.tools.cmgenToolFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
project.tasks.register("filamentCompileMesh", MeshCompileTask) {
|
|
||||||
enabled = extension.meshInputFile.isPresent() && extension.meshOutputDir.isPresent()
|
|
||||||
inputFile = extension.meshInputFile.getOrNull()
|
|
||||||
outputDir = extension.meshOutputDir.getOrNull()
|
|
||||||
filameshTool.from(extension.tools.filameshToolFiles)
|
|
||||||
}
|
|
||||||
|
|
||||||
project.preBuild.dependsOn "filamentCompileMaterials"
|
|
||||||
project.preBuild.dependsOn "filamentGenerateIbl"
|
|
||||||
project.preBuild.dependsOn "filamentCompileMesh"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.GradleException
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
|
||||||
import org.gradle.api.file.DirectoryProperty
|
|
||||||
import org.gradle.api.file.FileSystemOperations
|
|
||||||
import org.gradle.api.file.FileType
|
|
||||||
import org.gradle.api.file.RegularFileProperty
|
|
||||||
import org.gradle.api.model.ObjectFactory
|
|
||||||
import org.gradle.api.provider.Property
|
|
||||||
import org.gradle.api.tasks.Input
|
|
||||||
import org.gradle.api.tasks.InputFile
|
|
||||||
import org.gradle.api.tasks.InputFiles
|
|
||||||
import org.gradle.api.tasks.Optional
|
|
||||||
import org.gradle.api.tasks.OutputDirectory
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
|
||||||
import org.gradle.process.ExecOperations
|
|
||||||
import org.gradle.work.ChangeType
|
|
||||||
import org.gradle.work.Incremental
|
|
||||||
import org.gradle.work.InputChanges
|
|
||||||
import org.gradle.api.tasks.incremental.InputFileDetails
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
abstract class IblGenerateTask extends DefaultTask {
|
|
||||||
|
|
||||||
@Input
|
|
||||||
@Optional
|
|
||||||
abstract Property<String> getCmgenArgs()
|
|
||||||
|
|
||||||
@Incremental
|
|
||||||
@InputFile
|
|
||||||
abstract RegularFileProperty getInputFile()
|
|
||||||
|
|
||||||
@OutputDirectory
|
|
||||||
abstract DirectoryProperty getOutputDir()
|
|
||||||
|
|
||||||
@InputFiles
|
|
||||||
abstract ConfigurableFileCollection getCmgenTool()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract FileSystemOperations getFileSystemOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ExecOperations getExecOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ObjectFactory getObjectFactory()
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
void execute(InputChanges inputs) {
|
|
||||||
if (cmgenTool.empty) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"cmgen executable not configured. Please configure the 'cmgen' block in the " +
|
|
||||||
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
|
|
||||||
"property."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
File cmgen = getCmgenTool().singleFile
|
|
||||||
if (!cmgen.exists()) {
|
|
||||||
throw new IllegalStateException("cmgen executable does not exist: ${cmgen.absolutePath}")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmgen.canExecute()) {
|
|
||||||
cmgen.setExecutable(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inputs.incremental) {
|
|
||||||
getFileSystemOperations().delete {
|
|
||||||
delete(getObjectFactory().fileTree().from(getOutputDir()).matching { include '*' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inputs.getFileChanges(getInputFile()).each { InputFileDetails change ->
|
|
||||||
if (change.fileType == FileType.DIRECTORY) return
|
|
||||||
|
|
||||||
def file = change.file
|
|
||||||
|
|
||||||
if (change.changeType == ChangeType.REMOVED) {
|
|
||||||
computeOutputFile(file).delete()
|
|
||||||
} else {
|
|
||||||
println "Generating IBL: ${file.name}"
|
|
||||||
|
|
||||||
def outputPath = getOutputDir().get().asFile
|
|
||||||
def commandArgs = getCmgenArgs().getOrNull()
|
|
||||||
if (commandArgs == null) {
|
|
||||||
// Default args if not provided
|
|
||||||
commandArgs = '-q -x ' + outputPath + ' --format=rgb32f ' +
|
|
||||||
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
|
||||||
}
|
|
||||||
|
|
||||||
def argsList = commandArgs.split(' ').toList()
|
|
||||||
argsList.add(file.absolutePath)
|
|
||||||
|
|
||||||
getExecOperations().exec { spec ->
|
|
||||||
spec.executable(cmgen)
|
|
||||||
spec.args(argsList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File computeOutputFile(final File file) {
|
|
||||||
String name = file.name
|
|
||||||
int dotIndex = name.lastIndexOf('.')
|
|
||||||
String baseName = dotIndex > 0 ? name.substring(0, dotIndex) : name
|
|
||||||
return getOutputDir().file(baseName).get().asFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
|
||||||
import org.gradle.api.file.DirectoryProperty
|
|
||||||
import org.gradle.api.file.FileSystemOperations
|
|
||||||
import org.gradle.api.file.FileType
|
|
||||||
import org.gradle.api.model.ObjectFactory
|
|
||||||
import org.gradle.api.provider.ProviderFactory
|
|
||||||
import org.gradle.api.tasks.InputDirectory
|
|
||||||
import org.gradle.api.tasks.InputFiles
|
|
||||||
import org.gradle.api.tasks.OutputDirectory
|
|
||||||
import org.gradle.api.tasks.PathSensitive
|
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
|
||||||
import org.gradle.api.tasks.SkipWhenEmpty
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
|
||||||
import org.gradle.process.ExecOperations
|
|
||||||
import org.gradle.work.ChangeType
|
|
||||||
import org.gradle.work.Incremental
|
|
||||||
import org.gradle.work.InputChanges
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
abstract class MaterialCompileTask extends DefaultTask {
|
|
||||||
|
|
||||||
@Incremental
|
|
||||||
@InputDirectory
|
|
||||||
@PathSensitive(PathSensitivity.RELATIVE)
|
|
||||||
abstract DirectoryProperty getInputDir()
|
|
||||||
|
|
||||||
@OutputDirectory
|
|
||||||
abstract DirectoryProperty getOutputDir()
|
|
||||||
|
|
||||||
@InputFiles
|
|
||||||
@PathSensitive(PathSensitivity.NONE)
|
|
||||||
abstract ConfigurableFileCollection getMatcTool()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ExecOperations getExecOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract FileSystemOperations getFileSystemOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ObjectFactory getObjectFactory()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ProviderFactory getProviderFactory()
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
void compile(InputChanges inputs) {
|
|
||||||
if (matcTool.empty) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"matc executable not configured. Please configure the 'matc' block in the " +
|
|
||||||
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
|
|
||||||
"property."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
File matc = matcTool.singleFile
|
|
||||||
if (!matc.exists()) {
|
|
||||||
throw new IllegalStateException("matc executable does not exist: ${matc.absolutePath}")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!matc.canExecute()) {
|
|
||||||
matc.setExecutable(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inputs.incremental) {
|
|
||||||
getFileSystemOperations().delete {
|
|
||||||
delete(getObjectFactory().fileTree().from(getOutputDir()).matching {
|
|
||||||
include '*.filamat'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def pf = getProviderFactory()
|
|
||||||
def excludeVulkanProperty = pf.gradleProperty("com.google.android.filament.exclude-vulkan")
|
|
||||||
def includeWebGpuProperty = pf.gradleProperty("com.google.android.filament.include-webgpu")
|
|
||||||
def matNoOptProperty = pf.gradleProperty("com.google.android.filament.matnopt")
|
|
||||||
def excludeVulkan = excludeVulkanProperty.orNull == "true"
|
|
||||||
def includeWebGpu = includeWebGpuProperty.orNull == "true"
|
|
||||||
def matNoOpt = matNoOptProperty.orNull == "true"
|
|
||||||
|
|
||||||
inputs.getFileChanges(getInputDir()).each { change ->
|
|
||||||
if (change.fileType == FileType.DIRECTORY) return
|
|
||||||
|
|
||||||
File file = change.file
|
|
||||||
File outputFile = computeOutputFile(file)
|
|
||||||
|
|
||||||
if (change.changeType == ChangeType.REMOVED) {
|
|
||||||
outputFile.delete()
|
|
||||||
} else {
|
|
||||||
println "Compiling material: ${file.name}"
|
|
||||||
|
|
||||||
def args = []
|
|
||||||
if (!excludeVulkan) {
|
|
||||||
args += ['-a', 'vulkan']
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeWebGpu) {
|
|
||||||
args += ['-a', 'webgpu', '--variant-filter=stereo']
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matNoOpt) {
|
|
||||||
args += ['-g']
|
|
||||||
}
|
|
||||||
|
|
||||||
args += [
|
|
||||||
'-a', 'opengl', '-p', 'mobile',
|
|
||||||
'-o', outputFile.absolutePath,
|
|
||||||
file.absolutePath
|
|
||||||
]
|
|
||||||
|
|
||||||
getExecOperations().exec { spec ->
|
|
||||||
spec.executable(matc)
|
|
||||||
spec.args(args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File computeOutputFile(File inputFile) {
|
|
||||||
String baseName = inputFile.name
|
|
||||||
int dotIndex = baseName.lastIndexOf('.')
|
|
||||||
if (dotIndex > 0) {
|
|
||||||
baseName = baseName.substring(0, dotIndex)
|
|
||||||
}
|
|
||||||
return getOutputDir().file("${baseName}.filamat").get().asFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
|
||||||
import org.gradle.api.file.DirectoryProperty
|
|
||||||
import org.gradle.api.file.FileSystemOperations
|
|
||||||
import org.gradle.api.file.FileType
|
|
||||||
import org.gradle.api.file.RegularFileProperty
|
|
||||||
import org.gradle.api.model.ObjectFactory
|
|
||||||
import org.gradle.api.tasks.InputFile
|
|
||||||
import org.gradle.api.tasks.InputFiles
|
|
||||||
import org.gradle.api.tasks.OutputDirectory
|
|
||||||
import org.gradle.api.tasks.PathSensitive
|
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
|
||||||
import org.gradle.process.ExecOperations
|
|
||||||
import org.gradle.work.ChangeType
|
|
||||||
import org.gradle.work.Incremental
|
|
||||||
import org.gradle.work.InputChanges
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
abstract class MeshCompileTask extends DefaultTask {
|
|
||||||
|
|
||||||
@Incremental
|
|
||||||
@InputFile
|
|
||||||
@PathSensitive(PathSensitivity.RELATIVE)
|
|
||||||
abstract RegularFileProperty getInputFile()
|
|
||||||
|
|
||||||
@OutputDirectory
|
|
||||||
abstract DirectoryProperty getOutputDir()
|
|
||||||
|
|
||||||
@InputFiles
|
|
||||||
@PathSensitive(PathSensitivity.NONE)
|
|
||||||
abstract ConfigurableFileCollection getFilameshTool()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ExecOperations getExecOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract FileSystemOperations getFileSystemOperations()
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
abstract ObjectFactory getObjectFactory()
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
void compile(InputChanges inputs) {
|
|
||||||
if (filameshTool.empty) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"filamesh executable not configured. Please configure the 'filamesh' block in the " +
|
|
||||||
"'filament' extension or set the 'com.google.android.filament.tools-dir' " +
|
|
||||||
"property."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
File filamesh = filameshTool.singleFile
|
|
||||||
if (!filamesh.exists()) {
|
|
||||||
throw new IllegalStateException("filamesh executable does not exist: ${filamesh.absolutePath}")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filamesh.canExecute()) {
|
|
||||||
filamesh.setExecutable(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inputs.incremental) {
|
|
||||||
getFileSystemOperations().delete {
|
|
||||||
delete(getObjectFactory().fileTree().from(getOutputDir()).matching {
|
|
||||||
include '*.filamesh'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inputs.getFileChanges(inputFile).each { change ->
|
|
||||||
if (change.fileType == FileType.DIRECTORY) return
|
|
||||||
|
|
||||||
File file = change.file
|
|
||||||
File outputFile = computeOutputFile(file)
|
|
||||||
|
|
||||||
if (change.changeType == ChangeType.REMOVED) {
|
|
||||||
outputFile.delete()
|
|
||||||
} else {
|
|
||||||
println "Compiling mesh: ${file.name}"
|
|
||||||
|
|
||||||
getExecOperations().exec { spec ->
|
|
||||||
spec.executable(filamesh)
|
|
||||||
spec.args(file.absolutePath, outputFile.absolutePath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File computeOutputFile(File inputFile) {
|
|
||||||
String baseName = inputFile.name
|
|
||||||
int dotIndex = baseName.lastIndexOf('.')
|
|
||||||
if (dotIndex > 0) {
|
|
||||||
baseName = baseName.substring(0, dotIndex)
|
|
||||||
}
|
|
||||||
return getOutputDir().file("${baseName}.filamesh").get().asFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.gradle
|
|
||||||
|
|
||||||
import org.gradle.api.Action
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.artifacts.Configuration
|
|
||||||
import org.gradle.api.file.FileCollection
|
|
||||||
import org.gradle.internal.os.OperatingSystem
|
|
||||||
|
|
||||||
import java.nio.file.Paths
|
|
||||||
|
|
||||||
class ToolsLocator {
|
|
||||||
static class ToolConfig {
|
|
||||||
String artifact
|
|
||||||
String path
|
|
||||||
FileCollection files
|
|
||||||
}
|
|
||||||
|
|
||||||
final ToolConfig matc = new ToolConfig()
|
|
||||||
final ToolConfig cmgen = new ToolConfig()
|
|
||||||
final ToolConfig filamesh = new ToolConfig()
|
|
||||||
private final Project project
|
|
||||||
|
|
||||||
ToolsLocator(Project project) {
|
|
||||||
this.project = project
|
|
||||||
}
|
|
||||||
|
|
||||||
void resolve(Project project) {
|
|
||||||
resolveTool(matc, "matc")
|
|
||||||
resolveTool(cmgen, "cmgen")
|
|
||||||
resolveTool(filamesh, "filamesh")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves a specific tool by its name and sets the {@link ToolConfig#files} property of the
|
|
||||||
* provided {@link ToolConfig} object. It first attempts to locate the tool based on a Gradle
|
|
||||||
* property `com.google.android.filament.tools-dir` if present, otherwise it resolves the tool
|
|
||||||
* through a Gradle configuration.
|
|
||||||
*
|
|
||||||
* @param tool The {@link ToolConfig} object whose {@code files} property will be set.
|
|
||||||
* @param name The name of the tool (e.g., "matc", "cmgen").
|
|
||||||
*/
|
|
||||||
private void resolveTool(ToolConfig tool, String name) {
|
|
||||||
// Find the OS classifier, e.g. 'osx-aarch_64'.
|
|
||||||
def classifier =
|
|
||||||
project.extensions.getByType(com.google.gradle.osdetector.OsDetector).classifier
|
|
||||||
|
|
||||||
// If com.google.android.filament.tools-dir is set, we'll use it as the tool's base path.
|
|
||||||
def toolsDirProp = project.providers.gradleProperty("com.google.android.filament.tools-dir")
|
|
||||||
if (toolsDirProp.isPresent()) {
|
|
||||||
def toolsDir = toolsDirProp.get()
|
|
||||||
def path = OperatingSystem.current().isWindows() ?
|
|
||||||
"${toolsDir}/bin/${name}.exe" :
|
|
||||||
"${toolsDir}/bin/${name}"
|
|
||||||
tool.files = project.files(path)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an explicit path for the tool is provided in ToolConfig
|
|
||||||
// (e.g. matc { path = 'path/to/tool' }), use it directly.
|
|
||||||
if (tool.path) {
|
|
||||||
tool.files = project.files(tool.path)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, if an artifact is provided
|
|
||||||
// (e.g. matc { artifact = 'com.google.android.filament:matc:1.68.5' }), resolve it.
|
|
||||||
if (tool.artifact) {
|
|
||||||
String depString = tool.artifact
|
|
||||||
|
|
||||||
// In Gradle, a configuration is a named, manageable group of dependencies.
|
|
||||||
// Resolve the tool artifact using a detached configuration. A detached configuration
|
|
||||||
// is a temporary, isolated configuration that is not part of the project's regular
|
|
||||||
// configuration hierarchy.
|
|
||||||
Configuration config = project.configurations.detachedConfiguration()
|
|
||||||
config.setTransitive(false) // We only want the tool itself, not its dependencies
|
|
||||||
|
|
||||||
def dep = project.dependencies.create("${depString}:${classifier}@exe")
|
|
||||||
config.dependencies.add(dep)
|
|
||||||
|
|
||||||
// A Gradle Configuration implements FileCollection. When treated as a FileCollection,
|
|
||||||
// it represents the resolved files of its dependencies.
|
|
||||||
tool.files = config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileCollection getMatcToolFiles() {
|
|
||||||
return matc.files ?: project.files()
|
|
||||||
}
|
|
||||||
|
|
||||||
FileCollection getCmgenToolFiles() {
|
|
||||||
return cmgen.files ?: project.files()
|
|
||||||
}
|
|
||||||
|
|
||||||
FileCollection getFilameshToolFiles() {
|
|
||||||
return filamesh.files ?: project.files()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -335,13 +335,6 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefract
|
|||||||
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
|
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
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
|
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
|
||||||
jclass, jlong nativeBuilder, jint type) {
|
jclass, jlong nativeBuilder, jint type) {
|
||||||
|
|||||||
@@ -177,11 +177,6 @@ public class MaterialBuilder {
|
|||||||
SCREEN_SPACE
|
SCREEN_SPACE
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ReflectionMode {
|
|
||||||
DEFAULT,
|
|
||||||
SCREEN_SPACE
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum RefractionType {
|
public enum RefractionType {
|
||||||
SOLID,
|
SOLID,
|
||||||
THIN
|
THIN
|
||||||
@@ -408,12 +403,6 @@ public class MaterialBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public MaterialBuilder reflectionMode(ReflectionMode mode) {
|
|
||||||
nMaterialBuilderReflectionMode(mNativeObject, mode.ordinal());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public MaterialBuilder refractionType(RefractionType type) {
|
public MaterialBuilder refractionType(RefractionType type) {
|
||||||
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
|
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
|
||||||
@@ -615,7 +604,6 @@ public class MaterialBuilder {
|
|||||||
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
|
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
|
||||||
float threshold);
|
float threshold);
|
||||||
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
|
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 nMaterialBuilderRefractionType(long nativeBuilder, int type);
|
||||||
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
||||||
boolean clearCoatIorChange);
|
boolean clearCoatIorChange);
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ add_library(bluevk STATIC IMPORTED)
|
|||||||
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
|
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
|
${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)
|
if (FILAMENT_SUPPORTS_WEBGPU)
|
||||||
add_library(webgpu_dawn STATIC IMPORTED)
|
add_library(webgpu_dawn STATIC IMPORTED)
|
||||||
set_target_properties(webgpu_dawn PROPERTIES IMPORTED_LOCATION
|
set_target_properties(webgpu_dawn PROPERTIES IMPORTED_LOCATION
|
||||||
@@ -134,7 +138,6 @@ target_include_directories(filament-jni PRIVATE
|
|||||||
../../filament/backend/include
|
../../filament/backend/include
|
||||||
../../third_party/robin-map
|
../../third_party/robin-map
|
||||||
../../third_party/perfetto
|
../../third_party/perfetto
|
||||||
../../libs/bluevk/include
|
|
||||||
../../libs/utils/include)
|
../../libs/utils/include)
|
||||||
|
|
||||||
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
|
# 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>:matdbg>
|
||||||
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
||||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
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_VULKAN},ON>:smol-v>
|
||||||
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
|
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
|
||||||
)
|
)
|
||||||
|
|
||||||
# Force a relink when the version script is changed:
|
# Force a relink when the version script is changed:
|
||||||
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
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()
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <filament/Camera.h>
|
#include <filament/Camera.h>
|
||||||
|
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
|
|
||||||
#include <math/mat4.h>
|
#include <math/mat4.h>
|
||||||
@@ -41,13 +40,6 @@ Java_com_google_android_filament_Camera_nSetProjectionFov(JNIEnv*, jclass ,
|
|||||||
camera->setProjection(fovInDegrees, aspect, near, far, (Camera::Fov) fov);
|
camera->setProjection(fovInDegrees, aspect, near, far, (Camera::Fov) fov);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jdouble JNICALL
|
|
||||||
Java_com_google_android_filament_Camera_nGetFieldOfViewInDegrees(JNIEnv*, jclass,
|
|
||||||
jlong nativeCamera, jint direction) {
|
|
||||||
Camera *camera = (Camera *) nativeCamera;
|
|
||||||
return camera->getFieldOfViewInDegrees((Camera::Fov) direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
|
Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
|
||||||
jlong nativeCamera, jdouble focalLength, jdouble aspect, jdouble near, jdouble far) {
|
jlong nativeCamera, jdouble focalLength, jdouble aspect, jdouble near, jdouble far) {
|
||||||
@@ -70,21 +62,6 @@ Java_com_google_android_filament_Camera_nSetCustomProjection(JNIEnv *env, jclass
|
|||||||
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
|
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_Camera_nSetCustomEyeProjection(JNIEnv *env, jclass,
|
|
||||||
jlong nativeCamera, jdoubleArray inProjection_, jint count, jdoubleArray inProjectionForCulling_,
|
|
||||||
jdouble near, jdouble far) {
|
|
||||||
Camera *camera = (Camera *) nativeCamera;
|
|
||||||
jdouble *inProjection = env->GetDoubleArrayElements(inProjection_, NULL);
|
|
||||||
jdouble *inProjectionForCulling = env->GetDoubleArrayElements(inProjectionForCulling_, NULL);
|
|
||||||
camera->setCustomEyeProjection(
|
|
||||||
reinterpret_cast<const filament::math::mat4 *>(inProjection), (size_t) count,
|
|
||||||
*reinterpret_cast<const filament::math::mat4 *>(inProjectionForCulling),
|
|
||||||
near, far);
|
|
||||||
env->ReleaseDoubleArrayElements(inProjection_, inProjection, JNI_ABORT);
|
|
||||||
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
|
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
|
||||||
jlong nativeCamera, jdouble x, jdouble y) {
|
jlong nativeCamera, jdouble x, jdouble y) {
|
||||||
@@ -99,17 +76,6 @@ Java_com_google_android_filament_Camera_nSetShift(JNIEnv* env, jclass,
|
|||||||
camera->setShift({(double)x, (double)y});
|
camera->setShift({(double)x, (double)y});
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_Camera_nGetShift(JNIEnv* env, jclass,
|
|
||||||
jlong nativeCamera, jdoubleArray out_) {
|
|
||||||
Camera *camera = (Camera *) nativeCamera;
|
|
||||||
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
|
|
||||||
filament::math::double2 s = camera->getShift();
|
|
||||||
out[0] = s.x;
|
|
||||||
out[1] = s.y;
|
|
||||||
env->ReleaseDoubleArrayElements(out_, out, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Camera_nLookAt(JNIEnv*, jclass, jlong nativeCamera,
|
Java_com_google_android_filament_Camera_nLookAt(JNIEnv*, jclass, jlong nativeCamera,
|
||||||
jdouble eye_x, jdouble eye_y, jdouble eye_z, jdouble center_x, jdouble center_y,
|
jdouble eye_x, jdouble eye_y, jdouble eye_z, jdouble center_x, jdouble center_y,
|
||||||
@@ -149,15 +115,6 @@ Java_com_google_android_filament_Camera_nSetModelMatrixFp64(JNIEnv *env, jclass,
|
|||||||
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
|
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_Camera_nSetEyeModelMatrix(JNIEnv *env, jclass,
|
|
||||||
jlong nativeCamera, jint eyeId, jdoubleArray model_) {
|
|
||||||
Camera* camera = (Camera *) nativeCamera;
|
|
||||||
jdouble *model = env->GetDoubleArrayElements(model_, NULL);
|
|
||||||
camera->setEyeModelMatrix((uint8_t)eyeId, *reinterpret_cast<const filament::math::mat4*>(model));
|
|
||||||
env->ReleaseDoubleArrayElements(model_, model, JNI_ABORT);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
|
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
|
||||||
jlong nativeCamera, jdoubleArray out_) {
|
jlong nativeCamera, jdoubleArray out_) {
|
||||||
@@ -323,5 +280,3 @@ Java_com_google_android_filament_Camera_nComputeEffectiveFov(JNIEnv*, jclass,
|
|||||||
jdouble fovInDegrees, jdouble focusDistance) {
|
jdouble fovInDegrees, jdouble focusDistance) {
|
||||||
return Camera::computeEffectiveFov(fovInDegrees, focusDistance);
|
return Camera::computeEffectiveFov(fovInDegrees, focusDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <filament/Camera.h>
|
#include <filament/Camera.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/MorphTargetBuffer.h>
|
|
||||||
|
|
||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
#include <utils/EntityManager.h>
|
#include <utils/EntityManager.h>
|
||||||
@@ -208,14 +207,6 @@ Java_com_google_android_filament_Engine_nDestroySkinningBuffer(JNIEnv*, jclass,
|
|||||||
return engine->destroy(skinningBuffer);
|
return engine->destroy(skinningBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_Engine_nDestroyMorphTargetBuffer(JNIEnv*, jclass,
|
|
||||||
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
MorphTargetBuffer* mtb = (MorphTargetBuffer*) nativeMorphTargetBuffer;
|
|
||||||
return engine->destroy(mtb);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
|
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
|
||||||
jlong nativeEngine, jlong nativeIndirectLight) {
|
jlong nativeEngine, jlong nativeIndirectLight) {
|
||||||
@@ -337,13 +328,6 @@ Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass,
|
|||||||
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
|
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_Engine_nIsValidMorphTargetBuffer(JNIEnv*, jclass,
|
|
||||||
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
|
|
||||||
Engine* engine = (Engine*) nativeEngine;
|
|
||||||
return (jboolean) engine->isValid((MorphTargetBuffer*) nativeMorphTargetBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
|
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
|
||||||
jlong nativeEngine, jlong nativeIndirectLight) {
|
jlong nativeEngine, jlong nativeIndirectLight) {
|
||||||
@@ -573,8 +557,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
|
|||||||
jboolean disableHandleUseAfterFreeCheck,
|
jboolean disableHandleUseAfterFreeCheck,
|
||||||
jint preferredShaderLanguage,
|
jint preferredShaderLanguage,
|
||||||
jboolean forceGLES2Context, jboolean assertNativeWindowIsValid,
|
jboolean forceGLES2Context, jboolean assertNativeWindowIsValid,
|
||||||
jint gpuContextPriority,
|
jint gpuContextPriority) {
|
||||||
jlong sharedUboInitialSizeInBytes) {
|
|
||||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||||
Engine::Config config = {
|
Engine::Config config = {
|
||||||
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
|
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
|
||||||
@@ -593,7 +576,6 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
|
|||||||
.forceGLES2Context = (bool) forceGLES2Context,
|
.forceGLES2Context = (bool) forceGLES2Context,
|
||||||
.assertNativeWindowIsValid = (bool) assertNativeWindowIsValid,
|
.assertNativeWindowIsValid = (bool) assertNativeWindowIsValid,
|
||||||
.gpuContextPriority = (Engine::GpuContextPriority) gpuContextPriority,
|
.gpuContextPriority = (Engine::GpuContextPriority) gpuContextPriority,
|
||||||
.sharedUboInitialSizeInBytes = (uint32_t) sharedUboInitialSizeInBytes,
|
|
||||||
};
|
};
|
||||||
builder->config(&config);
|
builder->config(&config);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ using namespace filament;
|
|||||||
|
|
||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
|
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;
|
Engine* engine = (Engine*) nativeEngine;
|
||||||
AutoBuffer buffer(env, buffer_, size);
|
AutoBuffer buffer(env, buffer_, size);
|
||||||
auto builder = Material::Builder();
|
auto builder = Material::Builder();
|
||||||
@@ -33,7 +33,6 @@ Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
|
|||||||
builder.sphericalHarmonicsBandCount(shBandCount);
|
builder.sphericalHarmonicsBandCount(shBandCount);
|
||||||
}
|
}
|
||||||
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
|
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
|
||||||
builder.uboBatching((Material::UboBatchingMode)uboBatchingMode);
|
|
||||||
Material* material = builder
|
Material* material = builder
|
||||||
.package(buffer.getData(), buffer.getSize())
|
.package(buffer.getData(), buffer.getSize())
|
||||||
.build(*engine);
|
.build(*engine);
|
||||||
@@ -96,14 +95,6 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
|
|||||||
return (jint) material->getBlendingMode();
|
return (jint) material->getBlendingMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_Material_nGetTransparencyMode(JNIEnv*, jclass,
|
|
||||||
jlong nativeMaterial) {
|
|
||||||
Material* material = (Material*) nativeMaterial;
|
|
||||||
return (jint) material->getTransparencyMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
@@ -288,17 +279,6 @@ Java_com_google_android_filament_Material_nHasParameter(JNIEnv* env, jclass,
|
|||||||
return (jboolean) hasParameter;
|
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"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Material_nCompile(JNIEnv *env, jclass clazz,
|
Java_com_google_android_filament_Material_nCompile(JNIEnv *env, jclass clazz,
|
||||||
|
|||||||
@@ -564,19 +564,3 @@ Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jcl
|
|||||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||||
return (jint)instance->getDepthFunc();
|
return (jint)instance->getDepthFunc();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_MaterialInstance_nSetTransparencyMode(JNIEnv*, jclass,
|
|
||||||
jlong nativeMaterialInstance, jint mode) {
|
|
||||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
|
||||||
instance->setTransparencyMode((MaterialInstance::TransparencyMode) mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_MaterialInstance_nGetTransparencyMode(JNIEnv*, jclass,
|
|
||||||
jlong nativeMaterialInstance) {
|
|
||||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
|
||||||
return (jint) instance->getTransparencyMode();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -58,27 +58,6 @@ Java_com_google_android_filament_MorphTargetBuffer_nBuilderCount(JNIEnv*, jclass
|
|||||||
builder->count((size_t) count);
|
builder->count((size_t) count);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithPositions(JNIEnv*, jclass,
|
|
||||||
jlong nativeBuilder, jboolean enabled) {
|
|
||||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
|
|
||||||
builder->withPositions(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithTangents(JNIEnv*, jclass,
|
|
||||||
jlong nativeBuilder, jboolean enabled) {
|
|
||||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
|
|
||||||
builder->withTangents(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderEnableCustomMorphing(JNIEnv*,
|
|
||||||
jclass, jlong nativeBuilder, jboolean enabled) {
|
|
||||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
|
|
||||||
builder->enableCustomMorphing(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jlong JNICALL
|
JNIEXPORT jlong JNICALL
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
|
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
|
||||||
@@ -133,24 +112,3 @@ Java_com_google_android_filament_MorphTargetBuffer_nGetCount(JNIEnv*, jclass,
|
|||||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||||
return (jint)morphTargetBuffer->getCount();
|
return (jint)morphTargetBuffer->getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nHasPositions(JNIEnv*, jclass,
|
|
||||||
jlong nativeObject) {
|
|
||||||
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
|
|
||||||
return (jboolean) morphTargetBuffer->hasPositions();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nHasTangents(JNIEnv*, jclass,
|
|
||||||
jlong nativeObject) {
|
|
||||||
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
|
|
||||||
return (jboolean) morphTargetBuffer->hasTangents();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_MorphTargetBuffer_nIsCustomMorphingEnabled(JNIEnv*, jclass,
|
|
||||||
jlong nativeObject) {
|
|
||||||
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
|
|
||||||
return (jboolean) morphTargetBuffer->isCustomMorphingEnabled();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -366,13 +366,6 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
|
|||||||
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
|
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nGetPriority(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jint) rm->getPriority((RenderableManager::Instance) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
|
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
|
||||||
jlong nativeRenderableManager, jint i, jint channel) {
|
jlong nativeRenderableManager, jint i, jint channel) {
|
||||||
@@ -380,13 +373,6 @@ Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
|
|||||||
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
|
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nGetChannel(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jint) rm->getChannel((RenderableManager::Instance) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
|
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
|
||||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||||
@@ -394,13 +380,6 @@ Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
|
|||||||
rm->setCulling((RenderableManager::Instance) i, enabled);
|
rm->setCulling((RenderableManager::Instance) i, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nIsCullingEnabled(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jboolean) rm->isCullingEnabled((RenderableManager::Instance) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nSetFogEnabled(JNIEnv*, jclass,
|
Java_com_google_android_filament_RenderableManager_nSetFogEnabled(JNIEnv*, jclass,
|
||||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||||
@@ -450,13 +429,6 @@ Java_com_google_android_filament_RenderableManager_nIsShadowReceiver(JNIEnv*, jc
|
|||||||
return (jboolean) rm->isShadowReceiver((RenderableManager::Instance) i);
|
return (jboolean) rm->isShadowReceiver((RenderableManager::Instance) i);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nIsScreenSpaceContactShadowsEnabled(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jboolean) rm->isScreenSpaceContactShadowsEnabled((RenderableManager::Instance) i);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nGetAxisAlignedBoundingBox(JNIEnv* env,
|
Java_com_google_android_filament_RenderableManager_nGetAxisAlignedBoundingBox(JNIEnv* env,
|
||||||
jclass, jlong nativeRenderableManager, jint i, jfloatArray center_,
|
jclass, jlong nativeRenderableManager, jint i, jfloatArray center_,
|
||||||
@@ -528,13 +500,6 @@ Java_com_google_android_filament_RenderableManager_nSetBlendOrderAt(JNIEnv*, jcl
|
|||||||
(uint16_t) blendOrder);
|
(uint16_t) blendOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nGetBlendOrderAt(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jint) rm->getBlendOrderAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
|
Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
|
||||||
jlong nativeRenderableManager, jint i, jint primitiveIndex, jboolean enabled) {
|
jlong nativeRenderableManager, jint i, jint primitiveIndex, jboolean enabled) {
|
||||||
@@ -543,13 +508,6 @@ Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt
|
|||||||
(bool) enabled);
|
(bool) enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_RenderableManager_nIsGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
|
|
||||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
|
||||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
|
||||||
return (jboolean) rm->isGlobalBlendOrderEnabledAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEnv*, jclass,
|
Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEnv*, jclass,
|
||||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
||||||
|
|||||||
@@ -208,19 +208,3 @@ Java_com_google_android_filament_Renderer_nSetVsyncTime(JNIEnv *, jclass,
|
|||||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||||
renderer->setVsyncTime(steadyClockTimeNano);
|
renderer->setVsyncTime(steadyClockTimeNano);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_Renderer_nSkipNextFrames(JNIEnv *, jclass ,
|
|
||||||
jlong nativeRenderer, jint frameCount) {
|
|
||||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
|
||||||
renderer->skipNextFrames(frameCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_Renderer_nGetFrameToSkipCount(JNIEnv *, jclass ,
|
|
||||||
jlong nativeRenderer) {
|
|
||||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
|
||||||
return renderer->getFrameToSkipCount();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -63,14 +63,6 @@ Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
|
|||||||
builder->color({r, g, b, a});
|
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
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
|
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
|
||||||
jlong nativeSkyBoxBuilder, jlong nativeEngine) {
|
jlong nativeSkyBoxBuilder, jlong nativeEngine) {
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
|
|||||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
||||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||||
auto* callback = JniCallback::make(env, handler, runnable);
|
auto* callback = JniCallback::make(env, handler, runnable);
|
||||||
swapChain->setFrameCompletedCallback(callback->getHandler(),
|
swapChain->setFrameCompletedCallback(nullptr, [callback](SwapChain* swapChain) {
|
||||||
[callback](SwapChain* swapChain) { JniCallback::postToJavaAndDestroy(callback); });
|
JniCallback::postToJavaAndDestroy(callback);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
@@ -52,22 +53,3 @@ Java_com_google_android_filament_SwapChain_nIsProtectedContentSupported(
|
|||||||
Engine* engine = (Engine*) nativeEngine;
|
Engine* engine = (Engine*) nativeEngine;
|
||||||
return (jboolean)SwapChain::isProtectedContentSupported(*engine);
|
return (jboolean)SwapChain::isProtectedContentSupported(*engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_SwapChain_nSetFrameScheduledCallback(JNIEnv* env, jclass,
|
|
||||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
|
||||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
|
||||||
auto* callback = JniCallback::make(env, handler, runnable);
|
|
||||||
swapChain->setFrameScheduledCallback(callback->getHandler(),
|
|
||||||
[callback](backend::PresentCallable) {
|
|
||||||
// Ignore PresentCallable, which is only meaningful with the Metal backend.
|
|
||||||
JniCallback::postToJavaAndDestroy(callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_SwapChain_nIsFrameScheduledCallbackSet(
|
|
||||||
JNIEnv *, jclass, jlong nativeSwapChain) {
|
|
||||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
|
||||||
return (jboolean)swapChain->isFrameScheduledCallbackSet();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,11 +21,6 @@
|
|||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include <android/bitmap.h>
|
#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
|
#endif
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
@@ -173,13 +168,6 @@ Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
|
|||||||
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
|
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_Texture_nBuilderSamples(JNIEnv*, jclass,
|
|
||||||
jlong nativeBuilder, jint samples) {
|
|
||||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
|
||||||
builder->samples((uint8_t) samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
|
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
|
||||||
@@ -400,57 +388,6 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon
|
|||||||
texture->setExternalImage(*engine, (void*)eglImage);
|
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
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
|
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
|
||||||
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
|
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
|
||||||
@@ -670,4 +607,3 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -52,11 +52,6 @@ Java_com_google_android_filament_ToneMapper_nCreatePBRNeutralToneMapper(JNIEnv*,
|
|||||||
return (jlong) new PBRNeutralToneMapper();
|
return (jlong) new PBRNeutralToneMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jlong JNICALL
|
|
||||||
Java_com_google_android_filament_ToneMapper_nCreateGT7ToneMapper(JNIEnv*, jclass) {
|
|
||||||
return (jlong) new GT7ToneMapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
|
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
|
||||||
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));
|
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));
|
||||||
|
|||||||
@@ -76,12 +76,6 @@ Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong n
|
|||||||
view->setVisibleLayers((uint8_t) select, (uint8_t) value);
|
view->setVisibleLayers((uint8_t) select, (uint8_t) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_View_nGetVisibleLayers(JNIEnv*, jclass, jlong nativeView) {
|
|
||||||
View* view = (View*) nativeView;
|
|
||||||
return view->getVisibleLayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_View_nSetShadowingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
|
Java_com_google_android_filament_View_nSetShadowingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
|
||||||
View* view = (View*) nativeView;
|
View* view = (View*) nativeView;
|
||||||
@@ -153,15 +147,6 @@ Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jcla
|
|||||||
view->setDynamicResolutionOptions(options);
|
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
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
|
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
|
||||||
View* view = (View*) nativeView;
|
View* view = (View*) nativeView;
|
||||||
@@ -371,7 +356,6 @@ Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong na
|
|||||||
view->setFogOptions(options);
|
view->setFogOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nativeView, jint blendMode) {
|
Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nativeView, jint blendMode) {
|
||||||
View* view = (View*) nativeView;
|
View* view = (View*) nativeView;
|
||||||
@@ -446,18 +430,6 @@ Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlon
|
|||||||
return (jboolean)view->isShadowingEnabled();
|
return (jboolean)view->isShadowingEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_View_nSetFrustumCullingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
|
|
||||||
View* view = (View*) nativeView;
|
|
||||||
view->setFrustumCullingEnabled(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_View_nIsFrustumCullingEnabled(JNIEnv*, jclass, jlong nativeView) {
|
|
||||||
View* view = (View*) nativeView;
|
|
||||||
return (jboolean)view->isFrustumCullingEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_View_nSetScreenSpaceRefractionEnabled(JNIEnv *, jclass,
|
Java_com_google_android_filament_View_nSetScreenSpaceRefractionEnabled(JNIEnv *, jclass,
|
||||||
@@ -582,20 +554,3 @@ Java_com_google_android_filament_View_nClearFrameHistory(JNIEnv *env, jclass cla
|
|||||||
Engine *engine = (Engine *) nativeEngine;
|
Engine *engine = (Engine *) nativeEngine;
|
||||||
view->clearFrameHistory(*engine);
|
view->clearFrameHistory(*engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_View_nSetChannelDepthClearEnabled(JNIEnv *, jclass ,
|
|
||||||
jlong nativeView, jint channel, jboolean enabled) {
|
|
||||||
View* view = (View*) nativeView;
|
|
||||||
view->setChannelDepthClearEnabled((uint8_t) channel, (bool) enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jboolean JNICALL
|
|
||||||
Java_com_google_android_filament_View_nIsChannelDepthClearEnabled(JNIEnv *env, jclass clazz,
|
|
||||||
jlong nativeView, jint channel) {
|
|
||||||
// TODO: implement nIsChannelDepthClearEnabled()
|
|
||||||
View* view = (View*) nativeView;
|
|
||||||
return (jboolean)view->isChannelDepthClearEnabled((uint8_t) channel);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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)
|
@NonNull @Size(min = 4)
|
||||||
static float[] assertFloat4(@Nullable float[] out) {
|
static float[] assertFloat4(@Nullable float[] out) {
|
||||||
if (out == null) out = new float[4];
|
if (out == null) out = new float[4];
|
||||||
@@ -136,13 +127,4 @@ final class Asserts {
|
|||||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
|
throw new ArrayIndexOutOfBoundsException("Array length must be at least 4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull @Size(min = 2)
|
|
||||||
static double[] assertDouble2(@Nullable double[] out) {
|
|
||||||
if (out == null) out = new double[2];
|
|
||||||
else if (out.length < 2) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 2");
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,27 +343,6 @@ public class Camera {
|
|||||||
nSetScaling(getNativeObject(), xscaling, yscaling);
|
nSetScaling(getNativeObject(), xscaling, yscaling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a custom projection matrix for each eye.
|
|
||||||
*
|
|
||||||
* @param inProjection An array of projection matrices, one for each eye.
|
|
||||||
* Must have at least 16 * count elements.
|
|
||||||
* @param count Number of eyes to set.
|
|
||||||
* @param inProjectionForCulling Custom projection matrix for culling, must encompass all eyes.
|
|
||||||
* @param near Distance to the near plane.
|
|
||||||
* @param far Distance to the far plane.
|
|
||||||
*/
|
|
||||||
public void setCustomEyeProjection(
|
|
||||||
@NonNull double[] inProjection, int count,
|
|
||||||
@NonNull @Size(min = 16) double[] inProjectionForCulling,
|
|
||||||
double near, double far) {
|
|
||||||
Asserts.assertMat4dIn(inProjectionForCulling);
|
|
||||||
if (inProjection.length < 16 * count) {
|
|
||||||
throw new IllegalArgumentException("inProjection array too small for the given count");
|
|
||||||
}
|
|
||||||
nSetCustomEyeProjection(getNativeObject(), inProjection, count, inProjectionForCulling, near, far);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an additional matrix that scales the projection matrix.
|
* Sets an additional matrix that scales the projection matrix.
|
||||||
*
|
*
|
||||||
@@ -420,31 +399,6 @@ public class Camera {
|
|||||||
nSetShift(getNativeObject(), xshift, yshift);
|
nSetShift(getNativeObject(), xshift, yshift);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the shift amount used to translate the projection matrix.
|
|
||||||
*
|
|
||||||
* @param out A 2-double array where the shift will be stored, or null.
|
|
||||||
* @return A 2-double array containing the x and y shift.
|
|
||||||
*/
|
|
||||||
@NonNull @Size(min = 2)
|
|
||||||
public double[] getShift(@Nullable @Size(min = 2) double[] out) {
|
|
||||||
out = Asserts.assertDouble2(out);
|
|
||||||
nGetShift(getNativeObject(), out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the camera's field of view in degrees.
|
|
||||||
*
|
|
||||||
* @param direction The direction of the FOV (VERTICAL or HORIZONTAL).
|
|
||||||
* @return The field of view in degrees.
|
|
||||||
*/
|
|
||||||
public double getFieldOfViewInDegrees(@NonNull Fov direction) {
|
|
||||||
return nGetFieldOfViewInDegrees(getNativeObject(), direction.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the camera's model matrix.
|
* Sets the camera's model matrix.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -791,17 +745,6 @@ public class Camera {
|
|||||||
return mEntity;
|
return mEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the model matrix for a specific eye.
|
|
||||||
*
|
|
||||||
* @param eyeId The index of the eye.
|
|
||||||
* @param model The model matrix for the eye.
|
|
||||||
*/
|
|
||||||
public void setEyeModelMatrix(int eyeId, @NonNull @Size(min = 16) double[] model) {
|
|
||||||
Asserts.assertMat4dIn(model);
|
|
||||||
nSetEyeModelMatrix(getNativeObject(), eyeId, model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to compute the effective focal length taking into account the focus distance
|
* Helper to compute the effective focal length taking into account the focus distance
|
||||||
*
|
*
|
||||||
@@ -841,13 +784,8 @@ public class Camera {
|
|||||||
private static native void nSetCustomProjection(long nativeCamera, double[] inProjection, double[] inProjectionForCulling, double near, double far);
|
private static native void nSetCustomProjection(long nativeCamera, double[] inProjection, double[] inProjectionForCulling, double near, double far);
|
||||||
private static native void nSetScaling(long nativeCamera, double x, double y);
|
private static native void nSetScaling(long nativeCamera, double x, double y);
|
||||||
private static native void nSetShift(long nativeCamera, double x, double y);
|
private static native void nSetShift(long nativeCamera, double x, double y);
|
||||||
private static native void nGetShift(long nativeCamera, double[] out);
|
|
||||||
private static native void nSetModelMatrix(long nativeCamera, float[] in);
|
private static native void nSetModelMatrix(long nativeCamera, float[] in);
|
||||||
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
|
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
|
||||||
private static native void nSetEyeModelMatrix(long nativeCamera, int eyeId, double[] model);
|
|
||||||
private static native void nSetCustomEyeProjection(long nativeCamera, double[] inProjection, int count, double[] inProjectionForCulling, double near, double far);
|
|
||||||
private static native double nGetFieldOfViewInDegrees(long nativeCamera, int direction);
|
|
||||||
|
|
||||||
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||||
private static native double nGetNear(long nativeCamera);
|
private static native double nGetNear(long nativeCamera);
|
||||||
private static native double nGetCullingFar(long nativeCamera);
|
private static native double nGetCullingFar(long nativeCamera);
|
||||||
|
|||||||
@@ -264,8 +264,7 @@ public class Engine {
|
|||||||
config.disableHandleUseAfterFreeCheck,
|
config.disableHandleUseAfterFreeCheck,
|
||||||
config.preferredShaderLanguage.ordinal(),
|
config.preferredShaderLanguage.ordinal(),
|
||||||
config.forceGLES2Context, config.assertNativeWindowIsValid,
|
config.forceGLES2Context, config.assertNativeWindowIsValid,
|
||||||
config.gpuContextPriority.ordinal(),
|
config.gpuContextPriority.ordinal());
|
||||||
config.sharedUboInitialSizeInBytes);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,16 +525,6 @@ public class Engine {
|
|||||||
* GPU context priority level. Controls GPU work scheduling and preemption.
|
* GPU context priority level. Controls GPU work scheduling and preemption.
|
||||||
*/
|
*/
|
||||||
public GpuContextPriority gpuContextPriority = GpuContextPriority.DEFAULT;
|
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) {
|
private Engine(long nativeEngine, Config config) {
|
||||||
@@ -939,15 +928,6 @@ public class Engine {
|
|||||||
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
|
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the object is valid.
|
|
||||||
* @param object Object to check for validity
|
|
||||||
* @return returns true if the specified object is valid.
|
|
||||||
*/
|
|
||||||
public boolean isValidMorphTargetBuffer(@NonNull MorphTargetBuffer object) {
|
|
||||||
return nIsValidMorphTargetBuffer(getNativeObject(), object.getNativeObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the object is valid.
|
* Returns whether the object is valid.
|
||||||
* @param object Object to check for validity
|
* @param object Object to check for validity
|
||||||
@@ -1201,15 +1181,6 @@ public class Engine {
|
|||||||
skinningBuffer.clearNativeObject();
|
skinningBuffer.clearNativeObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroys a {@link MorphTargetBuffer} and frees all its associated resources.
|
|
||||||
* @param morphTargetBuffer the {@link MorphTargetBuffer} to destroy
|
|
||||||
*/
|
|
||||||
public void destroyMorphTargetBuffer(@NonNull MorphTargetBuffer morphTargetBuffer) {
|
|
||||||
assertDestroy(nDestroyMorphTargetBuffer(getNativeObject(), morphTargetBuffer.getNativeObject()));
|
|
||||||
morphTargetBuffer.clearNativeObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a {@link IndirectLight} and frees all its associated resources.
|
* Destroys a {@link IndirectLight} and frees all its associated resources.
|
||||||
* @param ibl the {@link IndirectLight} to destroy
|
* @param ibl the {@link IndirectLight} to destroy
|
||||||
@@ -1501,7 +1472,6 @@ public class Engine {
|
|||||||
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||||
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
||||||
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
||||||
private static native boolean nDestroyMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
|
|
||||||
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
|
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
|
||||||
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
|
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
|
||||||
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
|
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
|
||||||
@@ -1518,7 +1488,6 @@ public class Engine {
|
|||||||
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||||
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
||||||
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
||||||
private static native boolean nIsValidMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
|
|
||||||
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
|
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
|
||||||
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
|
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
|
||||||
private static native boolean nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);
|
private static native boolean nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);
|
||||||
@@ -1560,8 +1529,7 @@ public class Engine {
|
|||||||
boolean disableHandleUseAfterFreeCheck,
|
boolean disableHandleUseAfterFreeCheck,
|
||||||
int preferredShaderLanguage,
|
int preferredShaderLanguage,
|
||||||
boolean forceGLES2Context, boolean assertNativeWindowIsValid,
|
boolean forceGLES2Context, boolean assertNativeWindowIsValid,
|
||||||
int gpuContextPriority,
|
int gpuContextPriority);
|
||||||
long sharedUboInitialSizeInBytes);
|
|
||||||
private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal);
|
private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal);
|
||||||
private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext);
|
private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext);
|
||||||
private static native void nSetBuilderPaused(long nativeBuilder, boolean paused);
|
private static native void nSetBuilderPaused(long nativeBuilder, boolean paused);
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public class Material {
|
|||||||
static final CullingMode[] sCullingModeValues = CullingMode.values();
|
static final CullingMode[] sCullingModeValues = CullingMode.values();
|
||||||
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
|
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
|
||||||
VertexBuffer.VertexAttribute.values();
|
VertexBuffer.VertexAttribute.values();
|
||||||
static final TransparencyMode[] sTransparencyModeValues = TransparencyMode.values();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private long mNativeObject;
|
private long mNativeObject;
|
||||||
@@ -161,31 +160,6 @@ public class Material {
|
|||||||
SCREEN,
|
SCREEN,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* How transparent objects are handled
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:transparencymode">
|
|
||||||
* Blending and transparency: transparencyMode</a>
|
|
||||||
*/
|
|
||||||
public enum TransparencyMode {
|
|
||||||
/** The transparent object is drawn honoring the raster state. */
|
|
||||||
DEFAULT,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The transparent object is first drawn in the depth buffer,
|
|
||||||
* then in the color buffer, honoring the culling mode, but ignoring the depth test function.
|
|
||||||
*/
|
|
||||||
TWO_PASSES_ONE_SIDE,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The transparent object is drawn twice in the color buffer,
|
|
||||||
* first with back faces only, then with front faces; the culling
|
|
||||||
* mode is ignored. Can be combined with two-sided lighting.
|
|
||||||
*/
|
|
||||||
TWO_PASSES_TWO_SIDES
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Supported refraction modes
|
* Supported refraction modes
|
||||||
*
|
*
|
||||||
@@ -287,20 +261,6 @@ public class Material {
|
|||||||
LOW
|
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 {
|
public static class UserVariantFilterBit {
|
||||||
/** Directional lighting */
|
/** Directional lighting */
|
||||||
public static int DIRECTIONAL_LIGHTING = 0x01;
|
public static int DIRECTIONAL_LIGHTING = 0x01;
|
||||||
@@ -412,7 +372,6 @@ public class Material {
|
|||||||
private int mSize;
|
private int mSize;
|
||||||
private int mShBandCount = 0;
|
private int mShBandCount = 0;
|
||||||
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
|
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
|
||||||
private UboBatchingMode mUboBatchingMode = UboBatchingMode.DEFAULT;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -457,17 +416,6 @@ public class Material {
|
|||||||
return this;
|
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.
|
* Creates and returns the Material object.
|
||||||
*
|
*
|
||||||
@@ -480,7 +428,7 @@ public class Material {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public Material build(@NonNull Engine engine) {
|
public Material build(@NonNull Engine engine) {
|
||||||
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
|
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");
|
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
|
||||||
return new Material(nativeMaterial);
|
return new Material(nativeMaterial);
|
||||||
}
|
}
|
||||||
@@ -613,18 +561,6 @@ public class Material {
|
|||||||
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
|
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the transparency mode of this material.
|
|
||||||
* This value only makes sense when the blending mode is transparent or fade.
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/blendingandtransparency:transparencymode">
|
|
||||||
* Blending and transparency: transparencyMode</a>
|
|
||||||
*/
|
|
||||||
public TransparencyMode getTransparencyMode() {
|
|
||||||
return EnumCache.sTransparencyModeValues[nGetTransparencyMode(getNativeObject())];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the refraction mode of this material.
|
* Returns the refraction mode of this material.
|
||||||
*
|
*
|
||||||
@@ -851,21 +787,6 @@ public class Material {
|
|||||||
return nHasParameter(getNativeObject(), name);
|
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.
|
* Sets the value of a bool parameter on this material's default instance.
|
||||||
*
|
*
|
||||||
@@ -1158,7 +1079,7 @@ public class Material {
|
|||||||
mNativeObject = 0;
|
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 nCreateInstance(long nativeMaterial);
|
||||||
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
|
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
|
||||||
private static native long nGetDefaultInstance(long nativeMaterial);
|
private static native long nGetDefaultInstance(long nativeMaterial);
|
||||||
@@ -1168,7 +1089,6 @@ public class Material {
|
|||||||
private static native int nGetShading(long nativeMaterial);
|
private static native int nGetShading(long nativeMaterial);
|
||||||
private static native int nGetInterpolation(long nativeMaterial);
|
private static native int nGetInterpolation(long nativeMaterial);
|
||||||
private static native int nGetBlendingMode(long nativeMaterial);
|
private static native int nGetBlendingMode(long nativeMaterial);
|
||||||
private static native int nGetTransparencyMode(long nativeMaterial);
|
|
||||||
private static native int nGetVertexDomain(long nativeMaterial);
|
private static native int nGetVertexDomain(long nativeMaterial);
|
||||||
private static native int nGetCullingMode(long nativeMaterial);
|
private static native int nGetCullingMode(long nativeMaterial);
|
||||||
private static native boolean nIsColorWriteEnabled(long nativeMaterial);
|
private static native boolean nIsColorWriteEnabled(long nativeMaterial);
|
||||||
@@ -1191,5 +1111,4 @@ public class Material {
|
|||||||
private static native int nGetRequiredAttributes(long nativeMaterial);
|
private static native int nGetRequiredAttributes(long nativeMaterial);
|
||||||
|
|
||||||
private static native boolean nHasParameter(long nativeMaterial, @NonNull String name);
|
private static native boolean nHasParameter(long nativeMaterial, @NonNull String name);
|
||||||
private static native String nGetParameterTransformName(long nativeMaterial, @NonNull String samplerName);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -537,14 +537,6 @@ public class MaterialInstance {
|
|||||||
nSetDoubleSided(getNativeObject(), doubleSided);
|
nSetDoubleSided(getNativeObject(), doubleSided);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the transparency mode for this material instance.
|
|
||||||
* @see Material.TransparencyMode
|
|
||||||
*/
|
|
||||||
public void setTransparencyMode(@NonNull Material.TransparencyMode mode) {
|
|
||||||
nSetTransparencyMode(getNativeObject(), mode.ordinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
|
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
|
||||||
* capability.
|
* capability.
|
||||||
@@ -553,14 +545,6 @@ public class MaterialInstance {
|
|||||||
return nIsDoubleSided(getNativeObject());
|
return nIsDoubleSided(getNativeObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the transparency mode.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Material.TransparencyMode getTransparencyMode() {
|
|
||||||
return Material.EnumCache.sTransparencyModeValues[nGetTransparencyMode(getNativeObject())];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the default triangle culling state that was set on the material.
|
* Overrides the default triangle culling state that was set on the material.
|
||||||
*
|
*
|
||||||
@@ -998,6 +982,4 @@ public class MaterialInstance {
|
|||||||
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
|
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
|
||||||
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
|
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
|
||||||
private static native int nGetDepthFunc(long nativeMaterialInstance);
|
private static native int nGetDepthFunc(long nativeMaterialInstance);
|
||||||
private static native void nSetTransparencyMode(long nativeMaterialInstance, int mode);
|
|
||||||
private static native int nGetTransparencyMode(long nativeMaterialInstance);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,45 +64,6 @@ public class MorphTargetBuffer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to enable or disable the built-in position morphing buffer.
|
|
||||||
* Default is true.
|
|
||||||
*
|
|
||||||
* @param enabled true to enable, false to disable
|
|
||||||
* @return this <code>Builder</code> object for chaining calls
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Builder withPositions(boolean enabled) {
|
|
||||||
nBuilderWithPositions(mNativeBuilder, enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to enable or disable the built-in tangent morphing buffer.
|
|
||||||
* Default is true.
|
|
||||||
*
|
|
||||||
* @param enabled true to enable, false to disable
|
|
||||||
* @return this <code>Builder</code> object for chaining calls
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Builder withTangents(boolean enabled) {
|
|
||||||
nBuilderWithTangents(mNativeBuilder, enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use this method to enable or disable custom morphing.
|
|
||||||
* Default is false.
|
|
||||||
*
|
|
||||||
* @param enabled true to enable, false to disable
|
|
||||||
* @return this <code>Builder</code> object for chaining calls
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Builder enableCustomMorphing(boolean enabled) {
|
|
||||||
nBuilderEnableCustomMorphing(mNativeBuilder, enabled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns the <code>MorphTargetBuffer</code> object.
|
* Creates and returns the <code>MorphTargetBuffer</code> object.
|
||||||
*
|
*
|
||||||
@@ -195,27 +156,6 @@ public class MorphTargetBuffer {
|
|||||||
return nGetCount(mNativeObject);
|
return nGetCount(mNativeObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if this MorphTargetBuffer has a position buffer.
|
|
||||||
*/
|
|
||||||
public boolean hasPositions() {
|
|
||||||
return nHasPositions(mNativeObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if this MorphTargetBuffer has a tangent buffer.
|
|
||||||
*/
|
|
||||||
public boolean hasTangents() {
|
|
||||||
return nHasTangents(mNativeObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if custom morphing is enabled.
|
|
||||||
*/
|
|
||||||
public boolean isCustomMorphingEnabled() {
|
|
||||||
return nIsCustomMorphingEnabled(mNativeObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNativeObject() {
|
public long getNativeObject() {
|
||||||
if (mNativeObject == 0) {
|
if (mNativeObject == 0) {
|
||||||
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
|
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
|
||||||
@@ -231,16 +171,10 @@ public class MorphTargetBuffer {
|
|||||||
private static native void nDestroyBuilder(long nativeBuilder);
|
private static native void nDestroyBuilder(long nativeBuilder);
|
||||||
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
|
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
|
||||||
private static native void nBuilderCount(long nativeBuilder, int count);
|
private static native void nBuilderCount(long nativeBuilder, int count);
|
||||||
private static native void nBuilderWithPositions(long nativeBuilder, boolean enabled);
|
|
||||||
private static native void nBuilderWithTangents(long nativeBuilder, boolean enabled);
|
|
||||||
private static native void nBuilderEnableCustomMorphing(long nativeBuilder, boolean enabled);
|
|
||||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||||
|
|
||||||
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
|
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
|
||||||
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
|
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
|
||||||
private static native int nGetVertexCount(long nativeObject);
|
private static native int nGetVertexCount(long nativeObject);
|
||||||
private static native int nGetCount(long nativeObject);
|
private static native int nGetCount(long nativeObject);
|
||||||
private static native boolean nHasPositions(long nativeObject);
|
|
||||||
private static native boolean nHasTangents(long nativeObject);
|
|
||||||
private static native boolean nIsCustomMorphingEnabled(long nativeObject);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -332,7 +332,7 @@ public class RenderableManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the channel this renderable is associated to. There can be 8 channels.
|
* Set the channel this renderable is associated to. There can be 4 channels.
|
||||||
*
|
*
|
||||||
* <p>All renderables in a given channel are rendered together, regardless of anything else.
|
* <p>All renderables in a given channel are rendered together, regardless of anything else.
|
||||||
* They are sorted as usual within a channel.</p>
|
* They are sorted as usual within a channel.</p>
|
||||||
@@ -342,16 +342,16 @@ public class RenderableManager {
|
|||||||
* <p>Channels 0 and 1 may not have render primitives using a material with `refractionType`
|
* <p>Channels 0 and 1 may not have render primitives using a material with `refractionType`
|
||||||
* set to `screenspace`.</p>
|
* set to `screenspace`.</p>
|
||||||
*
|
*
|
||||||
* @param channel clamped to the range [0..7], defaults to 2.
|
* @param channel clamped to the range [0..3], defaults to 2.
|
||||||
*
|
*
|
||||||
* @return Builder reference for chaining calls.
|
* @return Builder reference for chaining calls.
|
||||||
*
|
*
|
||||||
* @see Builder#blendOrder()
|
* @see Builder::blendOrder()
|
||||||
* @see Builder#priority()
|
* @see Builder::priority()
|
||||||
* @see RenderableManager::setBlendOrderAt()
|
* @see RenderableManager::setBlendOrderAt()
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public Builder channel(@IntRange(from = 0, to = 7) int channel) {
|
public Builder channel(@IntRange(from = 0, to = 3) int channel) {
|
||||||
nBuilderChannel(mNativeBuilder, channel);
|
nBuilderChannel(mNativeBuilder, channel);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -725,23 +725,15 @@ public class RenderableManager {
|
|||||||
nSetPriority(mNativeObject, i, priority);
|
nSetPriority(mNativeObject, i, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPriority(@EntityInstance int i) {
|
|
||||||
return nGetPriority(mNativeObject, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the channel of a renderable
|
* Changes the channel of a renderable
|
||||||
*
|
*
|
||||||
* @see Builder#channel
|
* @see Builder#channel
|
||||||
*/
|
*/
|
||||||
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
|
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 3) int channel) {
|
||||||
nSetChannel(mNativeObject, i, channel);
|
nSetChannel(mNativeObject, i, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChannel(@EntityInstance int i) {
|
|
||||||
return nGetChannel(mNativeObject, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes whether or not frustum culling is on.
|
* Changes whether or not frustum culling is on.
|
||||||
*
|
*
|
||||||
@@ -751,10 +743,6 @@ public class RenderableManager {
|
|||||||
nSetCulling(mNativeObject, i, enabled);
|
nSetCulling(mNativeObject, i, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCullingEnabled(@EntityInstance int i) {
|
|
||||||
return nIsCullingEnabled(mNativeObject, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes whether or not the large-scale fog is applied to this renderable
|
* Changes whether or not the large-scale fog is applied to this renderable
|
||||||
* @see Builder#fog
|
* @see Builder#fog
|
||||||
@@ -824,10 +812,6 @@ public class RenderableManager {
|
|||||||
nSetScreenSpaceContactShadows(mNativeObject, i, enabled);
|
nSetScreenSpaceContactShadows(mNativeObject, i, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isScreenSpaceContactShadowsEnabled(@EntityInstance int i) {
|
|
||||||
return nIsScreenSpaceContactShadowsEnabled(mNativeObject, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the renderable can cast shadows.
|
* Checks if the renderable can cast shadows.
|
||||||
*
|
*
|
||||||
@@ -948,10 +932,6 @@ public class RenderableManager {
|
|||||||
nSetBlendOrderAt(mNativeObject, instance, primitiveIndex, blendOrder);
|
nSetBlendOrderAt(mNativeObject, instance, primitiveIndex, blendOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBlendOrderAt(@EntityInstance int instance, @IntRange(from = 0) int primitiveIndex) {
|
|
||||||
return nGetBlendOrderAt(mNativeObject, instance, primitiveIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes whether the blend order is global or local to this Renderable (by default).
|
* Changes whether the blend order is global or local to this Renderable (by default).
|
||||||
*
|
*
|
||||||
@@ -966,10 +946,6 @@ public class RenderableManager {
|
|||||||
nSetGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex, enabled);
|
nSetGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isGlobalBlendOrderEnabledAt(@EntityInstance int instance, @IntRange(from = 0) int primitiveIndex) {
|
|
||||||
return nIsGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
|
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
|
||||||
*/
|
*/
|
||||||
@@ -1037,11 +1013,8 @@ public class RenderableManager {
|
|||||||
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
|
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
|
||||||
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
||||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||||
private static native int nGetPriority(long nativeRenderableManager, int i);
|
|
||||||
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
|
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
|
||||||
private static native int nGetChannel(long nativeRenderableManager, int i);
|
|
||||||
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
||||||
private static native boolean nIsCullingEnabled(long nativeRenderableManager, int i);
|
|
||||||
private static native void nSetFogEnabled(long nativeRenderableManager, int i, boolean enabled);
|
private static native void nSetFogEnabled(long nativeRenderableManager, int i, boolean enabled);
|
||||||
private static native boolean nGetFogEnabled(long nativeRenderableManager, int i);
|
private static native boolean nGetFogEnabled(long nativeRenderableManager, int i);
|
||||||
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
|
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
|
||||||
@@ -1049,7 +1022,6 @@ public class RenderableManager {
|
|||||||
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
|
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||||
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
|
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||||
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
|
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||||
private static native boolean nIsScreenSpaceContactShadowsEnabled(long nativeRenderableManager, int i);
|
|
||||||
private static native boolean nIsShadowCaster(long nativeRenderableManager, int i);
|
private static native boolean nIsShadowCaster(long nativeRenderableManager, int i);
|
||||||
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
|
private static native boolean nIsShadowReceiver(long nativeRenderableManager, int i);
|
||||||
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
|
private static native void nGetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float[] center, float[] halfExtent);
|
||||||
@@ -1060,8 +1032,6 @@ public class RenderableManager {
|
|||||||
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
|
private static native long nGetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||||
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
|
private static native void nSetGeometryAt(long nativeRenderableManager, int i, int primitiveIndex, int primitiveType, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
|
||||||
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
|
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
|
||||||
private static native int nGetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex);
|
|
||||||
private static native void nSetGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex, boolean enabled);
|
private static native void nSetGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex, boolean enabled);
|
||||||
private static native boolean nIsGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex);
|
|
||||||
private static native int nGetEnabledAttributesAt(long nativeRenderableManager, int i, int primitiveIndex);
|
private static native int nGetEnabledAttributesAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -732,22 +732,6 @@ public class Renderer {
|
|||||||
nResetUserTime(getNativeObject());
|
nResetUserTime(getNativeObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests the next frameCount frames to be skipped. For Debugging.
|
|
||||||
* @param frameCount number of frames to skip.
|
|
||||||
*/
|
|
||||||
public void skipNextFrames(int frameCount) {
|
|
||||||
nSkipNextFrames(getNativeObject(), frameCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remainder count of frame to be skipped
|
|
||||||
* @return remaining frames to be skipped
|
|
||||||
*/
|
|
||||||
public int getFrameToSkipCount() {
|
|
||||||
return nGetFrameToSkipCount(getNativeObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNativeObject() {
|
public long getNativeObject() {
|
||||||
if (mNativeObject == 0) {
|
if (mNativeObject == 0) {
|
||||||
throw new IllegalStateException("Calling method on destroyed Renderer");
|
throw new IllegalStateException("Calling method on destroyed Renderer");
|
||||||
@@ -789,7 +773,4 @@ public class Renderer {
|
|||||||
float interval, float headRoomRatio, float scaleRate, int history);
|
float interval, float headRoomRatio, float scaleRate, int history);
|
||||||
private static native void nSetClearOptions(long nativeRenderer,
|
private static native void nSetClearOptions(long nativeRenderer,
|
||||||
float r, float g, float b, float a, boolean clear, boolean discard);
|
float r, float g, float b, float a, boolean clear, boolean discard);
|
||||||
|
|
||||||
private static native void nSkipNextFrames(long nativeObject, int frameCount);
|
|
||||||
private static native int nGetFrameToSkipCount(long nativeObject);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,24 +155,6 @@ public class Skybox {
|
|||||||
return this;
|
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
|
* 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 nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
|
||||||
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
|
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 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 long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
|
||||||
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
|
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
|
||||||
private static native int nGetLayerMask(long nativeSkybox);
|
private static native int nGetLayerMask(long nativeSkybox);
|
||||||
|
|||||||
@@ -139,78 +139,6 @@ public class SwapChain {
|
|||||||
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
|
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* FrameScheduledCallback is a callback function that notifies an application about the status
|
|
||||||
* of a frame after Filament has finished its processing.
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The exact timing and semantics of this callback differ depending on the graphics backend in
|
|
||||||
* use.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <h3>Metal Backend</h3>
|
|
||||||
* <p>
|
|
||||||
* With the Metal backend, this callback signifies that Filament has completed all CPU-side
|
|
||||||
* processing for a frame and the frame is ready to be scheduled for presentation.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Typically, Filament is responsible for scheduling the frame's presentation to the SwapChain.
|
|
||||||
* If a FrameScheduledCallback is set, however, the application bears the responsibility of
|
|
||||||
* scheduling the frame for presentation by calling the PresentCallable passed to the callback
|
|
||||||
* function. In this mode, Filament will not automatically schedule the frame for presentation.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* When using the Metal backend, if your application delays the call to the PresentCallable
|
|
||||||
* (e.g., by invoking it on a separate thread), you must ensure all PresentCallables have been
|
|
||||||
* called before shutting down the Filament Engine. You can guarantee this by calling
|
|
||||||
* Engine.flushAndWait() before Engine.shutdown(). This is necessary to ensure the Engine has
|
|
||||||
* a chance to clean up all memory related to frame presentation.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <h3>Other Backends (OpenGL, Vulkan, WebGPU)</h3>
|
|
||||||
* <p>
|
|
||||||
* On other backends, this callback serves as a notification that Filament has completed all
|
|
||||||
* CPU-side processing for a frame. Filament proceeds with its normal presentation logic
|
|
||||||
* automatically, and the PresentCallable passed to the callback is a no-op that can be safely
|
|
||||||
* ignored.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <h3>General Behavior</h3>
|
|
||||||
* <p>
|
|
||||||
* A FrameScheduledCallback can be set on an individual SwapChain through
|
|
||||||
* setFrameScheduledCallback. Each SwapChain can have only one callback set per frame. If
|
|
||||||
* setFrameScheduledCallback is called multiple times on the same SwapChain before
|
|
||||||
* Renderer.endFrame(), the most recent call effectively overwrites any previously set callback.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* The callback set by setFrameScheduledCallback is "latched" when Renderer.endFrame() is
|
|
||||||
* executed. At this point, the callback is fixed for the frame that was just encoded.
|
|
||||||
* Subsequent calls to setFrameScheduledCallback after endFrame() will apply to the next frame.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Use setFrameScheduledCallback() (with default arguments) to unset the callback.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param handler A {@link java.util.concurrent.Executor Executor}.
|
|
||||||
* @param callback The Runnable callback to invoke when frame processing is complete.
|
|
||||||
*/
|
|
||||||
public void setFrameScheduledCallback(@NonNull Object handler, @NonNull Runnable callback) {
|
|
||||||
nSetFrameScheduledCallback(getNativeObject(), handler, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this SwapChain currently has a FrameScheduledCallback set.
|
|
||||||
*
|
|
||||||
* @return true, if the last call to setFrameScheduledCallback set a callback
|
|
||||||
*/
|
|
||||||
public boolean isFrameScheduledCallbackSet() {
|
|
||||||
return nIsFrameScheduledCallbackSet(getNativeObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getNativeObject() {
|
public long getNativeObject() {
|
||||||
if (mNativeObject == 0) {
|
if (mNativeObject == 0) {
|
||||||
throw new IllegalStateException("Calling method on destroyed SwapChain");
|
throw new IllegalStateException("Calling method on destroyed SwapChain");
|
||||||
@@ -223,8 +151,6 @@ public class SwapChain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
|
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
|
||||||
private static native void nSetFrameScheduledCallback(long nativeSwapChain, Object handler, Runnable callback);
|
|
||||||
private static native boolean nIsFrameScheduledCallbackSet(long nativeSwapChain);
|
|
||||||
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
|
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
|
||||||
private static native boolean nIsMSAASwapChainSupported(long nativeEngine, int samples);
|
private static native boolean nIsMSAASwapChainSupported(long nativeEngine, int samples);
|
||||||
private static native boolean nIsProtectedContentSupported(long nativeEngine);
|
private static native boolean nIsProtectedContentSupported(long nativeEngine);
|
||||||
|
|||||||
@@ -71,16 +71,6 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
|
|||||||
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
|
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
|
||||||
*/
|
*/
|
||||||
public class Texture {
|
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 Sampler[] sSamplerValues = Sampler.values();
|
||||||
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
|
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
|
||||||
|
|
||||||
@@ -795,17 +785,6 @@ public class Texture {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the number of samples for multisample anti-aliasing.
|
|
||||||
* @param samples number of samples, must be at least 1. Default is 1.
|
|
||||||
* @return This Builder, for chaining calls.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public Builder samples(@IntRange(from = 1) int samples) {
|
|
||||||
nBuilderSamples(mNativeBuilder, samples);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the texture's internal format.
|
* Specifies the texture's internal format.
|
||||||
* <p>The internal format specifies how texels are stored (which may be different from how
|
* <p>The internal format specifies how texels are stored (which may be different from how
|
||||||
@@ -1193,38 +1172,6 @@ public class Texture {
|
|||||||
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
|
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>.
|
* Specifies the external stream to associate with this <code>Texture</code>.
|
||||||
*
|
*
|
||||||
@@ -1381,7 +1328,6 @@ public class Texture {
|
|||||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||||
private static native void nBuilderUsage(long nativeBuilder, int flags);
|
private static native void nBuilderUsage(long nativeBuilder, int flags);
|
||||||
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
|
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
|
||||||
private static native void nBuilderSamples(long nativeBuilder, int samples);
|
|
||||||
private static native void nBuilderImportTexture(long nativeBuilder, long id);
|
private static native void nBuilderImportTexture(long nativeBuilder, long id);
|
||||||
private static native void nBuilderExternal(long nativeBuilder);
|
private static native void nBuilderExternal(long nativeBuilder);
|
||||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||||
@@ -1418,8 +1364,6 @@ public class Texture {
|
|||||||
private static native void nSetExternalImage(
|
private static native void nSetExternalImage(
|
||||||
long nativeObject, long nativeEngine, long eglImage);
|
long nativeObject, long nativeEngine, long eglImage);
|
||||||
|
|
||||||
private static native boolean nSetExternalImageByAHB(long nativeTexture, long nativeObject, Object ahb);
|
|
||||||
|
|
||||||
private static native void nSetExternalStream(long nativeTexture,
|
private static native void nSetExternalStream(long nativeTexture,
|
||||||
long nativeEngine, long nativeStream);
|
long nativeEngine, long nativeStream);
|
||||||
|
|
||||||
|
|||||||
@@ -294,8 +294,8 @@ public class TextureSampler {
|
|||||||
/**
|
/**
|
||||||
* This controls anisotropic filtering.
|
* This controls anisotropic filtering.
|
||||||
*
|
*
|
||||||
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 1.
|
* @param anisotropy Amount of anisotropy, should be a power-of-two. The default is 0.
|
||||||
* The maximum permissible value is 128.
|
* The maximum permissible value is 7.
|
||||||
*/
|
*/
|
||||||
public void setAnisotropy(float anisotropy) {
|
public void setAnisotropy(float anisotropy) {
|
||||||
mSampler = nSetAnisotropy(mSampler, anisotropy);
|
mSampler = nSetAnisotropy(mSampler, anisotropy);
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ package com.google.android.filament;
|
|||||||
* <li>ACESLegacyToneMapper</li>
|
* <li>ACESLegacyToneMapper</li>
|
||||||
* <li>FilmicToneMapper</li>
|
* <li>FilmicToneMapper</li>
|
||||||
* <li>PBRNeutralToneMapper</li>
|
* <li>PBRNeutralToneMapper</li>
|
||||||
* <li>GT7ToneMapper</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
* <li>Debug/validation tone mapping operators</li>
|
* <li>Debug/validation tone mapping operators</li>
|
||||||
* <ul>
|
* <ul>
|
||||||
@@ -112,19 +111,6 @@ public class ToneMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gran Turismo 7 tone mapping operator. This tone mapper was designed
|
|
||||||
* to preserve the appearance of materials across lighting conditions while
|
|
||||||
* avoiding artifacts in the highlights in high dynamic range conditions.
|
|
||||||
* This tone mapper targets an SDR paper white value of 250 nits, with a
|
|
||||||
* reference luminance of 100 cd/m^2 (a value of 1.0 in the HDR framebuffer).
|
|
||||||
*/
|
|
||||||
public static class GT7ToneMapper extends ToneMapper {
|
|
||||||
public GT7ToneMapper() {
|
|
||||||
super(nCreateGT7ToneMapper());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AgX tone mapping operator.
|
* AgX tone mapping operator.
|
||||||
*/
|
*/
|
||||||
@@ -258,7 +244,6 @@ public class ToneMapper {
|
|||||||
private static native long nCreateACESLegacyToneMapper();
|
private static native long nCreateACESLegacyToneMapper();
|
||||||
private static native long nCreateFilmicToneMapper();
|
private static native long nCreateFilmicToneMapper();
|
||||||
private static native long nCreatePBRNeutralToneMapper();
|
private static native long nCreatePBRNeutralToneMapper();
|
||||||
private static native long nCreateGT7ToneMapper();
|
|
||||||
private static native long nCreateAgxToneMapper(int look);
|
private static native long nCreateAgxToneMapper(int look);
|
||||||
private static native long nCreateGenericToneMapper(
|
private static native long nCreateGenericToneMapper(
|
||||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
|
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
*.iml
|
|
||||||
.gradle
|
|
||||||
/local.properties
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/libraries
|
|
||||||
/.idea/caches
|
|
||||||
/.idea/gradle.xml
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
.externalNativeBuild
|
|
||||||
/.cxx
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id "de.undercouch.download" version "5.6.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
|
||||||
|
|
||||||
def tools = ['matc', 'cmgen']
|
|
||||||
|
|
||||||
def platforms = [
|
|
||||||
'mac': [classifier: 'osx-aarch_64', archive: "filament-v${VERSION_NAME}-mac.tgz", path: { t -> "filament/bin/${t}" }],
|
|
||||||
'linux': [classifier: 'linux-x86_64', archive: "filament-v${VERSION_NAME}-linux.tgz", path: { t -> "filament/bin/${t}" }],
|
|
||||||
'windows': [classifier: 'windows-x86_64', archive: "filament-v${VERSION_NAME}-windows.tgz", path: { t -> "bin/${t}.exe" }]
|
|
||||||
]
|
|
||||||
|
|
||||||
platforms.each { platform, config ->
|
|
||||||
def platformName = platform.capitalize()
|
|
||||||
def remoteUrl = "https://github.com/google/filament/releases/download/v${VERSION_NAME}/${config.archive}"
|
|
||||||
def downloadFile = file("${buildDir}/downloads/${config.archive}")
|
|
||||||
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
|
|
||||||
|
|
||||||
task "downloadRelease${platformName}"(type: Download) {
|
|
||||||
src remoteUrl
|
|
||||||
dest downloadFile
|
|
||||||
overwrite false
|
|
||||||
}
|
|
||||||
|
|
||||||
def extractionTask = task "extractTools${platformName}"(dependsOn: "downloadRelease${platformName}", type: Copy) {
|
|
||||||
group = "setup"
|
|
||||||
from tarTree(resources.gzip(downloadFile))
|
|
||||||
|
|
||||||
// Include specific tools based on platform pattern
|
|
||||||
include tools.collect { tool -> config.path(tool) }
|
|
||||||
|
|
||||||
// Flatten the path so it lands directly in 'into'
|
|
||||||
eachFile { fcd ->
|
|
||||||
fcd.relativePath = new RelativePath(true, fcd.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
into extractDir
|
|
||||||
includeEmptyDirs = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
tools.each { toolName ->
|
|
||||||
create(toolName, MavenPublication) {
|
|
||||||
artifactId = toolName
|
|
||||||
|
|
||||||
platforms.each { platform, config ->
|
|
||||||
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
|
|
||||||
def archivePath = config.path(toolName)
|
|
||||||
def exeName = new File(archivePath).name
|
|
||||||
|
|
||||||
artifact(new File(extractDir, exeName)) {
|
|
||||||
classifier = config.classifier
|
|
||||||
extension = "exe"
|
|
||||||
builtBy tasks.named("extractTools${platform.capitalize()}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
POM_NAME=Filament
|
|
||||||
POM_PACKAGING=exe
|
|
||||||
@@ -22,10 +22,6 @@ add_library(image STATIC IMPORTED)
|
|||||||
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
||||||
|
|
||||||
add_library(imageio-lite STATIC IMPORTED)
|
|
||||||
set_target_properties(imageio-lite PROPERTIES IMPORTED_LOCATION
|
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimageio-lite.a)
|
|
||||||
|
|
||||||
add_library(ktxreader STATIC IMPORTED)
|
add_library(ktxreader STATIC IMPORTED)
|
||||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||||
@@ -34,10 +30,6 @@ add_library(viewer STATIC IMPORTED)
|
|||||||
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
|
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
|
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
|
||||||
|
|
||||||
add_library(imagediff STATIC IMPORTED)
|
|
||||||
set_target_properties(imagediff PROPERTIES IMPORTED_LOCATION
|
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimagediff.a)
|
|
||||||
|
|
||||||
add_library(civetweb STATIC IMPORTED)
|
add_library(civetweb STATIC IMPORTED)
|
||||||
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
|
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
|
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
|
||||||
@@ -65,7 +57,6 @@ add_library(filament-utils-jni SHARED
|
|||||||
src/main/cpp/IBLPrefilterContext.cpp
|
src/main/cpp/IBLPrefilterContext.cpp
|
||||||
src/main/cpp/Utils.cpp
|
src/main/cpp/Utils.cpp
|
||||||
src/main/cpp/Manipulator.cpp
|
src/main/cpp/Manipulator.cpp
|
||||||
src/main/cpp/ImageDiff.cpp
|
|
||||||
src/main/cpp/RemoteServer.cpp
|
src/main/cpp/RemoteServer.cpp
|
||||||
|
|
||||||
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
|
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
|
||||||
@@ -83,7 +74,6 @@ target_include_directories(filament-utils-jni PRIVATE
|
|||||||
${FILAMENT_DIR}/include
|
${FILAMENT_DIR}/include
|
||||||
../../filament/backend/include
|
../../filament/backend/include
|
||||||
${IMAGEIO_DIR}/include
|
${IMAGEIO_DIR}/include
|
||||||
../../libs/imagediff/include
|
|
||||||
../../libs/utils/include)
|
../../libs/utils/include)
|
||||||
|
|
||||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
|
||||||
@@ -95,13 +85,10 @@ target_link_libraries(filament-utils-jni
|
|||||||
PRIVATE camutils
|
PRIVATE camutils
|
||||||
PRIVATE iblprefilter
|
PRIVATE iblprefilter
|
||||||
PRIVATE image
|
PRIVATE image
|
||||||
PRIVATE imageio-lite
|
|
||||||
PRIVATE filament-jni
|
PRIVATE filament-jni
|
||||||
PRIVATE ktxreader
|
PRIVATE ktxreader
|
||||||
PRIVATE viewer
|
PRIVATE viewer
|
||||||
PRIVATE imagediff
|
|
||||||
PRIVATE log
|
PRIVATE log
|
||||||
PRIVATE utils
|
PRIVATE utils
|
||||||
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
||||||
PRIVATE jnigraphics # needed for AndroidBitmap_* functions in ImageDiff
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -71,10 +71,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nStartBatchMode(JNIEnv*
|
|||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
|
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
|
||||||
jlong nativeAutomation, jlong nativeEngine,
|
jlong nativeAutomation, jlong nativeEngine,
|
||||||
jlong view, jlongArray materials, jlong renderer, jlong nativeIbl, jint sunlightEntity,
|
jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
|
||||||
jintArray assetLights, jlong nativeLm, jlong scene, jfloat deltaTime) {
|
|
||||||
using MaterialPointer = MaterialInstance*;
|
using MaterialPointer = MaterialInstance*;
|
||||||
|
|
||||||
jsize materialCount = 0;
|
jsize materialCount = 0;
|
||||||
jlong* longMaterials = nullptr;
|
jlong* longMaterials = nullptr;
|
||||||
MaterialPointer* ptrMaterials = nullptr;
|
MaterialPointer* ptrMaterials = nullptr;
|
||||||
@@ -86,28 +84,12 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
|||||||
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jsize lightCount = 0;
|
|
||||||
jint* intLights = nullptr;
|
|
||||||
if (assetLights) {
|
|
||||||
lightCount = env->GetArrayLength(assetLights);
|
|
||||||
intLights = env->GetIntArrayElements(assetLights, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(sizeof(jint) == sizeof(Entity));
|
|
||||||
|
|
||||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||||
AutomationEngine::ViewerContent content = {
|
AutomationEngine::ViewerContent content = {
|
||||||
.view = (View*) view,
|
.view = (View*) view,
|
||||||
.renderer = (Renderer*) renderer,
|
.renderer = (Renderer*) renderer,
|
||||||
.materials = ptrMaterials,
|
.materials = ptrMaterials,
|
||||||
.materialCount = (size_t) materialCount,
|
.materialCount = (size_t) materialCount,
|
||||||
.lightManager = (LightManager*) nativeLm,
|
|
||||||
.scene = (Scene*) scene,
|
|
||||||
.indirectLight = (IndirectLight*) nativeIbl,
|
|
||||||
.sunlight = (Entity&) sunlightEntity,
|
|
||||||
.assetLights = (Entity*) intLights,
|
|
||||||
.assetLightCount = (size_t) lightCount,
|
|
||||||
};
|
};
|
||||||
Engine* engine = (Engine*)nativeEngine;
|
Engine* engine = (Engine*)nativeEngine;
|
||||||
automation->tick(engine, content, deltaTime);
|
automation->tick(engine, content, deltaTime);
|
||||||
@@ -115,9 +97,6 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
|
|||||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||||
delete[] ptrMaterials;
|
delete[] ptrMaterials;
|
||||||
}
|
}
|
||||||
if (intLights) {
|
|
||||||
env->ReleaseIntArrayElements(assetLights, intLights, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
@@ -180,50 +159,37 @@ extern "C" JNIEXPORT void JNICALL
|
|||||||
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
|
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
|
||||||
jlong nativeObject, jobject result) {
|
jlong nativeObject, jobject result) {
|
||||||
AutomationEngine* automation = (AutomationEngine*) nativeObject;
|
AutomationEngine* automation = (AutomationEngine*) nativeObject;
|
||||||
const auto& settings = automation->getSettings();
|
auto options = automation->getViewerOptions();
|
||||||
const auto& options = settings.viewer;
|
|
||||||
|
|
||||||
const jclass klass = env->GetObjectClass(result);
|
const jclass klass = env->GetObjectClass(result);
|
||||||
|
|
||||||
|
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
|
||||||
|
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
|
||||||
|
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
|
||||||
|
const jfieldID cameraNear = env->GetFieldID(klass, "cameraNear", "F");
|
||||||
|
const jfieldID cameraFar = env->GetFieldID(klass, "cameraFar", "F");
|
||||||
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
|
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
|
||||||
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
|
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
|
||||||
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
|
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
|
||||||
|
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
|
||||||
|
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
|
||||||
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
|
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
|
||||||
const jfieldID autoInstancingEnabled = env->GetFieldID(klass, "autoInstancingEnabled", "Z");
|
const jfieldID autoInstancingEnabled = env->GetFieldID(klass, "autoInstancingEnabled", "Z");
|
||||||
|
|
||||||
|
env->SetFloatField(result, cameraAperture, options.cameraAperture);
|
||||||
|
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
|
||||||
|
env->SetFloatField(result, cameraISO, options.cameraISO);
|
||||||
|
env->SetFloatField(result, cameraNear, options.cameraNear);
|
||||||
|
env->SetFloatField(result, cameraFar, options.cameraFar);
|
||||||
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
|
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
|
||||||
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
|
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
|
||||||
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
|
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
|
||||||
|
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
|
||||||
|
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
|
||||||
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
|
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
|
||||||
env->SetBooleanField(result, autoInstancingEnabled, options.autoInstancingEnabled);
|
env->SetBooleanField(result, autoInstancingEnabled, options.autoInstancingEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nGetCameraSettings(JNIEnv* env, jclass,
|
|
||||||
jlong nativeObject, jobject result) {
|
|
||||||
AutomationEngine* automation = (AutomationEngine*) nativeObject;
|
|
||||||
const auto& settings = automation->getSettings();
|
|
||||||
const auto& camera = settings.camera;
|
|
||||||
|
|
||||||
const jclass klass = env->GetObjectClass(result);
|
|
||||||
|
|
||||||
const jfieldID aperture = env->GetFieldID(klass, "aperture", "F");
|
|
||||||
const jfieldID shutterSpeed = env->GetFieldID(klass, "shutterSpeed", "F");
|
|
||||||
const jfieldID sensitivity = env->GetFieldID(klass, "sensitivity", "F");
|
|
||||||
const jfieldID near = env->GetFieldID(klass, "near", "F");
|
|
||||||
const jfieldID far = env->GetFieldID(klass, "far", "F");
|
|
||||||
const jfieldID focalLength = env->GetFieldID(klass, "focalLength", "F");
|
|
||||||
const jfieldID focusDistance = env->GetFieldID(klass, "focusDistance", "F");
|
|
||||||
|
|
||||||
env->SetFloatField(result, aperture, camera.aperture);
|
|
||||||
env->SetFloatField(result, shutterSpeed, camera.shutterSpeed);
|
|
||||||
env->SetFloatField(result, sensitivity, camera.sensitivity);
|
|
||||||
env->SetFloatField(result, near, camera.near);
|
|
||||||
env->SetFloatField(result, far, camera.far);
|
|
||||||
env->SetFloatField(result, focalLength, camera.focalLength);
|
|
||||||
env->SetFloatField(result, focusDistance, camera.focusDistance);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jlong JNICALL
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
|
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
|
||||||
jlong nativeObject, jlong nativeEngine) {
|
jlong nativeObject, jlong nativeEngine) {
|
||||||
@@ -249,18 +215,6 @@ Java_com_google_android_filament_utils_AutomationEngine_nShouldClose(JNIEnv*, jc
|
|||||||
return automation->shouldClose();
|
return automation->shouldClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nGetTestCount(JNIEnv*, jclass, jlong native) {
|
|
||||||
AutomationEngine* automation = (AutomationEngine*) native;
|
|
||||||
return (jint) automation->testCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nGetCurrentTest(JNIEnv*, jclass, jlong native) {
|
|
||||||
AutomationEngine* automation = (AutomationEngine*) native;
|
|
||||||
return (jint) automation->currentTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_utils_AutomationEngine_nDestroy(JNIEnv*, jclass, jlong native) {
|
Java_com_google_android_filament_utils_AutomationEngine_nDestroy(JNIEnv*, jclass, jlong native) {
|
||||||
AutomationEngine* automation = (AutomationEngine*) native;
|
AutomationEngine* automation = (AutomationEngine*) native;
|
||||||
|
|||||||
@@ -1,217 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <android/bitmap.h>
|
|
||||||
|
|
||||||
#include <imagediff/ImageDiff.h>
|
|
||||||
#include <utils/Log.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
using namespace imagediff;
|
|
||||||
using namespace utils;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct BitmapLock {
|
|
||||||
JNIEnv* env;
|
|
||||||
jobject bitmap;
|
|
||||||
void* pixels;
|
|
||||||
AndroidBitmapInfo info;
|
|
||||||
|
|
||||||
BitmapLock(JNIEnv* env, jobject bitmap) : env(env), bitmap(bitmap), pixels(nullptr) {
|
|
||||||
if (!bitmap) return;
|
|
||||||
if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
|
|
||||||
pixels = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~BitmapLock() {
|
|
||||||
if (pixels) {
|
|
||||||
AndroidBitmap_unlockPixels(env, bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid() const { return pixels != nullptr; }
|
|
||||||
|
|
||||||
imagediff::Bitmap toBitmap() const {
|
|
||||||
return {
|
|
||||||
.width = (uint32_t) info.width,
|
|
||||||
.height = (uint32_t) info.height,
|
|
||||||
.stride = (size_t) info.stride,
|
|
||||||
.data = pixels
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Helper to convert C++ ImageDiffResult to Java Result
|
|
||||||
jobject createResult(JNIEnv* env, ImageDiffResult const& result, bool generateDiff) {
|
|
||||||
// Create Result class/objects
|
|
||||||
jclass resultClass = env->FindClass("com/google/android/filament/utils/ImageDiff$Result");
|
|
||||||
jmethodID resultCtor = env->GetMethodID(resultClass, "<init>", "()V");
|
|
||||||
jobject resultObj = env->NewObject(resultClass, resultCtor);
|
|
||||||
jfieldID statusField = env->GetFieldID(resultClass, "status", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
|
|
||||||
jfieldID failingCountField = env->GetFieldID(resultClass, "failingPixelCount", "J");
|
|
||||||
jfieldID maxDiffField = env->GetFieldID(resultClass, "maxDiffFound", "[F");
|
|
||||||
jfieldID diffImageField = env->GetFieldID(resultClass, "diffImage", "Landroid/graphics/Bitmap;");
|
|
||||||
|
|
||||||
// Map Status enum
|
|
||||||
jclass statusEnum = env->FindClass("com/google/android/filament/utils/ImageDiff$Result$Status");
|
|
||||||
jobject statusObj = nullptr;
|
|
||||||
jfieldID enumField = nullptr;
|
|
||||||
switch (result.status) {
|
|
||||||
case ImageDiffResult::Status::PASSED:
|
|
||||||
enumField = env->GetStaticFieldID(statusEnum, "PASSED", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
|
|
||||||
break;
|
|
||||||
case ImageDiffResult::Status::SIZE_MISMATCH:
|
|
||||||
enumField = env->GetStaticFieldID(statusEnum, "SIZE_MISMATCH", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
|
|
||||||
break;
|
|
||||||
case ImageDiffResult::Status::PIXEL_DIFFERENCE:
|
|
||||||
enumField = env->GetStaticFieldID(statusEnum, "PIXEL_DIFFERENCE", "Lcom/google/android/filament/utils/ImageDiff$Result$Status;");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
statusObj = env->GetStaticObjectField(statusEnum, enumField);
|
|
||||||
env->SetObjectField(resultObj, statusField, statusObj);
|
|
||||||
|
|
||||||
env->SetLongField(resultObj, failingCountField, (jlong) result.failingPixelCount);
|
|
||||||
|
|
||||||
jfloatArray maxDiffArray = env->NewFloatArray(4);
|
|
||||||
env->SetFloatArrayRegion(maxDiffArray, 0, 4, result.maxDiffFound);
|
|
||||||
env->SetObjectField(resultObj, maxDiffField, maxDiffArray);
|
|
||||||
|
|
||||||
if (generateDiff && result.diffImage.getWidth() > 0) {
|
|
||||||
jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
|
|
||||||
jmethodID createBitmap = env->GetStaticMethodID(bitmapClass, "createBitmap",
|
|
||||||
"(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
|
|
||||||
|
|
||||||
jclass configClass = env->FindClass("android/graphics/Bitmap$Config");
|
|
||||||
jfieldID argb8888 = env->GetStaticFieldID(configClass, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
|
|
||||||
jobject configObj = env->GetStaticObjectField(configClass, argb8888);
|
|
||||||
|
|
||||||
uint32_t width = result.diffImage.getWidth();
|
|
||||||
uint32_t height = result.diffImage.getHeight();
|
|
||||||
jobject diffBitmap = env->CallStaticObjectMethod(bitmapClass, createBitmap, (jint)width, (jint)height, configObj);
|
|
||||||
|
|
||||||
if (diffBitmap) {
|
|
||||||
void* diffPixels;
|
|
||||||
if (AndroidBitmap_lockPixels(env, diffBitmap, &diffPixels) == 0) {
|
|
||||||
float const* src = result.diffImage.getPixelRef();
|
|
||||||
uint8_t* dst = (uint8_t*) diffPixels;
|
|
||||||
uint32_t channels = result.diffImage.getChannels(); // usually 4
|
|
||||||
|
|
||||||
for (size_t i = 0; i < width * height; ++i) {
|
|
||||||
for (int c = 0; c < 4; ++c) {
|
|
||||||
float v = 0.0f;
|
|
||||||
if (c < channels) v = src[i * channels + c];
|
|
||||||
if (c == 3 && channels < 4) v = 1.0f; // Alpha 1.0 if missing
|
|
||||||
dst[i * 4 + c] = (uint8_t) std::min(255.0f, std::max(0.0f, v * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AndroidBitmap_unlockPixels(env, diffBitmap);
|
|
||||||
env->SetObjectField(resultObj, diffImageField, diffBitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jobject JNICALL
|
|
||||||
Java_com_google_android_filament_utils_ImageDiff_nCompareBasic(JNIEnv* env, jclass,
|
|
||||||
jobject refBitmap, jobject candBitmap, jint mode, jint swizzle, jint channelMask,
|
|
||||||
jfloat maxAbsDiff, jfloat maxFailingPixelsFraction, jobject maskBitmap) {
|
|
||||||
|
|
||||||
BitmapLock refArg(env, refBitmap);
|
|
||||||
BitmapLock candArg(env, candBitmap);
|
|
||||||
BitmapLock maskArg(env, maskBitmap);
|
|
||||||
|
|
||||||
if (!refArg.isValid() || !candArg.isValid()) {
|
|
||||||
ImageDiffResult emptyResult;
|
|
||||||
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
|
|
||||||
return createResult(env, emptyResult, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageDiffConfig config;
|
|
||||||
config.mode = (ImageDiffConfig::Mode) mode;
|
|
||||||
config.swizzle = (ImageDiffConfig::Swizzle) swizzle;
|
|
||||||
config.channelMask = (uint8_t) channelMask;
|
|
||||||
config.maxAbsDiff = maxAbsDiff;
|
|
||||||
config.maxFailingPixelsFraction = maxFailingPixelsFraction;
|
|
||||||
|
|
||||||
imagediff::Bitmap const* maskPtr = nullptr;
|
|
||||||
imagediff::Bitmap maskVal;
|
|
||||||
if (maskBitmap && maskArg.isValid()) {
|
|
||||||
maskVal = maskArg.toBitmap();
|
|
||||||
maskPtr = &maskVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool generateDiff = true;
|
|
||||||
ImageDiffResult result = compare(refArg.toBitmap(), candArg.toBitmap(), config, maskPtr, generateDiff);
|
|
||||||
|
|
||||||
return createResult(env, result, generateDiff);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" JNIEXPORT jobject JNICALL
|
|
||||||
Java_com_google_android_filament_utils_ImageDiff_nCompareJson(JNIEnv* env, jclass,
|
|
||||||
jobject refBitmap, jobject candBitmap, jstring jsonConfig, jobject maskBitmap) {
|
|
||||||
|
|
||||||
BitmapLock refArg(env, refBitmap);
|
|
||||||
BitmapLock candArg(env, candBitmap);
|
|
||||||
BitmapLock maskArg(env, maskBitmap);
|
|
||||||
|
|
||||||
if (!refArg.isValid() || !candArg.isValid()) {
|
|
||||||
ImageDiffResult emptyResult;
|
|
||||||
emptyResult.status = ImageDiffResult::Status::SIZE_MISMATCH; // or ERROR
|
|
||||||
return createResult(env, emptyResult, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageDiffConfig config;
|
|
||||||
const char* nativeJson = env->GetStringUTFChars(jsonConfig, 0);
|
|
||||||
size_t length = env->GetStringUTFLength(jsonConfig);
|
|
||||||
|
|
||||||
bool parsed = parseConfig(nativeJson, length, &config);
|
|
||||||
env->ReleaseStringUTFChars(jsonConfig, nativeJson);
|
|
||||||
|
|
||||||
if (!parsed) {
|
|
||||||
// Fallback to default or error?
|
|
||||||
// We could log error.
|
|
||||||
utils::slog.e << "ImageDiff JNI: Failed to parse JSON config" << utils::io::endl;
|
|
||||||
ImageDiffResult errResult;
|
|
||||||
errResult.status = ImageDiffResult::Status::PIXEL_DIFFERENCE; // assume fail
|
|
||||||
return createResult(env, errResult, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
imagediff::Bitmap const* maskPtr = nullptr;
|
|
||||||
imagediff::Bitmap maskVal;
|
|
||||||
if (maskBitmap && maskArg.isValid()) {
|
|
||||||
maskVal = maskArg.toBitmap();
|
|
||||||
maskPtr = &maskVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool generateDiff = true;
|
|
||||||
ImageDiffResult result = compare(refArg.toBitmap(), candArg.toBitmap(), config, maskPtr, generateDiff);
|
|
||||||
|
|
||||||
return createResult(env, result, generateDiff);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -94,23 +94,20 @@ public class AutomationEngine {
|
|||||||
* Allows remote control for the viewer.
|
* Allows remote control for the viewer.
|
||||||
*/
|
*/
|
||||||
public static class ViewerOptions {
|
public static class ViewerOptions {
|
||||||
|
public float cameraAperture = 16.0f;
|
||||||
|
public float cameraSpeed = 125.0f;
|
||||||
|
public float cameraISO = 100.0f;
|
||||||
|
public float cameraNear = 0.1f;
|
||||||
|
public float cameraFar = 100.0f;
|
||||||
public float groundShadowStrength = 0.75f;
|
public float groundShadowStrength = 0.75f;
|
||||||
public boolean groundPlaneEnabled = false;
|
public boolean groundPlaneEnabled = false;
|
||||||
public boolean skyboxEnabled = true;
|
public boolean skyboxEnabled = true;
|
||||||
|
public float cameraFocalLength = 28.0f;
|
||||||
|
public float cameraFocusDistance = 0.0f;
|
||||||
public boolean autoScaleEnabled = true;
|
public boolean autoScaleEnabled = true;
|
||||||
public boolean autoInstancingEnabled = false;
|
public boolean autoInstancingEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CameraSettings {
|
|
||||||
public float aperture = 16.0f;
|
|
||||||
public float shutterSpeed = 125.0f;
|
|
||||||
public float sensitivity = 100.0f;
|
|
||||||
public float near = 0.1f;
|
|
||||||
public float far = 100.0f;
|
|
||||||
public float focalLength = 28.0f;
|
|
||||||
public float focusDistance = 10.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an automation engine from a JSON specification.
|
* Creates an automation engine from a JSON specification.
|
||||||
*
|
*
|
||||||
@@ -178,12 +175,7 @@ public class AutomationEngine {
|
|||||||
}
|
}
|
||||||
long nativeView = content.view.getNativeObject();
|
long nativeView = content.view.getNativeObject();
|
||||||
long nativeRenderer = content.renderer.getNativeObject();
|
long nativeRenderer = content.renderer.getNativeObject();
|
||||||
long nativeIbl = content.indirectLight == null ? 0 : content.indirectLight.getNativeObject();
|
nTick(mNativeObject, engine.getNativeObject(), nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
|
||||||
long nativeLm = content.lightManager == null ? 0 : content.lightManager.getNativeObject();
|
|
||||||
long nativeScene = content.scene == null ? 0 : content.scene.getNativeObject();
|
|
||||||
nTick(mNativeObject, engine.getNativeObject(), nativeView, nativeMaterialInstances,
|
|
||||||
nativeRenderer, nativeIbl, content.sunlight, content.assetLights, nativeLm,
|
|
||||||
nativeScene, deltaTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -237,13 +229,6 @@ public class AutomationEngine {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public CameraSettings getCameraSettings() {
|
|
||||||
CameraSettings result = new CameraSettings();
|
|
||||||
nGetCameraSettings(mNativeObject, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a color grading object that corresponds to the latest settings.
|
* Gets a color grading object that corresponds to the latest settings.
|
||||||
*
|
*
|
||||||
@@ -276,9 +261,6 @@ public class AutomationEngine {
|
|||||||
*/
|
*/
|
||||||
public boolean shouldClose() { return nShouldClose(mNativeObject); }
|
public boolean shouldClose() { return nShouldClose(mNativeObject); }
|
||||||
|
|
||||||
public int getTestCount() { return nGetTestCount(mNativeObject); }
|
|
||||||
public int getCurrentTest() { return nGetCurrentTest(mNativeObject); }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void finalize() throws Throwable {
|
protected void finalize() throws Throwable {
|
||||||
nDestroy(mNativeObject);
|
nDestroy(mNativeObject);
|
||||||
@@ -292,19 +274,15 @@ public class AutomationEngine {
|
|||||||
private static native void nStartRunning(long nativeObject);
|
private static native void nStartRunning(long nativeObject);
|
||||||
private static native void nStartBatchMode(long nativeObject);
|
private static native void nStartBatchMode(long nativeObject);
|
||||||
private static native void nTick(long nativeObject, long nativeEngine,
|
private static native void nTick(long nativeObject, long nativeEngine,
|
||||||
long view, long[] materials, long renderer, long ibl, int sunlight, int[] assetLights,
|
long view, long[] materials, long renderer, float deltaTime);
|
||||||
long lightManager, long scene, float deltaTime);
|
|
||||||
private static native void nApplySettings(long nativeObject, long nativeEngine,
|
private static native void nApplySettings(long nativeObject, long nativeEngine,
|
||||||
String jsonSettings, long view,
|
String jsonSettings, long view,
|
||||||
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
|
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
|
||||||
long scene, long renderer);
|
long scene, long renderer);
|
||||||
private static native void nGetViewerOptions(long nativeObject, Object result);
|
private static native void nGetViewerOptions(long nativeObject, Object result);
|
||||||
private static native void nGetCameraSettings(long nativeObject, Object result);
|
|
||||||
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
|
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
|
||||||
private static native void nSignalBatchMode(long nativeObject);
|
private static native void nSignalBatchMode(long nativeObject);
|
||||||
private static native void nStopRunning(long nativeObject);
|
private static native void nStopRunning(long nativeObject);
|
||||||
private static native boolean nShouldClose(long nativeObject);
|
private static native boolean nShouldClose(long nativeObject);
|
||||||
private static native int nGetTestCount(long nativeObject);
|
|
||||||
private static native int nGetCurrentTest(long nativeObject);
|
|
||||||
private static native void nDestroy(long nativeObject);
|
private static native void nDestroy(long nativeObject);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2026 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.utils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
public class ImageDiff {
|
|
||||||
public enum Mode {
|
|
||||||
LEAF, AND, OR
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Swizzle {
|
|
||||||
RGBA, BGRA
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Config {
|
|
||||||
@NonNull
|
|
||||||
public Mode mode = Mode.LEAF;
|
|
||||||
@NonNull
|
|
||||||
public Swizzle swizzle = Swizzle.RGBA;
|
|
||||||
public int channelMask = 0xF;
|
|
||||||
public float maxAbsDiff = 0.0f;
|
|
||||||
public float maxFailingPixelsFraction = 0.0f;
|
|
||||||
// Children not supported in this simple wrapper for now, can be added if needed
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Result {
|
|
||||||
public enum Status {
|
|
||||||
PASSED,
|
|
||||||
SIZE_MISMATCH,
|
|
||||||
PIXEL_DIFFERENCE
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status status;
|
|
||||||
public long failingPixelCount;
|
|
||||||
public float[] maxDiffFound; // [R, G, B, A]
|
|
||||||
public Bitmap diffImage; // Null if not generated
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares two bitmaps using a configuration object.
|
|
||||||
*
|
|
||||||
* @param reference Golden image
|
|
||||||
* @param candidate Actual image
|
|
||||||
* @param config Comparison configuration
|
|
||||||
* @param mask Optional mask (grayscale)
|
|
||||||
* @return Result of comparison
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public static Result compareBasic(@NonNull Bitmap reference, @NonNull Bitmap candidate,
|
|
||||||
@NonNull Config config, @Nullable Bitmap mask) {
|
|
||||||
return nCompareBasic(reference, candidate, config.mode.ordinal(), config.swizzle.ordinal(),
|
|
||||||
config.channelMask, config.maxAbsDiff, config.maxFailingPixelsFraction, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares two bitmaps using a JSON configuration string.
|
|
||||||
*
|
|
||||||
* @param reference Golden image
|
|
||||||
* @param candidate Actual image
|
|
||||||
* @param jsonConfig Comparison configuration in JSON format
|
|
||||||
* @param mask Optional mask (grayscale)
|
|
||||||
* @return Result of comparison
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public static Result compare(@NonNull Bitmap reference, @NonNull Bitmap candidate,
|
|
||||||
@NonNull String jsonConfig, @Nullable Bitmap mask) {
|
|
||||||
return nCompareJson(reference, candidate, jsonConfig, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static native Result nCompareBasic(Bitmap reference, Bitmap candidate, int mode, int swizzle,
|
|
||||||
int channelMask, float maxAbsDiff, float maxFailingPixelsFraction, Bitmap mask);
|
|
||||||
|
|
||||||
private static native Result nCompareJson(Bitmap reference, Bitmap candidate, String jsonConfig, Bitmap mask);
|
|
||||||
}
|
|
||||||
@@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package com.google.android.filament.utils
|
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.MotionEvent
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
import android.view.SurfaceView
|
import android.view.SurfaceView
|
||||||
@@ -29,7 +26,6 @@ import com.google.android.filament.android.UiHelper
|
|||||||
import com.google.android.filament.gltfio.*
|
import com.google.android.filament.gltfio.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import java.nio.Buffer
|
import java.nio.Buffer
|
||||||
import java.nio.ByteBuffer
|
|
||||||
|
|
||||||
private const val kNearPlane = 0.05f // 5 cm
|
private const val kNearPlane = 0.05f // 5 cm
|
||||||
private const val kFarPlane = 1000.0f // 1 km
|
private const val kFarPlane = 1000.0f // 1 km
|
||||||
@@ -123,8 +119,6 @@ class ModelViewer(
|
|||||||
private val target = DoubleArray(3)
|
private val target = DoubleArray(3)
|
||||||
private val upward = DoubleArray(3)
|
private val upward = DoubleArray(3)
|
||||||
|
|
||||||
private var debugFrameCallback: ((Bitmap) -> Unit)? = null
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
renderer = engine.createRenderer()
|
renderer = engine.createRenderer()
|
||||||
scene = engine.createScene()
|
scene = engine.createScene()
|
||||||
@@ -311,39 +305,10 @@ class ModelViewer(
|
|||||||
// Render the scene, unless the renderer wants to skip the frame.
|
// Render the scene, unless the renderer wants to skip the frame.
|
||||||
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
|
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
|
||||||
renderer.render(view)
|
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()
|
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) {
|
private fun populateScene(asset: FilamentAsset) {
|
||||||
val rcm = engine.renderableManager
|
val rcm = engine.renderableManager
|
||||||
var count = 0
|
var count = 0
|
||||||
|
|||||||
@@ -40,21 +40,7 @@ fun loadTexture(engine: Engine, resources: Resources, resourceId: Int, type: Tex
|
|||||||
options.inPremultiplied = type == TextureType.COLOR
|
options.inPremultiplied = type == TextureType.COLOR
|
||||||
|
|
||||||
val bitmap = BitmapFactory.decodeResource(resources, resourceId, options)
|
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()
|
val texture = Texture.Builder()
|
||||||
.width(bitmap.width)
|
.width(bitmap.width)
|
||||||
.height(bitmap.height)
|
.height(bitmap.height)
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ object Utils {
|
|||||||
/**
|
/**
|
||||||
* Initializes the utils JNI layer. Must be called before using any utils functionality.
|
* Initializes the utils JNI layer. Must be called before using any utils functionality.
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
|
||||||
fun init() {
|
fun init() {
|
||||||
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
|
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
|
||||||
Filament.init()
|
Filament.init()
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
|
|||||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||||
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
||||||
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" 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)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
@@ -31,12 +30,6 @@ add_library(stb STATIC IMPORTED)
|
|||||||
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
|
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
|
${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)
|
add_library(basis_transcoder STATIC IMPORTED)
|
||||||
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
||||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
||||||
@@ -88,10 +81,6 @@ set(GLTFIO_INCLUDE_DIRS
|
|||||||
../../libs/ktxreader/include
|
../../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})
|
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
|
||||||
|
|
||||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
|
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 perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
|
||||||
PRIVATE log # needed only when perfetto above is used
|
PRIVATE log # needed only when perfetto above is used
|
||||||
)
|
)
|
||||||
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
|
|
||||||
target_link_libraries(gltfio-jni PRIVATE webpdecoder)
|
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -128,18 +128,6 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEn
|
|||||||
return (jlong) createKtx2Provider(engine);
|
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
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
|
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
|
||||||
jlong nativeProvider) {
|
jlong nativeProvider) {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class ResourceLoader {
|
|||||||
private final long mNativeObject;
|
private final long mNativeObject;
|
||||||
private final long mNativeStbProvider;
|
private final long mNativeStbProvider;
|
||||||
private final long mNativeKtx2Provider;
|
private final long mNativeKtx2Provider;
|
||||||
private final long mNativeWebpProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a resource loader tied to the given Filament engine.
|
* Constructs a resource loader tied to the given Filament engine.
|
||||||
@@ -51,17 +50,9 @@ public class ResourceLoader {
|
|||||||
mNativeObject = nCreateResourceLoader(nativeEngine, false);
|
mNativeObject = nCreateResourceLoader(nativeEngine, false);
|
||||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||||
|
|
||||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
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);
|
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
|
||||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||||
|
|
||||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
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);
|
nDestroyResourceLoader(mNativeObject);
|
||||||
nDestroyTextureProvider(mNativeStbProvider);
|
nDestroyTextureProvider(mNativeStbProvider);
|
||||||
nDestroyTextureProvider(mNativeKtx2Provider);
|
nDestroyTextureProvider(mNativeKtx2Provider);
|
||||||
if (nIsWebpSupported()) {
|
|
||||||
nDestroyTextureProvider(mNativeWebpProvider);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,9 +191,6 @@ public class ResourceLoader {
|
|||||||
|
|
||||||
private static native long nCreateStbProvider(long nativeEngine);
|
private static native long nCreateStbProvider(long nativeEngine);
|
||||||
private static native long nCreateKtx2Provider(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 nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
|
||||||
private static native void nDestroyTextureProvider(long nativeProvider);
|
private static native void nDestroyTextureProvider(long nativeProvider);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
GROUP=com.google.android.filament
|
GROUP=com.google.android.filament
|
||||||
VERSION_NAME=1.69.4
|
VERSION_NAME=1.65.0
|
||||||
|
|
||||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||||
|
|
||||||
|
|||||||
@@ -80,12 +80,54 @@ frame and the external texture are perfectly synchronized.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Building Samples
|
## Prerequisites
|
||||||
|
|
||||||
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
|
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
|
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
|
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.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,27 +10,19 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
cmgenArgs = "-q --format=ktx --size=256 --extract-blur=0.1 --deploy=src/main/assets/envs/default_env"
|
cmgenArgs = "-q --format=ktx --size=256 --extract-blur=0.1 --deploy=src/main/assets/envs/default_env"
|
||||||
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/lightroom_14b.hdr")
|
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/lightroom_14b.hdr")
|
||||||
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't forget to update MainACtivity.kt when/if changing this.
|
// don't forget to update MainACtivity.kt when/if changing this.
|
||||||
tasks.register('copyDamagedHelmetGltf', Copy) {
|
tasks.register('copyMesh', 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) {
|
|
||||||
from "../../../third_party/models/BusterDrone"
|
from "../../../third_party/models/BusterDrone"
|
||||||
into "src/main/assets/models"
|
into "src/main/assets/models"
|
||||||
}
|
}
|
||||||
|
|
||||||
preBuild.dependsOn copyDamagedHelmetGltf
|
preBuild.dependsOn copyMesh
|
||||||
preBuild.dependsOn copyBusterGltf
|
|
||||||
|
|
||||||
clean.doFirst {
|
clean.doFirst {
|
||||||
delete "src/main/assets"
|
delete "src/main/assets"
|
||||||
|
|||||||
@@ -389,9 +389,9 @@ class MainActivity : Activity() {
|
|||||||
viewerContent.assetLights = modelViewer.asset?.lightEntities
|
viewerContent.assetLights = modelViewer.asset?.lightEntities
|
||||||
automation.applySettings(modelViewer.engine, json, viewerContent)
|
automation.applySettings(modelViewer.engine, json, viewerContent)
|
||||||
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
|
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
|
||||||
modelViewer.cameraFocalLength = automation.cameraSettings.focalLength
|
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
|
||||||
modelViewer.cameraNear = automation.cameraSettings.near
|
modelViewer.cameraNear = automation.viewerOptions.cameraNear
|
||||||
modelViewer.cameraFar = automation.cameraSettings.far
|
modelViewer.cameraFar = automation.viewerOptions.cameraFar
|
||||||
updateRootTransform()
|
updateRootTransform()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,7 +10,7 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ android {
|
|||||||
|
|
||||||
compileSdkVersion versions.compileSdk
|
compileSdkVersion versions.compileSdk
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.google.android.filament.hellocam"
|
applicationId "com.google.android.filament.hellocamera"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion versions.targetSdk
|
targetSdkVersion versions.targetSdk
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,7 +10,7 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,7 +10,7 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,7 +10,7 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
id 'kotlin-android'
|
id 'kotlin-android'
|
||||||
id 'filament-plugin'
|
id 'filament-tools-plugin'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.isSample = true
|
project.ext.isSample = true
|
||||||
@@ -10,7 +10,7 @@ kotlin {
|
|||||||
jvmToolchain(versions.jdk)
|
jvmToolchain(versions.jdk)
|
||||||
}
|
}
|
||||||
|
|
||||||
filament {
|
filamentTools {
|
||||||
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
|
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
|
||||||
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
|
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'com.android.application'
|
|
||||||
id 'kotlin-android'
|
|
||||||
id 'filament-plugin'
|
|
||||||
}
|
|
||||||
|
|
||||||
project.ext.isSample = true
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
jvmToolchain(versions.jdk)
|
|
||||||
}
|
|
||||||
|
|
||||||
filament {
|
|
||||||
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')
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |