Compare commits
261 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8570e35224 | ||
|
|
84df9f9a03 | ||
|
|
5f93fb9613 | ||
|
|
75f77fdbdd | ||
|
|
7825d582c2 | ||
|
|
5deb0ba933 | ||
|
|
18e917aaf2 | ||
|
|
a165f3890a | ||
|
|
f88b6d9c97 | ||
|
|
db8ecd9952 | ||
|
|
b5ec06c2d2 | ||
|
|
dfbac8385e | ||
|
|
eceb72f609 | ||
|
|
aad782a15f | ||
|
|
eaab737b2c | ||
|
|
378600dc79 | ||
|
|
d4cc63f120 | ||
|
|
b99fd143f2 | ||
|
|
8c74430466 | ||
|
|
fc9608a392 | ||
|
|
ad731aebcb | ||
|
|
15406825aa | ||
|
|
1e17afbefa | ||
|
|
83334f7567 | ||
|
|
7275957947 | ||
|
|
45991cda0a | ||
|
|
74765f05bc | ||
|
|
bae32a1a5f | ||
|
|
347642985f | ||
|
|
6ebaad28b3 | ||
|
|
9508bf2a0c | ||
|
|
68c6253b3f | ||
|
|
803ce07701 | ||
|
|
95d3b19ced | ||
|
|
cc97a62587 | ||
|
|
434144eef2 | ||
|
|
09a016bb6f | ||
|
|
adf894a5bc | ||
|
|
5e4025bd4c | ||
|
|
9f8af21ad7 | ||
|
|
61e117beaa | ||
|
|
ec86fe4e33 | ||
|
|
3c29ec5c8e | ||
|
|
de32fc83a4 | ||
|
|
51e8a83234 | ||
|
|
b8163b7949 | ||
|
|
30dbd3ac4f | ||
|
|
0ae83a6c97 | ||
|
|
5ee54aa4ef | ||
|
|
56e7ae1d56 | ||
|
|
39332a92ed | ||
|
|
31607d355d | ||
|
|
a67d50b9e2 | ||
|
|
6a82f8090e | ||
|
|
8d42f53c80 | ||
|
|
5e21a55bce | ||
|
|
5860e7fdce | ||
|
|
22c3ba2466 | ||
|
|
4e260ba3dc | ||
|
|
49674c39e8 | ||
|
|
23174d56f5 | ||
|
|
5ff3e85d10 | ||
|
|
2242ddfbec | ||
|
|
69ec5f9720 | ||
|
|
6162782bee | ||
|
|
599b2ef377 | ||
|
|
7aa3b1a6ee | ||
|
|
718e7ab064 | ||
|
|
991fa0cf7d | ||
|
|
e81d053f35 | ||
|
|
211cf2b64c | ||
|
|
5837adf45f | ||
|
|
85930ea2e8 | ||
|
|
9bb6ce5f1d | ||
|
|
4b3cde8b39 | ||
|
|
eedfa85355 | ||
|
|
bb54c6c807 | ||
|
|
c23f905858 | ||
|
|
ab9dbb22cc | ||
|
|
2a84fe052c | ||
|
|
140ebbf10d | ||
|
|
00ecba67b5 | ||
|
|
beb8fd9893 | ||
|
|
cc7d88c033 | ||
|
|
f85103af9d | ||
|
|
6471efb3a5 | ||
|
|
f2e36c35a4 | ||
|
|
2eaacd7cb8 | ||
|
|
8c7be0a1d0 | ||
|
|
cc51d478f8 | ||
|
|
a844dc96eb | ||
|
|
e92a684b26 | ||
|
|
a5648de486 | ||
|
|
88dc25229b | ||
|
|
ddd93874cc | ||
|
|
609c0482be | ||
|
|
92acdff6cb | ||
|
|
292fd7d41f | ||
|
|
1af76638cf | ||
|
|
bf875554e1 | ||
|
|
2b91799ee0 | ||
|
|
2947229d40 | ||
|
|
878497b3d5 | ||
|
|
a155561769 | ||
|
|
648314d730 | ||
|
|
fc3c3376b7 | ||
|
|
fcbc6d43a1 | ||
|
|
a01fa21209 | ||
|
|
8b86a0ed2e | ||
|
|
60a6d4a348 | ||
|
|
6c740f060e | ||
|
|
5a8bf42ddb | ||
|
|
c8cc74e384 | ||
|
|
26f9a9b122 | ||
|
|
c82ae6a3a7 | ||
|
|
fbc43d24fe | ||
|
|
c0f8f3bdfe | ||
|
|
3461ec863b | ||
|
|
035f162ebc | ||
|
|
6754885795 | ||
|
|
42e4e5e3ae | ||
|
|
71a0f46b73 | ||
|
|
6e5f6978fb | ||
|
|
0d31d7b2de | ||
|
|
5f52afdc08 | ||
|
|
54706ad65e | ||
|
|
a96d5932a8 | ||
|
|
41c5615201 | ||
|
|
719427764c | ||
|
|
dd862b7e0a | ||
|
|
52065f2cbd | ||
|
|
887fb82cf2 | ||
|
|
0c78e91aed | ||
|
|
62a234a8f9 | ||
|
|
77c02d5831 | ||
|
|
f7e4c8d16d | ||
|
|
29086cee14 | ||
|
|
16369255e2 | ||
|
|
b3e9940625 | ||
|
|
c04f3e4f00 | ||
|
|
13f7c71bf2 | ||
|
|
b7410474ff | ||
|
|
eae55c1be8 | ||
|
|
d6588bd382 | ||
|
|
3343f2459d | ||
|
|
78679338d7 | ||
|
|
c049a1bfff | ||
|
|
f311453aed | ||
|
|
c67e5b6047 | ||
|
|
7ed315e8ab | ||
|
|
1d223498cb | ||
|
|
cbcaae6537 | ||
|
|
b8705198c0 | ||
|
|
bef3c85ebf | ||
|
|
2709533fb1 | ||
|
|
e3854f5c58 | ||
|
|
edb9ca71e5 | ||
|
|
ad9ce72f61 | ||
|
|
78f2065b6f | ||
|
|
a18013c8f4 | ||
|
|
b7787b9a1a | ||
|
|
63cfb817d7 | ||
|
|
a572a10ef7 | ||
|
|
e2255e45d8 | ||
|
|
0e5ba60cb6 | ||
|
|
f78d131015 | ||
|
|
384cc4ebf6 | ||
|
|
bf63baad53 | ||
|
|
7c0643f122 | ||
|
|
58abae3067 | ||
|
|
4742693869 | ||
|
|
f229aaa7c4 | ||
|
|
bf34ee6e22 | ||
|
|
a68a478bf3 | ||
|
|
626beee345 | ||
|
|
f40ef6209b | ||
|
|
c4c8399247 | ||
|
|
7baffe34ac | ||
|
|
434dce2b9f | ||
|
|
a76e74fb09 | ||
|
|
f39815393a | ||
|
|
9031babd92 | ||
|
|
c608f6ad79 | ||
|
|
efec4e1adc | ||
|
|
ebd5f150c1 | ||
|
|
156dcb54e8 | ||
|
|
88ef76989c | ||
|
|
fc284af684 | ||
|
|
3a8685cd15 | ||
|
|
f035655f5b | ||
|
|
f498e08d1e | ||
|
|
db3186a65f | ||
|
|
248815a3e0 | ||
|
|
6c39e474ea | ||
|
|
5c8977c906 | ||
|
|
ebb62b5d55 | ||
|
|
6b3cc2e2f3 | ||
|
|
b9a5ad205a | ||
|
|
100986d8d9 | ||
|
|
b7c9a36d57 | ||
|
|
d76551ab28 | ||
|
|
92bc0752d1 | ||
|
|
657c251463 | ||
|
|
b6b8fee483 | ||
|
|
be5b60f895 | ||
|
|
681d31758f | ||
|
|
76b2edd6ea | ||
|
|
80dc2f5c9d | ||
|
|
ce7dd7a1fb | ||
|
|
85617c96a2 | ||
|
|
58760adb6a | ||
|
|
4ef0b72773 | ||
|
|
45631c3b81 | ||
|
|
6f6dde2579 | ||
|
|
e0acbe42cf | ||
|
|
4f137ccf89 | ||
|
|
04010e7dd9 | ||
|
|
f4f9f331c0 | ||
|
|
dada291f6b | ||
|
|
18f2f8b6d4 | ||
|
|
d4117ac968 | ||
|
|
eccbc8c242 | ||
|
|
3cdf24f515 | ||
|
|
d91faf9df8 | ||
|
|
d950efa6ea | ||
|
|
8ebb37d011 | ||
|
|
861d69ea7c | ||
|
|
b2cc904fab | ||
|
|
3f87b520bb | ||
|
|
135a362176 | ||
|
|
391ebc3702 | ||
|
|
b4d1443720 | ||
|
|
c06737aca2 | ||
|
|
f847232296 | ||
|
|
89f06b8923 | ||
|
|
90a2b1f3c9 | ||
|
|
059f51338d | ||
|
|
d3cea5121e | ||
|
|
c37301d2dc | ||
|
|
aa16778fbd | ||
|
|
ee499ad2ca | ||
|
|
958dd5bb27 | ||
|
|
f988b75999 | ||
|
|
e3ccb4bb3c | ||
|
|
3f0dc6f7e6 | ||
|
|
c212dd5bc7 | ||
|
|
1eceab0040 | ||
|
|
ab9d1e5956 | ||
|
|
c906290416 | ||
|
|
d52a24b6e9 | ||
|
|
9aeec3a759 | ||
|
|
550fcfe2e3 | ||
|
|
b2cdf9f2b4 | ||
|
|
19a3fe3dce | ||
|
|
754abbf78e | ||
|
|
9b855e9a03 | ||
|
|
2534fdf92d | ||
|
|
dab02e915e | ||
|
|
68da1a25eb | ||
|
|
c67b363576 | ||
|
|
5c0e7d8211 |
10
.github/actions/verify-release-notes/Dockerfile
vendored
Normal file
10
.github/actions/verify-release-notes/Dockerfile
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM python:3.10.4
|
||||
|
||||
RUN pip3 install pygithub==1.55
|
||||
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
COPY verify_release_notes.py /verify_release_notes.py
|
||||
|
||||
RUN chmod +x /verify_release_notes.py
|
||||
ENTRYPOINT [ "/verify_release_notes.py" ]
|
||||
35
.github/actions/verify-release-notes/action.yml
vendored
Normal file
35
.github/actions/verify-release-notes/action.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: 'Verify Release Notes'
|
||||
description: 'Verifies that a RELEASE_NOTES file has been modified'
|
||||
inputs:
|
||||
repo-token:
|
||||
description: 'The GitHub token'
|
||||
required: true
|
||||
pull-request-number:
|
||||
description: 'The Pull Request number'
|
||||
required: true
|
||||
bypass-label-name:
|
||||
description: 'The Label used to bypass this check'
|
||||
required: false
|
||||
default: 'internal'
|
||||
release-notes-file:
|
||||
description: 'The path to the RELEASE_NOTES file'
|
||||
required: false
|
||||
default: 'RELEASE_NOTES.md'
|
||||
pull-request-repo-full-name:
|
||||
description: 'The full name of the Pull Request repo'
|
||||
required: false
|
||||
default: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
pull-request-head-ref:
|
||||
description: 'The HEAD ref of the Pull Request'
|
||||
required: false
|
||||
default: ${{ github.event.pull_request.head.ref }}
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
args:
|
||||
- ${{ inputs.repo-token }}
|
||||
- ${{ inputs.pull-request-number }}
|
||||
- ${{ inputs.bypass-label-name }}
|
||||
- ${{ inputs.release-notes-file }}
|
||||
- ${{ inputs.pull-request-repo-full-name }}
|
||||
- ${{ inputs.pull-request-head-ref }}
|
||||
100
.github/actions/verify-release-notes/verify_release_notes.py
vendored
Executable file
100
.github/actions/verify-release-notes/verify_release_notes.py
vendored
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (C) 2022 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.
|
||||
|
||||
from github import Github
|
||||
import sys, os
|
||||
|
||||
def print_usage():
|
||||
print('Verify that a GitHub pull request modifies a RELEASE_NOTES file')
|
||||
print()
|
||||
print('Usage:')
|
||||
print(' verify_release_notes.py [arguments]')
|
||||
print()
|
||||
print('Arguments:')
|
||||
print('1. github token')
|
||||
print('2. pull request number')
|
||||
print('3. bypass label name')
|
||||
print('4. release notes file path')
|
||||
print('5. pull request repo full name')
|
||||
print('6. pull request head ref')
|
||||
print()
|
||||
print('The GITHUB_REPOSITORY environment variable must be set (e.g., google/filament).')
|
||||
|
||||
def leave_single_comment(pull_request, comment_body):
|
||||
""" Leaves a comment on a PR once, without leaving a duplicate comment. """
|
||||
# To avoid spamming the PR author, we'll use this comment tag (which will render invisibly on
|
||||
# GitHub) to check if we've already left a comment on this PR.
|
||||
COMMENT_TAG = '<!-- verify_release_notes -->\n'
|
||||
comments = pull_request.get_issue_comments()
|
||||
for comment in comments:
|
||||
if comment.body.find(COMMENT_TAG) != -1:
|
||||
return
|
||||
# The GitHub token may not have WRITE permissions to leave a comment (for example, for 3P
|
||||
# contributors). In that case, we simply won't leave a comment.
|
||||
try:
|
||||
pull_request.create_issue_comment(f'{COMMENT_TAG}{comment_body}')
|
||||
except:
|
||||
print("Unable to leave comment. Continuing.")
|
||||
|
||||
# The first argument is the path to this script.
|
||||
if len(sys.argv) != 7:
|
||||
print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
authentication_token = sys.argv[1]
|
||||
pull_number = sys.argv[2]
|
||||
bypass_label_name = sys.argv[3]
|
||||
release_notes_file = sys.argv[4]
|
||||
pr_repo_full_name = sys.argv[5]
|
||||
pr_head_ref = sys.argv[6]
|
||||
|
||||
g = Github(authentication_token)
|
||||
|
||||
repo_name = os.environ.get('GITHUB_REPOSITORY')
|
||||
if repo_name is None:
|
||||
print("The GITHUB_REPOSITORY environment variable must be set.")
|
||||
sys.exit(1)
|
||||
|
||||
repo = g.get_repo(repo_name)
|
||||
|
||||
pull_request = repo.get_pull(int(pull_number))
|
||||
|
||||
# First check if the PR has the "bypass" label. This label is used for PRs that don't need to update
|
||||
# RELEASE_NOTES. If so, we can exit immediately.
|
||||
labels = [l.name for l in pull_request.labels]
|
||||
if bypass_label_name in labels:
|
||||
print(f"PR number {pull_number} in repo {repo_name} contains the '{bypass_label_name}' label.")
|
||||
print("Exiting with success.")
|
||||
sys.exit(0)
|
||||
|
||||
# Next, check if the release notes file (RELEASE_NOTES.md or similar) has been modified.
|
||||
files = pull_request.get_files()
|
||||
for file in files:
|
||||
if file.filename == release_notes_file:
|
||||
print(f"PR number {pull_number} in repo {repo_name} modifies '{release_notes_file}'.")
|
||||
print("Exiting with success.")
|
||||
sys.exit(0)
|
||||
|
||||
# At this point, we issue a warning to the PR author to remember to modify the release notes, and
|
||||
# exit with failure.
|
||||
edit_url = f"https://github.com/{pr_repo_full_name}/edit/{pr_head_ref}/{release_notes_file}"
|
||||
comment = (f"Please add a release note line to [{release_notes_file}]({edit_url}). "
|
||||
f"If this PR does not warrant a release note, add the '{bypass_label_name}' label "
|
||||
f"to this PR.")
|
||||
print(comment)
|
||||
leave_single_comment(pull_request, comment)
|
||||
|
||||
sys.exit(1)
|
||||
4
.github/workflows/android-continuous.yml
vendored
4
.github/workflows/android-continuous.yml
vendored
@@ -33,10 +33,6 @@ jobs:
|
||||
with:
|
||||
name: gltfio-android-release
|
||||
path: out/gltfio-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: gltfio-android-lite-release
|
||||
path: out/gltfio-android-lite-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filament-utils-android-release
|
||||
|
||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -126,7 +126,6 @@ jobs:
|
||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
|
||||
26
.github/workflows/verify-release-notes.yml
vendored
Normal file
26
.github/workflows/verify-release-notes.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Verify Release Notes
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
types: [opened, synchronize, reopened, labeled]
|
||||
|
||||
jobs:
|
||||
verify-release-notes:
|
||||
name: Verify Release Notes
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# We *only* need to check out the .github/ directory.
|
||||
# The verify RELEASE_NOTES script uses the GitHub API to verify that RELEASE_NOTES was
|
||||
# modified.
|
||||
- name: Check out action
|
||||
uses: Bhacaz/checkout-files@73e17cfbe8d7e0c6b2672b20cb05a718e20d18d4
|
||||
with:
|
||||
files: .github
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Verify release notes
|
||||
uses: ./.github/actions/verify-release-notes
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pull-request-number: ${{ github.event.pull_request.number }}
|
||||
@@ -349,7 +349,7 @@ same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.5.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
|
||||
@@ -650,10 +650,12 @@ add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/ktxreader)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/mathio)
|
||||
add_subdirectory(${LIBRARIES}/uberz)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
add_subdirectory(${LIBRARIES}/viewer)
|
||||
add_subdirectory(${FILAMENT}/filament)
|
||||
add_subdirectory(${FILAMENT}/shaders)
|
||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
@@ -686,10 +688,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
add_subdirectory(${EXTERNAL}/moltenvk/tnt)
|
||||
endif()
|
||||
|
||||
set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
|
||||
|
||||
if (WEBGL)
|
||||
@@ -706,9 +704,6 @@ if (IS_HOST_PLATFORM)
|
||||
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/basisu/tnt)
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/libassimp/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libpng/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
|
||||
@@ -727,9 +722,10 @@ if (IS_HOST_PLATFORM)
|
||||
add_subdirectory(${TOOLS}/rgb-to-lmsr)
|
||||
add_subdirectory(${TOOLS}/roughness-prefilter)
|
||||
add_subdirectory(${TOOLS}/specular-color)
|
||||
add_subdirectory(${TOOLS}/uberz)
|
||||
endif()
|
||||
|
||||
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
export(TARGETS matc cmgen filamesh mipgen resgen glslminifier FILE ${IMPORT_EXECUTABLES})
|
||||
export(TARGETS matc cmgen filamesh mipgen resgen uberz glslminifier FILE ${IMPORT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.21.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.24.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.21.2'
|
||||
pod 'Filament', '~> 1.24.0'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -177,6 +177,7 @@ steps:
|
||||
- [x] KHR_materials_variants
|
||||
- [x] KHR_materials_volume
|
||||
- [x] KHR_mesh_quantization
|
||||
- [x] KHR_texture_basisu
|
||||
- [x] KHR_texture_transform
|
||||
|
||||
|
||||
|
||||
@@ -50,13 +50,13 @@ Do not push to origin yet.
|
||||
git cherry-pick rc/$RELEASE
|
||||
```
|
||||
|
||||
Update the headers. The "Next release" header becomes a header for $NEXT_RELEASE, and a new "Next
|
||||
release" header is added.
|
||||
Update the headers. The "main branch" header becomes a header for $NEXT_RELEASE, and a new "main
|
||||
branch" header is added.
|
||||
|
||||
For example, this:
|
||||
|
||||
```
|
||||
## Next release (main branch)
|
||||
## main branch
|
||||
- foo
|
||||
- bar
|
||||
|
||||
@@ -68,7 +68,7 @@ For example, this:
|
||||
becomes:
|
||||
|
||||
```
|
||||
## Next release (main branch)
|
||||
## main branch
|
||||
|
||||
## v1.9.4
|
||||
- foo
|
||||
|
||||
@@ -3,7 +3,93 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## v1.21.3 (currently main branch)
|
||||
## main branch
|
||||
|
||||
## v1.24.0
|
||||
|
||||
- ImGuiHelper: add support for Y flip.
|
||||
- Metal: ignore `MTLTexture` formatting when importing external textures.
|
||||
- materials: add a new `instanced` material parameter that is now mandatory in order to call `getInstanceIndex()`
|
||||
- gltfio: UbershaderProvider now takes the ubershader archive in its constructor [⚠️ **API Change**]
|
||||
- gltfio: Fix morphing with sparse accessors.
|
||||
- gltfio: Fix models that use signed integers for morphing.
|
||||
- engine: Documentation improvements regarding SkinningBuffer and fix an off-by-one assert when setting a SkinningBuffer.
|
||||
- picking is now exposed to JavaScript
|
||||
- gltf_viewer: Exercise picking functionality.
|
||||
- OpenGL: add WebGL support for ReadPixels
|
||||
- Vulkan: add assert and error message for OOM (debug builds)
|
||||
- Vulkan: fix crash with picking and 2-component ReadPixels.
|
||||
- backend: workaround broken GLES timer query on some Mali-Gxx old drivers
|
||||
- backend: revert c049a1 & reenable b2cdf9 ("don't issue a flush systematically after framegraph's execute")
|
||||
- gltfio: namespace now lives under Filament [⚠️ **API Change**]
|
||||
- gltfio: UbershaderLoader renamed to UbershaderProvider [⚠️ **API Change**]
|
||||
- gltfio: MaterialGenerator renamed to JitShaderProvider [⚠️ **API Change**]
|
||||
|
||||
## v1.23.2
|
||||
|
||||
- gltfio: Fix morphing for un-packed accessors.
|
||||
- gltfio: Ubershaders are now packaged into flexible archives.
|
||||
- gltfio: Remove poorly maintained lite flavor.
|
||||
- engine: Disable user scissor while rendering the Shadow Maps.
|
||||
- engine: Merge identical backend `RenderPrimitives` together.
|
||||
- engine: Improve `ResourceAllocator` performance a bit by reserving 128 cache entries.
|
||||
- utils: Remove `std::hash<T>` definitions for `libutils` types. Use `T::Hasher` explicitly instead. [⚠️ **API Change**]
|
||||
- backend: Fix WGL context attributes.
|
||||
- Metal: Fix potential invalid shaders when using gltfio in Ubershader mode. [⚠️ **Recompile Materials to get the fix**]
|
||||
|
||||
## v1.23.1
|
||||
|
||||
- gltfio: support skinning with bones that do not belong to any scene.
|
||||
- gltfio: add `attachSkin` / `detachSkin` method to FilamentAsset.
|
||||
- gltfio: ubershader mode: set sheen to `OPAQUE`.
|
||||
- Metal: fix issues seen with dynamic resolution on M1 Macs.
|
||||
- engine: add a "global" mode for render primitive's `blendOrder`.
|
||||
- engine: remove `RenderManager::setGeometryAt(index, count)`. [⚠️ **API Change**]
|
||||
- engine: fix overallocation by about 17MB.
|
||||
- WebGL: Add JS bindings for Texture class methods.
|
||||
|
||||
## v1.23.0
|
||||
|
||||
- engine: Changed UBOs layout [⚠️ **Material breakage**].
|
||||
- engine: Normals on morphed models have been fixed (core Filament change).
|
||||
- Java: View has several minor changes due to generated code, such as field ordering.
|
||||
- gltfio: Fix crash when reloading glTF assets.
|
||||
- gltfio: introduce cross-fade animation API [**NEW API**].
|
||||
|
||||
## v1.22.2
|
||||
|
||||
- Java: Minor API change: rename `ssctStartTraceDistance` to `ssctShadowDistance`. [⚠️ **API Change**]
|
||||
- Java: Minor API change: rename `blendingMode` to `blendMode`. [⚠️ **API Change**]
|
||||
- engine: Fix some memory leaks.
|
||||
|
||||
## v1.22.1
|
||||
|
||||
- Metal: Shaders now use `half` floating-point arithmetic when possible for improved performance. [⚠️ **Recompile Materials**]
|
||||
- engine: add support for presentation time in `Renderer`
|
||||
- engine: added guard bands support for screen-space effects
|
||||
- gltfio: Add multi-scene support.
|
||||
- gltfio: Various glTF-related cleanup and enhancements.
|
||||
- gltfio: Add support for KHR_texture_basisu.
|
||||
|
||||
## v1.22.0
|
||||
|
||||
- engine: Changed UBOs layout [⚠️ **Material breakage**].
|
||||
- engine: Improve effects relying on mipmapping
|
||||
- engine: Fix assert seen with VSM shadows.
|
||||
- WebGL: Fix `isTextureFormatSupported` for ETC2 formats.
|
||||
|
||||
## v1.21.3
|
||||
|
||||
- Java: Renamed the `KTXLoader` Kotlin class to `KTX1Loader`. [⚠️ **API Change**].
|
||||
- libs: Added `Ktx2Reader` and `BasisEncoder` to support Basis-encoded KTX2 files.
|
||||
- engine: Remove deprecated `Stream` APIs, see `Texture::import()` for an alternative [⚠️ **API Change**].
|
||||
- tools: Removed KTX1 compression support from mipgen. [⚠️ **API Change**].
|
||||
- tools: Added support for KTX2 to mipgen.
|
||||
- gltfio: Added `resetBoneMatrices()` method.
|
||||
- gltfio: Introduced `TextureProvider` interface. [⚠️ **API Change**].
|
||||
- gltfio: Fix progress indicator when error occurs.
|
||||
- samples: Desktop and Web Suzanne samples now use KTX2 instead of KTX1.
|
||||
- samples: Fix regression with sample-gltf-viewer and zip files.
|
||||
|
||||
## v1.21.2
|
||||
|
||||
@@ -453,7 +539,7 @@ devices.
|
||||
- engine: Fix RenderTarget NPE when depth is not present.
|
||||
- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera.
|
||||
- engine: VSM shadows now support `shadowMultiplier`.
|
||||
- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
- java: Expose several MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
should have been public.
|
||||
- java: fix bug with Texture::setImage buffer size calculation.
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
// com.google.android.filament.exclude-vulkan
|
||||
// When set, support for Vulkan will be excluded.
|
||||
//
|
||||
// com.google.android.filament.matdbg
|
||||
// When set, enables matdbg, disables shader optimizations
|
||||
//
|
||||
// com.google.android.filament.skip-samples
|
||||
// Exclude samples from the project. Useful to speed up compilation.
|
||||
//
|
||||
@@ -59,6 +62,11 @@ buildscript {
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def matdbg = providers
|
||||
.gradleProperty("com.google.android.filament.matdbg")
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
|
||||
def newAbis = providers
|
||||
.gradleProperty("com.google.android.filament.abis")
|
||||
@@ -73,10 +81,10 @@ buildscript {
|
||||
'minSdk': 19,
|
||||
'targetSdk': 31,
|
||||
'compileSdk': 31,
|
||||
'kotlin': '1.6.10',
|
||||
'kotlin_coroutines': '1.6.0',
|
||||
'kotlin': '1.6.21',
|
||||
'kotlin_coroutines': '1.6.1',
|
||||
'buildTools': '32.0.0',
|
||||
'ndk': '23.1.7779620'
|
||||
'ndk': '24.0.8215888'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
@@ -93,22 +101,23 @@ buildscript {
|
||||
|
||||
dependencies {
|
||||
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath 'com.android.tools.build:gradle:7.2.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
ext.cmakeArgs = [
|
||||
"--no-warn-unused-cli",
|
||||
"-DANDROID_PIE=ON",
|
||||
"-DANDROID_PLATFORM=21",
|
||||
"-DANDROID_STL=c++_static",
|
||||
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString()
|
||||
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
|
||||
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
|
||||
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
|
||||
]
|
||||
|
||||
ext.cppFlags = [
|
||||
"-std=c++17",
|
||||
"-Wno-unused-command-line-argument",
|
||||
"-Wl,--hash-style=both", // Required to support API levels below 23
|
||||
"-fno-stack-protector",
|
||||
"-fno-exceptions",
|
||||
"-fno-unwind-tables",
|
||||
@@ -121,8 +130,13 @@ buildscript {
|
||||
"-fomit-frame-pointer",
|
||||
"-ffunction-sections",
|
||||
"-fdata-sections",
|
||||
"-no-canonical-prefixes",
|
||||
"-Wformat",
|
||||
"-Werror=format-security",
|
||||
"-Wno-unused-command-line-argument",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-Bsymbolic-functions",
|
||||
"-Wl,--hash-style=both", // Required to support API levels below 23
|
||||
]
|
||||
|
||||
ext.abis = abis
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
plugins {
|
||||
id 'groovy-gradle-plugin'
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament.filamat'
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation deps.androidx.annotations
|
||||
}
|
||||
|
||||
@@ -120,6 +120,14 @@ Java_com_google_android_filament_RenderableManager_nBuilderBlendOrder(JNIEnv*, j
|
||||
builder->blendOrder((size_t) index, (uint16_t) blendOrder);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderGlobalBlendOrderEnabled(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint index, jboolean enabled) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->globalBlendOrderEnabled((size_t) index, (bool) enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderBoundingBox(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jfloat cx, jfloat cy, jfloat cz, jfloat ex, jfloat ey, jfloat ez) {
|
||||
@@ -422,15 +430,6 @@ Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIJJII(JNIE
|
||||
(size_t) offset, (size_t) count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetGeometryAt__JIIIII(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex, jint primitiveType, jint offset,
|
||||
jint count) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setGeometryAt((RenderableManager::Instance) i, (size_t) primitiveIndex,
|
||||
(RenderableManager::PrimitiveType) primitiveType, (size_t) offset, (size_t) count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetBlendOrderAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex, jint blendOrder) {
|
||||
@@ -439,6 +438,14 @@ Java_com_google_android_filament_RenderableManager_nSetBlendOrderAt(JNIEnv*, jcl
|
||||
(uint16_t) blendOrder);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetGlobalBlendOrderEnabledAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex, jboolean enabled) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setGlobalBlendOrderEnabledAt((RenderableManager::Instance) i, (size_t) primitiveIndex,
|
||||
(bool) enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint primitiveIndex) {
|
||||
|
||||
@@ -156,12 +156,9 @@ Java_com_google_android_filament_Renderer_nResetUserTime(JNIEnv*, jclass, jlong
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Renderer_nSetDisplayInfo(JNIEnv*, jclass, jlong nativeRenderer,
|
||||
jfloat refreshRate, jlong presentationDeadlineNanos, jlong vsyncOffsetNanos) {
|
||||
Java_com_google_android_filament_Renderer_nSetDisplayInfo(JNIEnv*, jclass, jlong nativeRenderer, jfloat refreshRate) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
renderer->setDisplayInfo({ .refreshRate = refreshRate,
|
||||
.presentationDeadlineNanos = (uint64_t)presentationDeadlineNanos,
|
||||
.vsyncOffsetNanos = (uint64_t)vsyncOffsetNanos });
|
||||
renderer->setDisplayInfo({ .refreshRate = refreshRate });
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -183,3 +180,10 @@ Java_com_google_android_filament_Renderer_nSetClearOptions(JNIEnv *, jclass ,
|
||||
.clear = (bool) clear,
|
||||
.discard = (bool) discard});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Renderer_nSetPresentationTime(JNIEnv *, jclass ,
|
||||
jlong nativeRenderer, jlong monotonicClockNanos) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
renderer->setPresentationTime(monotonicClockNanos);
|
||||
}
|
||||
|
||||
@@ -98,16 +98,6 @@ Java_com_google_android_filament_Stream_nBuilderStreamSource(JNIEnv* env,
|
||||
builder->setStreamSource(env, streamSource);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jlong externalTextureId) {
|
||||
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
builder->builder()->stream(externalTextureId);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderWidth(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jint width) {
|
||||
@@ -143,41 +133,6 @@ Java_com_google_android_filament_Stream_nSetDimensions(JNIEnv*, jclass, jlong na
|
||||
stream->setDimensions((uint32_t) width, (uint32_t) height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
|
||||
jlong nativeStream, jlong nativeEngine,
|
||||
jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint top, jint type, jint alignment, jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
stride = stride ? stride : width;
|
||||
size_t sizeInBytes = PixelBufferDescriptor::computeDataSize(
|
||||
(PixelDataFormat) format, (PixelDataType) type,
|
||||
(size_t) stride, (size_t) (height + top), (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *buffer = nioBuffer.getData();
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
stream->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
|
||||
@@ -259,14 +259,14 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetSSCTOptions(JNIEnv *, jclass, jlong nativeView,
|
||||
jfloat ssctLightConeRad, jfloat ssctStartTraceDistance, jfloat ssctContactDistanceMax,
|
||||
jfloat ssctLightConeRad, jfloat ssctShadowDistance, jfloat ssctContactDistanceMax,
|
||||
jfloat ssctIntensity, jfloat ssctLightDirX, jfloat ssctLightDirY, jfloat ssctLightDirZ,
|
||||
jfloat ssctDepthBias, jfloat ssctDepthSlopeBias, jint ssctSampleCount,
|
||||
jint ssctRayCount, jboolean ssctEnabled) {
|
||||
View* view = (View*) nativeView;
|
||||
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
|
||||
options.ssct.lightConeRad = ssctLightConeRad;
|
||||
options.ssct.shadowDistance = ssctStartTraceDistance;
|
||||
options.ssct.shadowDistance = ssctShadowDistance;
|
||||
options.ssct.contactDistanceMax = ssctContactDistanceMax;
|
||||
options.ssct.intensity = ssctIntensity;
|
||||
options.ssct.lightDirection = math::float3{ ssctLightDirX, ssctLightDirY, ssctLightDirZ };
|
||||
@@ -461,3 +461,11 @@ Java_com_google_android_filament_View_nPick(JNIEnv* env, jclass,
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
}, callback->getHandler());
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
|
||||
jlong nativeView, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setGuardBandOptions({ .enabled = (bool)enabled });
|
||||
}
|
||||
|
||||
@@ -104,12 +104,12 @@ public class MorphTargetBuffer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positions of morph target at the index.
|
||||
* Updates float4 positions for the given morph target.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param positions Pointer to at least count positions
|
||||
* @param count Number of position elements in positions
|
||||
* @param positions An array with at least count*4 floats
|
||||
* @param count Number of float4 vectors in positions to be consumed
|
||||
*/
|
||||
public void setPositionsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@@ -122,12 +122,15 @@ public class MorphTargetBuffer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates tangents of morph target at the index.
|
||||
* Updates tangents for the given morph target.
|
||||
*
|
||||
* These quaternions must be represented as signed shorts, where real numbers in the [-1,+1]
|
||||
* range multiplied by 32767.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param tangents Pointer to at least count tangents
|
||||
* @param count Number of tangent elements in tangents
|
||||
* @param tangents An array with at least "count*4" shorts
|
||||
* @param count number of short4 quaternions in tangents
|
||||
*/
|
||||
public void setTangentsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@@ -140,14 +143,14 @@ public class MorphTargetBuffer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of vertex count in this {@link MorphTargetBuffer}
|
||||
* @return number of vertices in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getVertexCount() {
|
||||
return nGetVertexCount(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of target count in this {@link MorphTargetBuffer}
|
||||
* @return number of morph targets in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getCount() {
|
||||
return nGetCount(mNativeObject);
|
||||
|
||||
@@ -191,7 +191,9 @@ public class RenderableManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an ordering index for blended primitives that all live at the same Z value.
|
||||
* Sets the drawing order for blended primitives. The drawing order is either global or
|
||||
* local (default) to this Renderable. In either case, the Renderable priority takes
|
||||
* precedence.
|
||||
*
|
||||
* @param index the primitive of interest
|
||||
* @param blendOrder draw order number (0 by default). Only the lowest 15 bits are used.
|
||||
@@ -203,6 +205,18 @@ public class RenderableManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the blend order is global or local to this Renderable (by default).
|
||||
*
|
||||
* @param index the primitive of interest
|
||||
* @param enabled true for global, false for local blend ordering.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder globalBlendOrderEnabled(@IntRange(from = 0) int index, boolean enabled) {
|
||||
nBuilderGlobalBlendOrderEnabled(mNativeBuilder, index, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The axis-aligned bounding box of the renderable.
|
||||
*
|
||||
@@ -792,18 +806,9 @@ public class RenderableManager {
|
||||
0, indices.getIndexCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the geometry for the given primitive.
|
||||
*
|
||||
* @see Builder#geometry Builder.geometry
|
||||
*/
|
||||
public void setGeometryAt(@EntityInstance int i, @IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull PrimitiveType type, @IntRange(from = 0) int offset, @IntRange(from = 0) int count) {
|
||||
nSetGeometryAt(mNativeObject, i, primitiveIndex, type.getValue(), offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the ordering index for blended primitives that all live at the same Z value.
|
||||
/**
|
||||
* Changes the drawing order for blended primitives. The drawing order is either global or
|
||||
* local (default) to this Renderable. In either case, the Renderable priority takes precedence.
|
||||
*
|
||||
* @see Builder#blendOrder
|
||||
*
|
||||
@@ -816,6 +821,20 @@ public class RenderableManager {
|
||||
nSetBlendOrderAt(mNativeObject, instance, primitiveIndex, blendOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether the blend order is global or local to this Renderable (by default).
|
||||
*
|
||||
* @see Builder#globalBlendOrderEnabled
|
||||
*
|
||||
* @param instance the renderable of interest
|
||||
* @param primitiveIndex the primitive of interest
|
||||
* @param enabled true for global, false for local blend ordering.
|
||||
*/
|
||||
public void setGlobalBlendOrderEnabledAt(@EntityInstance int instance, @IntRange(from = 0) int primitiveIndex,
|
||||
boolean enabled) {
|
||||
nSetGlobalBlendOrderEnabledAt(mNativeObject, instance, primitiveIndex, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
|
||||
*/
|
||||
@@ -853,6 +872,7 @@ public class RenderableManager {
|
||||
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int minIndex, int maxIndex, int count);
|
||||
private static native void nBuilderMaterial(long nativeBuilder, int index, long nativeMaterialInstance);
|
||||
private static native void nBuilderBlendOrder(long nativeBuilder, int index, int blendOrder);
|
||||
private static native void nBuilderGlobalBlendOrderEnabled(long nativeBuilder, int index, boolean enabled);
|
||||
private static native void nBuilderBoundingBox(long nativeBuilder, float cx, float cy, float cz, float ex, float ey, float ez);
|
||||
private static native void nBuilderLayerMask(long nativeBuilder, int select, int value);
|
||||
private static native void nBuilderPriority(long nativeBuilder, int priority);
|
||||
@@ -891,7 +911,7 @@ public class RenderableManager {
|
||||
private static native void nSetMaterialInstanceAt(long nativeRenderableManager, int i, int primitiveIndex, long nativeMaterialInstance);
|
||||
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, int offset, int count);
|
||||
private static native void nSetBlendOrderAt(long nativeRenderableManager, int i, int primitiveIndex, int blendOrder);
|
||||
private static native void nSetGlobalBlendOrderEnabledAt(long nativeRenderableManager, int i, int primitiveIndex, boolean enabled);
|
||||
private static native int nGetEnabledAttributesAt(long nativeRenderableManager, int i, int primitiveIndex);
|
||||
}
|
||||
|
||||
@@ -61,13 +61,17 @@ public class Renderer {
|
||||
/**
|
||||
* How far in advance a buffer must be queued for presentation at a given time in ns
|
||||
* On Android you can use {@link android.view.Display#getPresentationDeadlineNanos()}.
|
||||
* @deprecated this value is ignored
|
||||
*/
|
||||
@Deprecated
|
||||
public long presentationDeadlineNanos = 0;
|
||||
|
||||
/**
|
||||
* Offset by which vsyncSteadyClockTimeNano provided in beginFrame() is offset in ns
|
||||
* On Android you can use {@link android.view.Display#getAppVsyncOffsetNanos()}.
|
||||
* @deprecated this value is ignored
|
||||
*/
|
||||
@Deprecated
|
||||
public long vsyncOffsetNanos = 0;
|
||||
};
|
||||
|
||||
@@ -175,8 +179,7 @@ public class Renderer {
|
||||
*/
|
||||
public void setDisplayInfo(@NonNull DisplayInfo info) {
|
||||
mDisplayInfo = info;
|
||||
nSetDisplayInfo(getNativeObject(),
|
||||
info.refreshRate, info.presentationDeadlineNanos, info.vsyncOffsetNanos);
|
||||
nSetDisplayInfo(getNativeObject(), info.refreshRate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,6 +250,23 @@ public class Renderer {
|
||||
return mEngine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time at which the frame must be presented to the display.
|
||||
* <p>
|
||||
* This must be called between {@link #beginFrame} and {@link #endFrame}.
|
||||
* </p>
|
||||
*
|
||||
* @param monotonicClockNanos The time in nanoseconds corresponding to the system monotonic
|
||||
* up-time clock. The presentation time is typically set in the
|
||||
* middle of the period of interest and cannot be too far in the
|
||||
* future as it is limited by how many buffers are available in
|
||||
* the display sub-system. Typically it is set to 1 or 2 vsync
|
||||
* periods away.
|
||||
*/
|
||||
public void setPresentationTime(long monotonicClockNanos) {
|
||||
nSetPresentationTime(getNativeObject(), monotonicClockNanos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a frame for this <code>Renderer</code>.
|
||||
* <p><code>beginFrame</code> manages frame pacing, and returns whether or not a frame should be
|
||||
@@ -531,6 +551,10 @@ public class Renderer {
|
||||
* Typically, this will happen after multiple calls to {@link #beginFrame},
|
||||
* {@link #render}, {@link #endFrame}.</p>
|
||||
* <br>
|
||||
* <p>OpenGL only: if issuing a <code>readPixels</code> on a {@link RenderTarget} backed by a
|
||||
* {@link Texture} that had data uploaded to it via {@link Texture#setImage}, the data returned
|
||||
* from <code>readPixels</code> will be y-flipped with respect to the {@link Texture#setImage}
|
||||
* call.</p>
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
@@ -660,6 +684,7 @@ public class Renderer {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static native void nSetPresentationTime(long nativeObject, long monotonicClockNanos);
|
||||
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
|
||||
private static native void nEndFrame(long nativeRenderer);
|
||||
private static native void nRender(long nativeRenderer, long nativeView);
|
||||
@@ -681,8 +706,7 @@ public class Renderer {
|
||||
Object handler, Runnable callback);
|
||||
private static native double nGetUserTime(long nativeRenderer);
|
||||
private static native void nResetUserTime(long nativeRenderer);
|
||||
private static native void nSetDisplayInfo(long nativeRenderer,
|
||||
float refreshRate, long presentationDeadlineNanos, long vsyncOffsetNanos);
|
||||
private static native void nSetDisplayInfo(long nativeRenderer, float refreshRate);
|
||||
private static native void nSetFrameRateOptions(long nativeRenderer,
|
||||
float interval, float headRoomRatio, float scaleRate, int history);
|
||||
private static native void nSetClearOptions(long nativeRenderer,
|
||||
|
||||
@@ -103,9 +103,6 @@ public class Stream {
|
||||
/** Not synchronized but copy-free. Good for video. */
|
||||
NATIVE,
|
||||
|
||||
/** Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26. */
|
||||
TEXTURE_ID,
|
||||
|
||||
/** Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+. */
|
||||
ACQUIRED,
|
||||
};
|
||||
@@ -121,7 +118,7 @@ public class Stream {
|
||||
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
|
||||
* {@link #setAcquiredImage}.
|
||||
*
|
||||
* To create a {@link StreamType#NATIVE NATIVE} or {@link StreamType#TEXTURE_ID TEXTURE_ID} stream, call one of the <pre>stream</pre> methods
|
||||
* To create a {@link StreamType#NATIVE NATIVE} stream, call one of the <pre>stream</pre> methods
|
||||
* on the builder.
|
||||
*/
|
||||
public static class Builder {
|
||||
@@ -156,27 +153,6 @@ public class Stream {
|
||||
throw new IllegalArgumentException("Invalid stream source: " + streamSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link StreamType#TEXTURE_ID TEXTURE_ID} stream. A copy stream will sample data from the supplied
|
||||
* external texture and copy it into an internal private texture.
|
||||
*
|
||||
* <p>Currently only OpenGL external texture ids are supported.</p>
|
||||
*
|
||||
* @param externalTextureId An opaque texture id (typically a GLuint created with
|
||||
* <code>glGenTextures()</code>) in a context shared with
|
||||
* filament -- in that case this texture's target must be
|
||||
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public Builder stream(long externalTextureId) {
|
||||
nBuilderStream(mNativeBuilder, externalTextureId);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param width initial width of the incoming stream. Whether this value is used is
|
||||
* stream dependent. On Android, it must be set when using
|
||||
@@ -276,92 +252,6 @@ public class Stream {
|
||||
nSetDimensions(getNativeObject(), width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads back the content of the last frame of a <code>Stream</code> since the last call to
|
||||
* {@link Renderer#beginFrame}.
|
||||
*
|
||||
* <p>The Stream must be a copy stream, which can be checked with {@link #getStreamType()}.
|
||||
* This function is a no-op otherwise.</p>
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* Stream buffer User buffer (PixelBufferDescriptor)
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
* | +---------+ | | +---------+ | |
|
||||
* | | ^ | | ======> | | | | |
|
||||
* | x | h| | | |.left| | | |
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* <p>Typically readPixels() will be called after {@link Renderer#beginFrame}.</p>
|
||||
*
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
* Typically, this will happen after multiple calls to {@link Renderer#beginFrame},
|
||||
* {@link Renderer#render}, {@link Renderer#endFrame}.</p>
|
||||
*
|
||||
* <p><code>readPixels</code> is intended for debugging and testing.
|
||||
* It will impact performance significantly.</p>
|
||||
*
|
||||
* @param xoffset left offset of the sub-region to read back
|
||||
* @param yoffset bottom offset of the sub-region to read back
|
||||
* @param width width of the sub-region to read back
|
||||
* @param height height of the sub-region to read back
|
||||
* @param buffer client-side buffer where the read-back will be written
|
||||
*
|
||||
* <p>
|
||||
* The following format are always supported:
|
||||
* <li>{@link Texture.Format#RGBA}</li>
|
||||
* <li>{@link Texture.Format#RGBA_INTEGER}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The following types are always supported:
|
||||
* <li>{@link Texture.Type#UBYTE}</li>
|
||||
* <li>{@link Texture.Type#UINT}</li>
|
||||
* <li>{@link Texture.Type#INT}</li>
|
||||
* <li>{@link Texture.Type#FLOAT}</li>
|
||||
* </p>
|
||||
*
|
||||
* <p>Other combination of format/type may be supported. If a combination is
|
||||
* not supported, this operation may fail silently. Use a DEBUG build
|
||||
* to get some logs about the failure.</p>
|
||||
*
|
||||
* @exception BufferOverflowException if the specified parameters would result in reading
|
||||
* outside of <code>buffer</code>.
|
||||
*/
|
||||
public void readPixels(
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@NonNull Texture.PixelBufferDescriptor buffer) {
|
||||
|
||||
if (buffer.storage.isReadOnly()) {
|
||||
throw new ReadOnlyBufferException();
|
||||
}
|
||||
|
||||
int result = nReadPixels(getNativeObject(), mNativeEngine,
|
||||
xoffset, yoffset, width, height,
|
||||
buffer.storage, buffer.storage.remaining(),
|
||||
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
|
||||
buffer.stride, buffer.format.ordinal(),
|
||||
buffer.handler, buffer.callback);
|
||||
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the presentation time of the currently displayed frame in nanosecond.
|
||||
*
|
||||
@@ -387,7 +277,6 @@ public class Stream {
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeStreamBuilder);
|
||||
private static native void nBuilderStreamSource(long nativeStreamBuilder, Object streamSource);
|
||||
private static native void nBuilderStream(long nativeStreamBuilder, long externalTextureId);
|
||||
private static native void nBuilderWidth(long nativeStreamBuilder, int width);
|
||||
private static native void nBuilderHeight(long nativeStreamBuilder, int height);
|
||||
private static native long nBuilderBuild(long nativeStreamBuilder, long nativeEngine);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -157,8 +157,6 @@ public class DisplayHelper {
|
||||
info = new Renderer.DisplayInfo();
|
||||
}
|
||||
info.refreshRate = DisplayHelper.getRefreshRate(display);
|
||||
info.presentationDeadlineNanos = DisplayHelper.getPresentationDeadlineNanos(display);
|
||||
info.vsyncOffsetNanos = DisplayHelper.getAppVsyncOffsetNanos(display);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.utils'
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
kotlin.srcDirs += "src/main/java"
|
||||
@@ -10,14 +12,14 @@ android {
|
||||
defaultConfig {
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
// "More than one file was found with OS independent path ..."
|
||||
packagingOptions {
|
||||
exclude 'lib/*/libfilament-jni.so'
|
||||
exclude 'lib/*/libgltfio-jni.so'
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
// "More than one file was found with OS independent path ..."
|
||||
jniLibs {
|
||||
excludes += ['lib/*/libfilament-jni.so', 'lib/*/libgltfio-jni.so']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
|
||||
int rc;
|
||||
|
||||
// KTXLoader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
|
||||
// KTX1Loader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTX1Loader");
|
||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod ktxMethods[] = {
|
||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
||||
|
||||
@@ -40,7 +40,7 @@ import com.google.android.filament.Renderer;
|
||||
*
|
||||
* When executing a test, clients should call tick() after each frame is rendered, which provides an
|
||||
* opportunity to push settings to Filament, increment the current test index (if enough time has
|
||||
* elapsed), and request an asychronous screenshot.
|
||||
* elapsed), and request an asynchronous screenshot.
|
||||
*
|
||||
* The time to sleep between tests is configurable and can be set to zero. Automation also waits a
|
||||
* specified minimum number of frames between tests.
|
||||
|
||||
@@ -24,12 +24,12 @@ import com.google.android.filament.Texture
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utilities for consuming KTX files and producing Filament textures, IBLs, and sky boxes.
|
||||
* Utilities for consuming KTX1 files and producing Filament textures, IBLs, and sky boxes.
|
||||
*
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KTXLoader {
|
||||
object KTX1Loader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
@@ -114,7 +114,7 @@ class ModelViewer(
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
|
||||
materialProvider = UbershaderLoader(engine)
|
||||
materialProvider = UbershaderProvider(engine)
|
||||
assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes, ignoreBindTransform)
|
||||
|
||||
|
||||
@@ -11,49 +11,72 @@ add_library(dracodec STATIC IMPORTED)
|
||||
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
|
||||
|
||||
add_library(ktxreader STATIC IMPORTED)
|
||||
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
|
||||
|
||||
add_library(stb STATIC IMPORTED)
|
||||
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
|
||||
|
||||
add_library(basis_transcoder STATIC IMPORTED)
|
||||
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
|
||||
|
||||
add_library(zstd STATIC IMPORTED)
|
||||
set_target_properties(zstd PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libzstd.a)
|
||||
|
||||
add_library(utils STATIC IMPORTED)
|
||||
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
|
||||
|
||||
add_library(gltfio_resources STATIC IMPORTED)
|
||||
set_target_properties(gltfio_resources PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources.a)
|
||||
add_library(uberzlib STATIC IMPORTED)
|
||||
set_target_properties(uberzlib PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libuberzlib.a)
|
||||
|
||||
add_library(gltfio_resources_lite STATIC IMPORTED)
|
||||
set_target_properties(gltfio_resources_lite PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgltfio_resources_lite.a)
|
||||
add_library(uberarchive STATIC IMPORTED)
|
||||
set_target_properties(uberarchive PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libuberarchive.a)
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
|
||||
|
||||
set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/include/gltfio/Animator.h
|
||||
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
|
||||
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/NodeManager.h
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/math.h
|
||||
|
||||
${GLTFIO_DIR}/src/ArchiveCache.cpp
|
||||
${GLTFIO_DIR}/src/ArchiveCache.h
|
||||
${GLTFIO_DIR}/src/Animator.cpp
|
||||
${GLTFIO_DIR}/src/AssetLoader.cpp
|
||||
${GLTFIO_DIR}/src/DracoCache.cpp
|
||||
${GLTFIO_DIR}/src/DracoCache.h
|
||||
${GLTFIO_DIR}/src/DependencyGraph.cpp
|
||||
${GLTFIO_DIR}/src/DependencyGraph.h
|
||||
${GLTFIO_DIR}/src/DracoCache.cpp
|
||||
${GLTFIO_DIR}/src/DracoCache.h
|
||||
${GLTFIO_DIR}/src/FFilamentAsset.h
|
||||
${GLTFIO_DIR}/src/FilamentAsset.cpp
|
||||
${GLTFIO_DIR}/src/FFilamentInstance.h
|
||||
${GLTFIO_DIR}/src/FilamentAsset.cpp
|
||||
${GLTFIO_DIR}/src/FilamentInstance.cpp
|
||||
${GLTFIO_DIR}/src/FNodeManager.h
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/Ktx2Provider.cpp
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/NodeManager.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/StbProvider.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
${GLTFIO_DIR}/src/UbershaderLoader.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/UbershaderProvider.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.h
|
||||
${GLTFIO_DIR}/src/upcast.h
|
||||
${GLTFIO_DIR}/src/Image.cpp
|
||||
|
||||
src/main/cpp/Animator.cpp
|
||||
src/main/cpp/AssetLoader.cpp
|
||||
@@ -61,11 +84,10 @@ set(GLTFIO_SRCS
|
||||
src/main/cpp/FilamentInstance.cpp
|
||||
src/main/cpp/MaterialKey.cpp
|
||||
src/main/cpp/MaterialKey.h
|
||||
src/main/cpp/UbershaderLoader.cpp
|
||||
src/main/cpp/UbershaderProvider.cpp
|
||||
src/main/cpp/ResourceLoader.cpp
|
||||
|
||||
${FILAMENT_DIR}/include/gltfio/resources/gltfresources_lite.h
|
||||
${FILAMENT_DIR}/include/gltfio/resources/gltfresources.h
|
||||
${FILAMENT_DIR}/include/gltfio/materials/uberarchive.h
|
||||
|
||||
../common/NioUtils.cpp
|
||||
)
|
||||
@@ -73,30 +95,23 @@ set(GLTFIO_SRCS
|
||||
set(GLTFIO_INCLUDE_DIRS
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
${FILAMENT_DIR}/include/gltfio/resources
|
||||
../../filament/backend/include
|
||||
../../libs/gltfio/include
|
||||
../../third_party/basisu/zstd
|
||||
../../third_party/cgltf
|
||||
../../third_party/robin-map
|
||||
../../third_party/hat-trie
|
||||
../../third_party/stb
|
||||
../../libs/utils/include
|
||||
../../libs/ktxreader/include
|
||||
)
|
||||
|
||||
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
|
||||
target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
|
||||
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
|
||||
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map)
|
||||
|
||||
if(GLTFIO_LITE)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_LITE=1)
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources_lite)
|
||||
else()
|
||||
target_link_libraries(gltfio-jni filament-jni utils log gltfio_resources)
|
||||
|
||||
# Enable Draco in the non-lite variant of gltfio.
|
||||
target_link_libraries(gltfio-jni dracodec)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)
|
||||
endif()
|
||||
target_link_libraries(gltfio-jni filament-jni utils uberzlib log stb ktxreader basis_transcoder zstd uberarchive)
|
||||
target_link_libraries(gltfio-jni dracodec)
|
||||
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
|
||||
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament.gltfio'
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
dimension "functionality"
|
||||
}
|
||||
|
||||
lite {
|
||||
dimension "functionality"
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DGLTFIO_LITE=ON")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
// "More than one file was found with OS independent path ..."
|
||||
packagingOptions {
|
||||
exclude 'lib/*/libfilament-jni.so'
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
|
||||
// "More than one file was found with OS independent path ..."
|
||||
jniLibs {
|
||||
excludes += ['lib/*/libfilament-jni.so']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,11 +33,6 @@ afterEvaluate { project ->
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -36,6 +36,19 @@ Java_com_google_android_filament_gltfio_Animator_nUpdateBoneMatrices(JNIEnv*, jc
|
||||
animator->updateBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nApplyCrossFade(JNIEnv*, jclass, jlong nativeAnimator,
|
||||
jint previousAnimIndex, jfloat previousAnimTime, jfloat alpha) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
animator->applyCrossFade(previousAnimIndex, previousAnimTime, alpha);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nResetBoneMatrices(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
animator->resetBoneMatrices();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_Animator_nGetAnimationCount(JNIEnv*, jclass, jlong nativeAnimator) {
|
||||
Animator* animator = (Animator*) nativeAnimator;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
class JavaMaterialProvider : public MaterialProvider {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
@@ -120,10 +120,34 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetLightEntities(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jintArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
const jsize available = env->GetArrayLength(result);
|
||||
const size_t minCount = std::min(available, (jsize) asset->getLightEntityCount());
|
||||
if (minCount == 0) {
|
||||
return;
|
||||
}
|
||||
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
|
||||
std::copy_n(asset->getLightEntities(),
|
||||
std::min(available, (jsize) asset->getLightEntityCount()), entities);
|
||||
std::copy_n(asset->getLightEntities(), minCount, entities);
|
||||
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetRenderableEntityCount(JNIEnv*, jclass,
|
||||
jlong nativeAsset) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
return asset->getRenderableEntityCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetRenderableEntities(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jintArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
const jsize available = env->GetArrayLength(result);
|
||||
const size_t minCount = std::min(available, (jsize) asset->getRenderableEntityCount());
|
||||
if (minCount == 0) {
|
||||
return;
|
||||
}
|
||||
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
|
||||
std::copy_n(asset->getRenderableEntities(), minCount, entities);
|
||||
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
|
||||
}
|
||||
|
||||
@@ -131,10 +155,13 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetCameraEntities(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jintArray result) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
jsize available = env->GetArrayLength(result);
|
||||
const jsize available = env->GetArrayLength(result);
|
||||
const size_t minCount = std::min(available, (jsize) asset->getCameraEntityCount());
|
||||
if (minCount == 0) {
|
||||
return;
|
||||
}
|
||||
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
|
||||
std::copy_n(asset->getCameraEntities(),
|
||||
std::min(available, (jsize) asset->getCameraEntityCount()), entities);
|
||||
std::copy_n(asset->getCameraEntities(), minCount, entities);
|
||||
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
|
||||
}
|
||||
|
||||
@@ -313,3 +340,19 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv*
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
asset->releaseSourceData();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nAttachSkin(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jint targetEntity) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity target = Entity::import(targetEntity);
|
||||
asset->attachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nDetachSkin(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint skinIndex, jint targetEntity) {
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
Entity target = Entity::import(targetEntity);
|
||||
asset->detachSkin(skinIndex, target);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
|
||||
MaterialKeyHelper& MaterialKeyHelper::get() {
|
||||
static MaterialKeyHelper helper;
|
||||
|
||||
@@ -22,10 +22,12 @@
|
||||
|
||||
class MaterialKeyHelper {
|
||||
public:
|
||||
using MaterialKey = filament::gltfio::MaterialKey;
|
||||
|
||||
static MaterialKeyHelper& get();
|
||||
|
||||
void copy(JNIEnv* env, gltfio::MaterialKey& dst, jobject src);
|
||||
void copy(JNIEnv* env, jobject dst, const gltfio::MaterialKey& src);
|
||||
void copy(JNIEnv* env, MaterialKey& dst, jobject src);
|
||||
void copy(JNIEnv* env, jobject dst, const MaterialKey& src);
|
||||
|
||||
void init(JNIEnv* env); // called only from the Java static class constructor
|
||||
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <gltfio/ResourceLoader.h>
|
||||
#include <gltfio/TextureProvider.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
using namespace utils;
|
||||
|
||||
static void destroy(void*, size_t, void *userData) {
|
||||
@@ -114,3 +115,34 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*,
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
loader->asyncCancelLoad();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateStbProvider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createStbProvider(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createKtx2Provider(engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nAddTextureProvider(JNIEnv* env, jclass,
|
||||
jlong nativeLoader, jstring url, jlong nativeProvider) {
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
TextureProvider* provider = (TextureProvider*) nativeProvider;
|
||||
const char* cstring = env->GetStringUTFChars(url, nullptr);
|
||||
loader->addTextureProvider(cstring, provider);
|
||||
env->ReleaseStringUTFChars(url, cstring);
|
||||
}
|
||||
|
||||
@@ -17,37 +17,38 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <gltfio/MaterialProvider.h>
|
||||
#include <gltfio/materials/uberarchive.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include "MaterialKey.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace gltfio;
|
||||
using namespace filament::gltfio;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateUbershaderLoader(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nCreateUbershaderProvider(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) createUbershaderLoader(engine);
|
||||
return (jlong) createUbershaderProvider(engine, UBERARCHIVE_DEFAULT_DATA, UBERARCHIVE_DEFAULT_SIZE);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyUbershaderLoader(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nDestroyUbershaderProvider(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nDestroyMaterials(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nDestroyMaterials(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
provider->destroyMaterials();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nCreateMaterialInstance(JNIEnv* env, jclass,
|
||||
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) {
|
||||
MaterialKey nativeKey = {};
|
||||
|
||||
@@ -80,14 +81,14 @@ Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterialCount(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nGetMaterialCount(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
return provider->getMaterialsCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_UbershaderLoader_nGetMaterials(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_gltfio_UbershaderProvider_nGetMaterials(JNIEnv* env, jclass,
|
||||
jlong nativeProvider, jlongArray result) {
|
||||
auto provider = (MaterialProvider *) nativeProvider;
|
||||
auto materials = provider->getMaterials();
|
||||
@@ -66,6 +66,36 @@ public class Animator {
|
||||
nUpdateBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a blended transform to the union of nodes affected by two animations.
|
||||
* Used for cross-fading from a previous skinning-based animation or rigid body animation.
|
||||
*
|
||||
* First, this stashes the current transform hierarchy into a transient memory buffer.
|
||||
*
|
||||
* Next, this applies previousAnimIndex / previousAnimTime to the actual asset by internally
|
||||
* calling applyAnimation().
|
||||
*
|
||||
* Finally, the stashed local transforms are lerped (via the scale / translation / rotation
|
||||
* components) with their live counterparts, and the results are pushed to the asset.
|
||||
*
|
||||
* To achieve a cross fade effect with skinned models, clients will typically call animator
|
||||
* methods in this order: (1) applyAnimation (2) applyCrossFade (3) updateBoneMatrices. The
|
||||
* animation that clients pass to applyAnimation is the "current" animation corresponding to
|
||||
* alpha=1, while the "previous" animation passed to applyCrossFade corresponds to alpha=0.
|
||||
*/
|
||||
public void applyCrossFade(int previousAnimIndex, float previousAnimTime, float alpha) {
|
||||
nApplyCrossFade(getNativeObject(), previousAnimIndex, previousAnimTime, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the identity matrix into all bone nodes, useful for returning to the T pose.
|
||||
*
|
||||
* <p>NOTE: this operation is independent of <code>animation</code>.</p>
|
||||
*/
|
||||
public void resetBoneMatrices() {
|
||||
nResetBoneMatrices(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of <code>animation</code> definitions in the glTF asset.
|
||||
*/
|
||||
@@ -109,6 +139,8 @@ public class Animator {
|
||||
|
||||
private static native void nApplyAnimation(long nativeAnimator, int index, float time);
|
||||
private static native void nUpdateBoneMatrices(long nativeAnimator);
|
||||
private static native void nApplyCrossFade(long nativeAnimator, int animIndex, float animTime, float alpha);
|
||||
private static native void nResetBoneMatrices(long nativeAnimator);
|
||||
private static native int nGetAnimationCount(long nativeAnimator);
|
||||
private static native float nGetAnimationDuration(long nativeAnimator, int index);
|
||||
private static native String nGetAnimationName(long nativeAnimator, int index);
|
||||
|
||||
@@ -45,7 +45,7 @@ import java.nio.Buffer;
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* materialProvider = UbershaderLoader(engine)
|
||||
* materialProvider = UbershaderProvider(engine)
|
||||
* assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
*
|
||||
* filamentAsset = assets.open("models/lucy.gltf").use { input ->
|
||||
|
||||
@@ -30,9 +30,9 @@ import com.google.android.filament.MaterialInstance;
|
||||
*
|
||||
* <p>For usage instructions, see the documentation for {@link AssetLoader}.</p>
|
||||
*
|
||||
* <p>This class owns a hierarchy of entities that have been loaded from a glTF asset. Every entity has
|
||||
* a <code>TransformManager</code> component, and some entities also have
|
||||
* <code>NameComponentManager</code> and/or <code>RenderableManager</code> components.</p>
|
||||
* <p>This class owns a hierarchy of entities that have been loaded from a glTF asset. Every entity
|
||||
* has a <code>TransformManager</code> component, and some entities also have compnents managed by
|
||||
* <code>NameComponentManager</code>, <code>RenderableManager</code>, and others.</p>
|
||||
*
|
||||
* <p>In addition to the aforementioned entities, an asset has strong ownership over a list of
|
||||
* <code>VertexBuffer</code>, <code>IndexBuffer</code>, <code>MaterialInstance</code>, and
|
||||
@@ -113,6 +113,15 @@ public class FilamentAsset {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets only the entities that have renderable components.
|
||||
*/
|
||||
public @NonNull @Entity int[] getRenderableEntities() {
|
||||
int[] result = new int[nGetRenderableEntityCount(mNativeObject)];
|
||||
nGetRenderableEntities(mNativeObject, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets only the entities that have camera components.
|
||||
*
|
||||
@@ -232,17 +241,37 @@ public class FilamentAsset {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the given skin to the given node, which must have an associated mesh with
|
||||
* BONE_INDICES and BONE_WEIGHTS attributes.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
public void attachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
|
||||
nAttachSkin(getNativeObject(), skinIndex, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the given skin to the given node, which must have an associated mesh with
|
||||
* BONE_INDICES and BONE_WEIGHTS attributes.
|
||||
*
|
||||
* This is a no-op if the given skin index or target is invalid.
|
||||
*/
|
||||
public void detachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
|
||||
nDetachSkin(getNativeObject(), skinIndex, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the joint count at skin index in this asset.
|
||||
*/
|
||||
public int getJointCountAt(int skinIndex) {
|
||||
public int getJointCountAt(@IntRange(from = 0) int skinIndex) {
|
||||
return nGetJointCountAt(getNativeObject(), skinIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets joints at skin index in this asset.
|
||||
*/
|
||||
public @NonNull @Entity int[] getJointsAt(int skinIndex) {
|
||||
public @NonNull @Entity int[] getJointsAt(@IntRange(from = 0) int skinIndex) {
|
||||
int[] result = new int[getJointCountAt(skinIndex)];
|
||||
nGetJointsAt(getNativeObject(), skinIndex, result);
|
||||
return result;
|
||||
@@ -321,6 +350,9 @@ public class FilamentAsset {
|
||||
private static native int nGetLightEntityCount(long nativeAsset);
|
||||
private static native void nGetLightEntities(long nativeAsset, int[] result);
|
||||
|
||||
private static native int nGetRenderableEntityCount(long nativeAsset);
|
||||
private static native void nGetRenderableEntities(long nativeAsset, int[] result);
|
||||
|
||||
private static native int nGetCameraEntityCount(long nativeAsset);
|
||||
private static native void nGetCameraEntities(long nativeAsset, int[] result);
|
||||
|
||||
@@ -333,6 +365,9 @@ public class FilamentAsset {
|
||||
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
|
||||
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
|
||||
|
||||
private static native void nAttachSkin(long nativeAsset, int skinIndex, int entity);
|
||||
private static native void nDetachSkin(long nativeAsset, int skinIndex, int entity);
|
||||
|
||||
private static native void nGetBoundingBox(long nativeAsset, float[] box);
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
|
||||
@@ -35,6 +35,8 @@ import java.nio.Buffer;
|
||||
*/
|
||||
public class ResourceLoader {
|
||||
private final long mNativeObject;
|
||||
private final long mNativeStbProvider;
|
||||
private final long mNativeKtx2Provider;
|
||||
|
||||
/**
|
||||
* Constructs a resource loader tied to the given Filament engine.
|
||||
@@ -46,6 +48,11 @@ public class ResourceLoader {
|
||||
public ResourceLoader(@NonNull Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
|
||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,6 +70,11 @@ public class ResourceLoader {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
|
||||
recomputeBoundingBoxes, ignoreBindTransform);
|
||||
mNativeStbProvider = nCreateStbProvider(nativeEngine);
|
||||
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
|
||||
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
|
||||
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +82,8 @@ public class ResourceLoader {
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyResourceLoader(mNativeObject);
|
||||
nDestroyTextureProvider(mNativeStbProvider);
|
||||
nDestroyTextureProvider(mNativeKtx2Provider);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,4 +192,9 @@ public class ResourceLoader {
|
||||
private static native float nAsyncGetLoadProgress(long nativeLoader);
|
||||
private static native void nAsyncUpdateLoad(long nativeLoader);
|
||||
private static native void nAsyncCancelLoad(long nativeLoader);
|
||||
|
||||
private static native long nCreateStbProvider(long nativeEngine);
|
||||
private static native long nCreateKtx2Provider(long nativeEngine);
|
||||
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
|
||||
private static native void nDestroyTextureProvider(long nativeProvider);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import androidx.annotation.Size;
|
||||
* <p>This class is used by {@link AssetLoader} to create Filament materials.
|
||||
* Client applications do not need to call methods on it.</p>
|
||||
*/
|
||||
public class UbershaderLoader implements MaterialProvider {
|
||||
public class UbershaderProvider implements MaterialProvider {
|
||||
private static final VertexBuffer.VertexAttribute[] sVertexAttributesValues =
|
||||
VertexBuffer.VertexAttribute.values();
|
||||
|
||||
@@ -42,16 +42,16 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
*
|
||||
* @param engine the engine used to create materials
|
||||
*/
|
||||
public UbershaderLoader(Engine engine) {
|
||||
public UbershaderProvider(Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateUbershaderLoader(nativeEngine);
|
||||
mNativeObject = nCreateUbershaderProvider(nativeEngine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees memory associated with the native material provider.
|
||||
* */
|
||||
public void destroy() {
|
||||
nDestroyUbershaderLoader(mNativeObject);
|
||||
nDestroyUbershaderProvider(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
@@ -92,8 +92,8 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
private static native long nCreateUbershaderLoader(long nativeEngine);
|
||||
private static native void nDestroyUbershaderLoader(long nativeProvider);
|
||||
private static native long nCreateUbershaderProvider(long nativeEngine);
|
||||
private static native void nDestroyUbershaderProvider(long nativeProvider);
|
||||
private static native void nDestroyMaterials(long nativeProvider);
|
||||
private static native long nCreateMaterialInstance(long nativeProvider,
|
||||
MaterialKey config, int[] uvmap, String label);
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.21.2
|
||||
VERSION_NAME=1.24.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Wed Nov 17 10:40:18 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -25,6 +25,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.gltf'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.gltf"
|
||||
@@ -32,6 +34,7 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
@@ -150,12 +150,12 @@ class MainActivity : Activity() {
|
||||
val scene = modelViewer.scene
|
||||
val ibl = "default_env"
|
||||
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
|
||||
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight = KTX1Loader.createIndirectLight(engine, it)
|
||||
scene.indirectLight!!.intensity = 30_000.0f
|
||||
viewerContent.indirectLight = modelViewer.scene.indirectLight
|
||||
}
|
||||
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
|
||||
scene.skybox = KTXLoader.createSkybox(engine, it)
|
||||
scene.skybox = KTX1Loader.createSkybox(engine, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +297,10 @@ class MainActivity : Activity() {
|
||||
|
||||
val gltfBuffer = pathToBufferMapping[gltfPath]!!
|
||||
|
||||
// The gltf is often not at the root level (e.g. if a folder is zipped) so
|
||||
// we need to extract its path in order to resolve the embedded uri strings.
|
||||
var prefix = URI(gltfPath!!).resolve("..")
|
||||
// In a zip file, the gltf file might be in the same folder as resources, or in a different
|
||||
// folder. It is crucial to test against both of these cases. In any case, the resource
|
||||
// paths are all specified relative to the location of the gltf file.
|
||||
var prefix = URI(gltfPath!!).resolve(".")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
@@ -308,7 +309,7 @@ class MainActivity : Activity() {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = prefix.resolve(uri).toString()
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix'")
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix' and base path '${gltfPath!!}'")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
|
||||
@@ -16,6 +16,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.hellocam'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellocamera"
|
||||
|
||||
@@ -16,6 +16,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.hellotriangle'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellotriangle"
|
||||
|
||||
@@ -22,6 +22,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.ibl'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.ibl"
|
||||
|
||||
@@ -15,6 +15,8 @@ clean.doFirst {
|
||||
delete "src/main/assets"
|
||||
}
|
||||
android {
|
||||
namespace 'com.google.android.filament.litcube'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.litcube"
|
||||
|
||||
@@ -4,6 +4,8 @@ apply plugin: 'kotlin-android'
|
||||
project.ext.isSample = true
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.livewallpaper'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.livewallpaper"
|
||||
|
||||
@@ -19,6 +19,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.material_builder'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.material_builder"
|
||||
|
||||
@@ -15,6 +15,8 @@ clean.doFirst {
|
||||
delete "src/main/assets"
|
||||
}
|
||||
android {
|
||||
namespace 'com.google.android.filament.multiview'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.multiview"
|
||||
|
||||
@@ -18,6 +18,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.pagecurl'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.pagecurl"
|
||||
|
||||
@@ -16,6 +16,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.streamtest'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.streamtest"
|
||||
|
||||
@@ -79,8 +79,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
// Performs the rendering and schedules new frames
|
||||
private val frameScheduler = FrameCallback()
|
||||
|
||||
private var externalTextureID: Int = 0
|
||||
|
||||
@RequiresApi(30)
|
||||
class Api30Impl {
|
||||
companion object {
|
||||
@@ -103,8 +101,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
setupView()
|
||||
setupScene()
|
||||
|
||||
externalTextureID = createExternalTexture()
|
||||
|
||||
@Suppress("deprecation")
|
||||
val display = if (Build.VERSION.SDK_INT >= 30) {
|
||||
Api30Impl.getDisplay(this)
|
||||
@@ -112,7 +108,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
windowManager.defaultDisplay!!
|
||||
}
|
||||
|
||||
streamHelper = StreamHelper(engine, materialInstance, display, externalTextureID)
|
||||
streamHelper = StreamHelper(engine, materialInstance, display)
|
||||
this.title = streamHelper.getTestName()
|
||||
}
|
||||
|
||||
@@ -445,31 +441,4 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
check(EGL14.eglMakeCurrent(display, surface, surface, context)) { "Error making GL context." }
|
||||
return context
|
||||
}
|
||||
|
||||
private fun createExternalTexture(): Int {
|
||||
val textures = IntArray(1)
|
||||
GLES30.glGenTextures(1, textures, 0)
|
||||
val result = textures[0]
|
||||
|
||||
val textureTarget = GLES11Ext.GL_TEXTURE_EXTERNAL_OES
|
||||
GLES30.glBindTexture(textureTarget, result)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST)
|
||||
GLES30.glTexParameteri(textureTarget, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST)
|
||||
|
||||
if (!GLES30.glIsTexture(result)) {
|
||||
throw RuntimeException("OpenGL error: $result is an invalid texture.")
|
||||
}
|
||||
|
||||
val error = GLES30.glGetError()
|
||||
if (error != GLES30.GL_NO_ERROR) {
|
||||
val errorString = GLU.gluErrorString(error)
|
||||
throw RuntimeException("OpenGL error: $errorString!")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ class StreamHelper(
|
||||
private val filamentEngine: Engine,
|
||||
private val filamentMaterial: MaterialInstance,
|
||||
private val display: Display,
|
||||
private val externalTextureId: Int
|
||||
) {
|
||||
/**
|
||||
* The StreamSource configures the source data for the texture.
|
||||
@@ -51,7 +50,6 @@ class StreamHelper(
|
||||
*/
|
||||
enum class StreamSource {
|
||||
CANVAS_STREAM_NATIVE, // copy-free but does not guarantee synchronization
|
||||
CANVAS_STREAM_TEXID, // synchronized but incurs a copy
|
||||
CANVAS_STREAM_ACQUIRED, // synchronized and copy-free
|
||||
}
|
||||
|
||||
@@ -127,10 +125,6 @@ class StreamHelper(
|
||||
|
||||
surface.unlockCanvasAndPost(canvas)
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
surfaceTexture!!.updateTexImage()
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
val image = imageReader!!.acquireLatestImage()
|
||||
filamentStream!!.setAcquiredImage(
|
||||
@@ -146,7 +140,7 @@ class StreamHelper(
|
||||
|
||||
fun nextTest() {
|
||||
stopTest()
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % 3]
|
||||
streamSource = StreamSource.values()[(streamSource.ordinal + 1) % StreamSource.values().size]
|
||||
startTest()
|
||||
}
|
||||
|
||||
@@ -213,23 +207,6 @@ class StreamHelper(
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_TEXID) {
|
||||
|
||||
// Create the Android surface that will hold the canvas image.
|
||||
surfaceTexture = SurfaceTexture(externalTextureId)
|
||||
surfaceTexture!!.setDefaultBufferSize(resolution.width, resolution.height)
|
||||
canvasSurface = Surface(surfaceTexture)
|
||||
|
||||
// Create the Filament Stream object that gets bound to the Texture.
|
||||
filamentStream = Stream.Builder()
|
||||
.stream(externalTextureId.toLong())
|
||||
.width(resolution.width)
|
||||
.height(resolution.height)
|
||||
.build(filamentEngine)
|
||||
|
||||
filamentTexture.setExternalStream(filamentEngine, filamentStream!!)
|
||||
}
|
||||
|
||||
if (streamSource == StreamSource.CANVAS_STREAM_ACQUIRED) {
|
||||
filamentStream = Stream.Builder()
|
||||
.width(resolution.width)
|
||||
|
||||
@@ -16,6 +16,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.textureview'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textureview"
|
||||
|
||||
@@ -22,6 +22,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.textured'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textured"
|
||||
|
||||
@@ -16,6 +16,8 @@ clean.doFirst {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.transparentrendering'
|
||||
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textureview"
|
||||
|
||||
BIN
art/diagrams/ImageUploadReadPixels.png
Normal file
BIN
art/diagrams/ImageUploadReadPixels.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
BIN
art/diagrams/NDC.png
Normal file
BIN
art/diagrams/NDC.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
art/diagrams/RenderingReadPixels.png
Normal file
BIN
art/diagrams/RenderingReadPixels.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
21
build.sh
21
build.sh
@@ -2,7 +2,7 @@
|
||||
set -e
|
||||
|
||||
# Host tools required by Android, WebGL, and iOS builds
|
||||
MOBILE_HOST_TOOLS="matc resgen cmgen filamesh"
|
||||
MOBILE_HOST_TOOLS="matc resgen cmgen filamesh uberz"
|
||||
WEB_HOST_TOOLS="${MOBILE_HOST_TOOLS} mipgen filamesh"
|
||||
|
||||
function print_help {
|
||||
@@ -98,9 +98,9 @@ function print_matdbg_help {
|
||||
echo ""
|
||||
echo "FOR ANDROID BUILDS:"
|
||||
echo ""
|
||||
echo "1) The most reliable way to enable matdbg is to bypass Gradle and"
|
||||
echo " directly modify the appropriate two lines in the following file:"
|
||||
echo " ./android/filament-android/CMakeLists.txt"
|
||||
echo "1) For Android Studio builds, make sure to set:"
|
||||
echo " -Pcom.google.android.filament.matdbg"
|
||||
echo " option in Preferences > Build > Compiler > Command line options."
|
||||
echo ""
|
||||
echo "2) The port number is hardcoded to 8081 so you will need to do:"
|
||||
echo " adb forward tcp:8081 tcp:8081"
|
||||
@@ -156,6 +156,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
|
||||
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
|
||||
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
@@ -303,7 +304,7 @@ function build_webgl_with_target {
|
||||
}
|
||||
|
||||
function build_webgl {
|
||||
# For the host tools, supress install and always use Release.
|
||||
# For the host tools, suppress install and always use Release.
|
||||
local old_install_command=${INSTALL_COMMAND}; INSTALL_COMMAND=
|
||||
local old_issue_debug_build=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
|
||||
local old_issue_release_build=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
|
||||
@@ -402,7 +403,7 @@ function ensure_android_build {
|
||||
function build_android {
|
||||
ensure_android_build
|
||||
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -456,6 +457,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleDebug \
|
||||
:gltfio-android:assembleDebug \
|
||||
:filament-utils-android:assembleDebug
|
||||
@@ -476,14 +478,12 @@ function build_android {
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-debug.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-debug.aar ../out/
|
||||
cp filamat-android/build/outputs/aar/filamat-android-full-debug.aar ../out/filamat-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-android-debug.aar..."
|
||||
cp filament-android/build/outputs/aar/filament-android-debug.aar ../out/
|
||||
|
||||
echo "Installing out/gltfio-android-debug.aar..."
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-lite-debug.aar ../out/
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-debug.aar ../out/gltfio-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
@@ -504,6 +504,7 @@ function build_android {
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${VULKAN_ANDROID_GRADLE_OPTION} \
|
||||
${MATDBG_GRADLE_OPTION} \
|
||||
:filament-android:assembleRelease \
|
||||
:gltfio-android:assembleRelease \
|
||||
:filament-utils-android:assembleRelease
|
||||
@@ -531,7 +532,6 @@ function build_android {
|
||||
cp filament-android/build/outputs/aar/filament-android-release.aar ../out/
|
||||
|
||||
echo "Installing out/gltfio-android-release.aar..."
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-lite-release.aar ../out/
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-release.aar ../out/gltfio-android-release.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
@@ -598,7 +598,7 @@ function archive_ios {
|
||||
}
|
||||
|
||||
function build_ios {
|
||||
# Supress intermediate desktop tools install
|
||||
# Suppress intermediate desktop tools install
|
||||
local old_install_command=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
|
||||
@@ -754,6 +754,7 @@ while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
|
||||
d)
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
|
||||
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
|
||||
@@ -49,7 +49,8 @@ FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
|
||||
|
||||
# Install the required NDK version specifically (if not present)
|
||||
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
# NOTE: We MUST use Java 1.8 to run sdkmanager currently, it fails starting with Java 11
|
||||
JAVA_HOME=${JAVA_HOME_8_X64} ${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
fi
|
||||
|
||||
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||
|
||||
@@ -1 +1 @@
|
||||
23.1.7779620
|
||||
24.0.8215888
|
||||
@@ -7,7 +7,7 @@ Deprecated==1.2.13
|
||||
idna==3.3
|
||||
pycparser==2.21
|
||||
PyGithub==1.55
|
||||
PyJWT==2.3.0
|
||||
PyJWT==2.4.0
|
||||
PyNaCl==1.5.0
|
||||
requests==2.27.1
|
||||
urllib3==1.26.9
|
||||
|
||||
@@ -17,7 +17,7 @@ export PATH="$PWD:$PATH"
|
||||
# npm install -g typescript
|
||||
|
||||
# Install emscripten.
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.5.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
|
||||
@@ -119,9 +119,8 @@ cmake ..\.. ^
|
||||
:: Some resource libraries require significant heap space to compile, so first compile them serially.
|
||||
@echo on
|
||||
cmake --build . --target filagui --config %config% || exit /b
|
||||
cmake --build . --target gltfio_resources --config %config% || exit /b
|
||||
cmake --build . --target gltfio_resources_lite --config %config% || exit /b
|
||||
cmake --build . --target gltf-resources --config %config% || exit /b
|
||||
cmake --build . --target uberarchive --config %config% || exit /b
|
||||
cmake --build . --target gltf-demo-resources --config %config% || exit /b
|
||||
cmake --build . --target filamentapp-resources --config %config% || exit /b
|
||||
cmake --build . --target sample-resources --config %config% || exit /b
|
||||
cmake --build . --target suzanne-resources --config %config% || exit /b
|
||||
|
||||
@@ -118,6 +118,7 @@ counter-increment: h6;margin-right:10px}
|
||||
<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" class="level3"><span class="tocNumber">4.2.31 </span>Shading: customSurfaceShading</a><br>
|
||||
<a href="#materialdefinitions/vertexblock" class="level2"><span class="tocNumber">4.3 </span>Vertex block</a><br>
|
||||
<a href="#materialdefinitions/vertexblock/materialvertexinputs" class="level3"><span class="tocNumber">4.3.1 </span>Material vertex inputs</a><br>
|
||||
<a href="#materialdefinitions/vertexblock/customvertexattributes" class="level3"><span class="tocNumber">4.3.2 </span>Custom vertex attributes</a><br>
|
||||
<a href="#materialdefinitions/fragmentblock" class="level2"><span class="tocNumber">4.4 </span>Fragment block</a><br>
|
||||
<a href="#materialdefinitions/fragmentblock/preparematerialfunction" class="level3"><span class="tocNumber">4.4.1 </span>prepareMaterial function</a><br>
|
||||
<a href="#materialdefinitions/fragmentblock/materialfragmentinputs" class="level3"><span class="tocNumber">4.4.2 </span>Material fragment inputs</a><br>
|
||||
@@ -1536,7 +1537,7 @@ non-shader data.
|
||||
|
||||
</p><dl><dt>Type</dt><dd><p> array of <code>string</code>
|
||||
|
||||
</p></dd><dt>Value</dt><dd><p> Each entry must be any of <code>dynamicLighting</code>, <code>directionalLighting</code>, <code>shadowReceiver</code> or <code>skinning</code>.
|
||||
</p></dd><dt>Value</dt><dd><p> Each entry must be any of <code>dynamicLighting</code>, <code>directionalLighting</code>, <code>shadowReceiver</code>,<code>skinning</code> or <code>ssr</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Used to specify a list of shader variants that the application guarantees will never be
|
||||
needed. These shader variants are skipped during the code generation phase, thus reducing
|
||||
@@ -1561,7 +1562,9 @@ non-shader data.
|
||||
</li>
|
||||
<li class="minus"><code>fog</code>, used when global fog is applied to the scene
|
||||
</li>
|
||||
<li class="minus"><code>vsm</code>, used when VSM shadows are enabled and the object is a shadow receiver</li></ul>
|
||||
<li class="minus"><code>vsm</code>, used when VSM shadows are enabled and the object is a shadow receiver
|
||||
</li>
|
||||
<li class="minus"><code>ssr</code>, used when screen-space reflections are enabled in the View</li></ul>
|
||||
|
||||
<p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> name : <span class="hljs-string">"Invisible shadow plane"</span>,</span>
|
||||
@@ -1607,7 +1610,8 @@ non-shader data.
|
||||
|
||||
</p><dl><dt>Type</dt><dd><p> array of <code>string</code>
|
||||
|
||||
</p></dd><dt>Value</dt><dd><p> Each entry must be any of <code>uv0</code>, <code>uv1</code>, <code>color</code>, <code>position</code>, <code>tangents</code>.
|
||||
</p></dd><dt>Value</dt><dd><p> Each entry must be any of <code>uv0</code>, <code>uv1</code>, <code>color</code>, <code>position</code>, <code>tangents</code>, <code>custom0</code>
|
||||
through <code>custom7</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Lists the vertex attributes required by the material. The <code>position</code> attribute is always
|
||||
required and does not need to be specified. The <code>tangents</code> attribute is automatically required
|
||||
@@ -1622,7 +1626,8 @@ non-shader data.
|
||||
<span class="line"> },</span>
|
||||
<span class="line"> ],</span>
|
||||
<span class="line"> requires : [</span>
|
||||
<span class="line"> uv0</span>
|
||||
<span class="line"> uv0,</span>
|
||||
<span class="line"> custom0</span>
|
||||
<span class="line"> ],</span>
|
||||
<span class="line"> shadingModel : lit,</span>
|
||||
<span class="line">}</span>
|
||||
@@ -1631,6 +1636,7 @@ non-shader data.
|
||||
<span class="line"> void material(inout MaterialInputs material) {</span>
|
||||
<span class="line"> prepareMaterial(material);</span>
|
||||
<span class="line"> material.baseColor = texture(materialParams_texture, getUV0());</span>
|
||||
<span class="line"> material.baseColor.rgb *= getCustom0().rgb;</span>
|
||||
<span class="line"> }</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:variables"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:variables"> </a><a class="target" name="toc4.2.8"> </a><h3>Vertex and attributes: variables</h3>
|
||||
@@ -1759,8 +1765,9 @@ non-shader data.
|
||||
render target is brightened.
|
||||
</li>
|
||||
<li class="minus"><strong class="asterisk">Masked</strong>: blending is disabled. This blending mode enables alpha masking. The alpha channel
|
||||
of the material's output defines whether a fragment is discarded or not. See the maskThreshold
|
||||
section for more information.</li></ul>
|
||||
of the material's output defines whether a fragment is discarded or not. Additionally,
|
||||
ALPHA_TO_COVERAGE is enabled for non-translucent views. See the maskThreshold section for more
|
||||
information.</li></ul>
|
||||
|
||||
<p></p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> blending : transparent</span>
|
||||
@@ -1851,8 +1858,9 @@ and sorting issues are minimized or eliminated</span></center></div></center>
|
||||
</p></dd><dt>Value</dt><dd><p> A value between <code>0.0</code> and <code>1.0</code>. Defaults to <code>0.4</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Sets the minimum alpha value a fragment must have to not be discarded when the <code>blending</code> mode
|
||||
is set to <code>masked</code>. When the blending mode is not <code>masked</code>, this value is ignored. This value
|
||||
can be used to controlled the appearance of alpha-masked objects.
|
||||
is set to <code>masked</code>. If the fragment is not discarded, its source alpha is set to 1. When the
|
||||
blending mode is not <code>masked</code>, this value is ignored. This value can be used to controlled the
|
||||
appearance of alpha-masked objects.
|
||||
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> blending : masked,</span>
|
||||
@@ -2274,15 +2282,31 @@ APIs listed in the <a href="#shaderpublicapis">Shader public APIs</a> section.
|
||||
this behavior using the <code>flipUV</code> property and setting it to <code>false</code>.</p></div>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="customvertexattributes"> </a><a class="target" name="materialdefinitions/vertexblock/customvertexattributes"> </a><a class="target" name="toc4.3.2"> </a><h3>Custom vertex attributes</h3>
|
||||
<p>
|
||||
|
||||
|
||||
You can use up to 8 custom vertex attributes, all of type <code>float4</code>. These attributes can be accessed
|
||||
using the vertex block shader functions <code>getCustom0()</code> to <code>getCustom7()</code>. However, before using
|
||||
custom attributes, you <em class="asterisk">must</em> declare those attributes as required in the <code>requires</code> property of
|
||||
the material:
|
||||
|
||||
</p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> requires : [</span>
|
||||
<span class="line"> custom0,</span>
|
||||
<span class="line"> custom1,</span>
|
||||
<span class="line"> custom2</span>
|
||||
<span class="line"> ]</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="fragmentblock"> </a><a class="target" name="materialdefinitions/fragmentblock"> </a><a class="target" name="toc4.4"> </a><h2>Fragment block</h2>
|
||||
<p>
|
||||
|
||||
|
||||
The fragment block must be used to control the fragment shading stage of the material. The vertex
|
||||
The fragment block must be used to control the fragment shading stage of the material. The fragment
|
||||
block must contain valid
|
||||
<a href="https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf">ESSL 3.0</a>
|
||||
code (the version of GLSL supported in OpenGL ES 3.0). You are free to create multiple functions
|
||||
inside the vertex block but you <strong class="asterisk">must</strong> declare the <code>material</code> function:
|
||||
inside the fragment block but you <strong class="asterisk">must</strong> declare the <code>material</code> function:
|
||||
|
||||
</p><pre class="listing tilde"><code><span class="line">fragment {</span>
|
||||
<span class="line"> <span class="hljs-type">void</span> material(<span class="hljs-keyword">inout</span> MaterialInputs material) {</span>
|
||||
@@ -2316,7 +2340,7 @@ standard lit shading model:
|
||||
|
||||
|
||||
Note that you <strong class="asterisk">must</strong> call <code>prepareMaterial(material)</code> before exiting the <code>material()</code> function.
|
||||
This <code>prepareMaterial</code> function sets up the internal state of the material mdoel. Some of the APIs
|
||||
This <code>prepareMaterial</code> function sets up the internal state of the material model. Some of the APIs
|
||||
described in the Fragment APIs section - like <code>shading_normal</code> for instance - can only be accessed
|
||||
<em class="underscore">after</em> invoking <code>prepareMaterial()</code>.
|
||||
|
||||
@@ -2616,7 +2640,7 @@ type aliases:
|
||||
<p>
|
||||
|
||||
</p><div class="table"><table class="table"><tbody><tr><th style="text-align:left"> Name </th><th style="text-align:center"> Type </th><th style="text-align:left"> Description </th></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getResolution()</strong> </td><td style="text-align:center"> float4 </td><td style="text-align:left"> Resolution of the view in pixels: <code>width</code>, <code>height</code>, <code>1 / width</code>, <code>1 / height</code> </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getResolution()</strong> </td><td style="text-align:center"> float4 </td><td style="text-align:left"> Dimensions of the view's effective viewport in pixels: <code>width</code>, <code>height</code>, <code>1 / width</code>, <code>1 / height</code>. This might be different from <code>View::getViewport()</code> for instance because of added rendering guard-bands. This can be used in conjunction with <code>getNormalizedViewportCoord()</code> to generate pixel coordinates. </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getWorldCameraPosition()</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:left"> Position of the camera/eye in world space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getWorldOffset()</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:left"> The shift required to obtain API-level world space </td></tr>
|
||||
<tr><td style="text-align:left"> <strong class="asterisk">getTime()</strong> </td><td style="text-align:center"> float </td><td style="text-align:left"> Current time as a remainder of 1 second. Yields a value between 0 and 1 </td></tr>
|
||||
@@ -2821,7 +2845,9 @@ variants:
|
||||
</li>
|
||||
<li class="minus"><code>fog</code>, used when global fog is applied to the scene
|
||||
</li>
|
||||
<li class="minus"><code>vsm</code>, used when VSM shadows are enabled and the object is a shadow receiver</li></ul>
|
||||
<li class="minus"><code>vsm</code>, used when VSM shadows are enabled and the object is a shadow receiver
|
||||
</li>
|
||||
<li class="minus"><code>ssr</code>, used when screen-space reflections are enabled in the View</li></ul>
|
||||
|
||||
<p></p><p>
|
||||
|
||||
|
||||
@@ -1119,13 +1119,35 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: instanced
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: Allows a material to access the instance index (i.e.: **`gl_InstanceIndex`**) of instanced
|
||||
primitives using `getInstanceIndex()` in the material's shader code. Never use
|
||||
**`gl_InstanceIndex`** directly. This is typically used with
|
||||
`RenderableManager::Builder::instances()`. `getInstanceIndex()` is available in both the
|
||||
vertex and fragment shader.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
instanced : true
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Vertex and attributes: requires
|
||||
|
||||
Type
|
||||
: array of `string`
|
||||
|
||||
Value
|
||||
: Each entry must be any of `uv0`, `uv1`, `color`, `position`, `tangents`.
|
||||
: Each entry must be any of `uv0`, `uv1`, `color`, `position`, `tangents`, `custom0`
|
||||
through `custom7`.
|
||||
|
||||
Description
|
||||
: Lists the vertex attributes required by the material. The `position` attribute is always
|
||||
@@ -1142,7 +1164,8 @@ material {
|
||||
},
|
||||
],
|
||||
requires : [
|
||||
uv0
|
||||
uv0,
|
||||
custom0
|
||||
],
|
||||
shadingModel : lit,
|
||||
}
|
||||
@@ -1151,6 +1174,7 @@ fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
material.baseColor = texture(materialParams_texture, getUV0());
|
||||
material.baseColor.rgb *= getCustom0().rgb;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -1841,13 +1865,30 @@ struct MaterialVertexInputs {
|
||||
of the current mesh: `material.uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y)`. You can control
|
||||
this behavior using the `flipUV` property and setting it to `false`.
|
||||
|
||||
### Custom vertex attributes
|
||||
|
||||
You can use up to 8 custom vertex attributes, all of type `float4`. These attributes can be accessed
|
||||
using the vertex block shader functions `getCustom0()` to `getCustom7()`. However, before using
|
||||
custom attributes, you *must* declare those attributes as required in the `requires` property of
|
||||
the material:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
requires : [
|
||||
custom0,
|
||||
custom1,
|
||||
custom2
|
||||
]
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
## Fragment block
|
||||
|
||||
The fragment block must be used to control the fragment shading stage of the material. The vertex
|
||||
The fragment block must be used to control the fragment shading stage of the material. The fragment
|
||||
block must contain valid
|
||||
[ESSL 3.0](https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf)
|
||||
code (the version of GLSL supported in OpenGL ES 3.0). You are free to create multiple functions
|
||||
inside the vertex block but you **must** declare the `material` function:
|
||||
inside the fragment block but you **must** declare the `material` function:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GLSL
|
||||
fragment {
|
||||
@@ -1882,7 +1923,7 @@ fragment {
|
||||
### prepareMaterial function
|
||||
|
||||
Note that you **must** call `prepareMaterial(material)` before exiting the `material()` function.
|
||||
This `prepareMaterial` function sets up the internal state of the material mdoel. Some of the APIs
|
||||
This `prepareMaterial` function sets up the internal state of the material model. Some of the APIs
|
||||
described in the Fragment APIs section - like `shading_normal` for instance - can only be accessed
|
||||
_after_ invoking `prepareMaterial()`.
|
||||
|
||||
@@ -2169,7 +2210,7 @@ type aliases:
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getResolution()** | float4 | Resolution of the view in pixels: `width`, `height`, `1 / width`, `1 / height`
|
||||
**getResolution()** | float4 | Dimensions of the view's effective viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands. This can be used in conjunction with `getNormalizedViewportCoord()` to generate pixel coordinates.
|
||||
**getWorldCameraPosition()** | float3 | Position of the camera/eye in world space
|
||||
**getWorldOffset()** | float3 | The shift required to obtain API-level world space
|
||||
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
|
||||
|
||||
@@ -15,22 +15,17 @@
|
||||
*/
|
||||
|
||||
// If you are bundling this with rollup, webpack, or esbuild, the following URL should be trimmed.
|
||||
import { LitElement, html, css } from "https://unpkg.com/lit-element?module";
|
||||
import { LitElement, html, css } from "https://unpkg.com/lit?module";
|
||||
|
||||
// To allow the DOM to render before the Filament WASM module is ready, we maintain a little
|
||||
// queue of tasks that get invoked as soon as the module is done loading.
|
||||
// This little utility checks if the Filament module is ready for action.
|
||||
// If so, it immediately calls the given function. If not, it asks the Filament
|
||||
// loader to call it as soon as the module becomes ready.
|
||||
class FilamentTasks {
|
||||
constructor() {
|
||||
this.tasks = []
|
||||
if (!Filament.Engine) {
|
||||
Filament.init([], () => { for (const task of this.tasks) task(); });
|
||||
}
|
||||
}
|
||||
add(callback) {
|
||||
if (!Filament.Engine) {
|
||||
this.tasks.push(callback);
|
||||
} else {
|
||||
if (Filament.isReady) {
|
||||
callback();
|
||||
} else {
|
||||
Filament.init([], callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,6 +63,7 @@ class FilamentViewer extends LitElement {
|
||||
this.sky = null; // Path to skybox ktx.
|
||||
this.enableDrop = null; // Enables drag and drop.
|
||||
this.intensity = 30000; // Intensity of the image based light.
|
||||
this.materialVariant = 0; // Index of material variant.
|
||||
|
||||
// Private properties:
|
||||
this.filamentTasks = new FilamentTasks();
|
||||
@@ -84,6 +80,7 @@ class FilamentViewer extends LitElement {
|
||||
sky: { type: String },
|
||||
enableDrop: { type: Boolean },
|
||||
intensity: { type: Number },
|
||||
materialVariant: { type: Number },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +113,7 @@ class FilamentViewer extends LitElement {
|
||||
if (props.has("intensity") && this.indirectLight) {
|
||||
this.indirectLight.setIntensity(this.intensity);
|
||||
}
|
||||
if (props.has("materialVariant") && this.asset) this._applyMaterialVariant();
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
@@ -248,7 +246,7 @@ class FilamentViewer extends LitElement {
|
||||
return response.arrayBuffer();
|
||||
}).then(arrayBuffer => {
|
||||
const ktxData = new Uint8Array(arrayBuffer);
|
||||
this.indirectLight = this.engine.createIblFromKtx(ktxData);
|
||||
this.indirectLight = this.engine.createIblFromKtx1(ktxData);
|
||||
this.indirectLight.setIntensity(this.intensity);
|
||||
this.scene.setIndirectLight(this.indirectLight);
|
||||
});
|
||||
@@ -266,7 +264,7 @@ class FilamentViewer extends LitElement {
|
||||
return response.arrayBuffer();
|
||||
}).then(arrayBuffer => {
|
||||
const ktxData = new Uint8Array(arrayBuffer);
|
||||
this.skybox = this.engine.createSkyFromKtx(ktxData);
|
||||
this.skybox = this.engine.createSkyFromKtx1(ktxData);
|
||||
this.scene.setSkybox(this.skybox);
|
||||
});
|
||||
}
|
||||
@@ -311,7 +309,7 @@ class FilamentViewer extends LitElement {
|
||||
asyncInterval: 30
|
||||
};
|
||||
|
||||
const doneAddingResources = resourceLoader => {
|
||||
const doneAddingResources = (resourceLoader, stbProvider, ktx2Provider) => {
|
||||
this.srcBlobResources = {};
|
||||
resourceLoader.asyncBeginLoad(this.asset);
|
||||
const timer = setInterval(() => {
|
||||
@@ -320,6 +318,8 @@ class FilamentViewer extends LitElement {
|
||||
if (progress >= 1) {
|
||||
clearInterval(timer);
|
||||
resourceLoader.delete();
|
||||
stbProvider.delete();
|
||||
ktx2Provider.delete();
|
||||
this.animator = this.asset.getAnimator();
|
||||
this.animationStartTime = Date.now();
|
||||
}
|
||||
@@ -337,13 +337,20 @@ class FilamentViewer extends LitElement {
|
||||
config.recomputeBoundingBoxes,
|
||||
config.ignoreBindTransform);
|
||||
|
||||
const stbProvider = new Filament.gltfio$StbProvider(this.engine);
|
||||
const ktx2Provider = new Filament.gltfio$Ktx2Provider(this.engine);
|
||||
|
||||
resourceLoader.addStbProvider("image/jpeg", stbProvider);
|
||||
resourceLoader.addStbProvider("image/png", stbProvider);
|
||||
resourceLoader.addKtx2Provider("image/ktx2", ktx2Provider);
|
||||
|
||||
let remaining = Object.keys(this.srcBlobResources).length;
|
||||
for (const name in this.srcBlobResources) {
|
||||
this.srcBlobResources[name].arrayBuffer().then(buffer => {
|
||||
const desc = getBufferDescriptor(new Uint8Array(buffer));
|
||||
resourceLoader.addResourceData(name, getBufferDescriptor(desc));
|
||||
if (--remaining === 0) {
|
||||
doneAddingResources(resourceLoader);
|
||||
doneAddingResources(resourceLoader, stbProvider, ktx2Provider);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -375,6 +382,7 @@ class FilamentViewer extends LitElement {
|
||||
this.asset.loadResources(() => {
|
||||
this.animator = this.asset.getAnimator();
|
||||
this.animationStartTime = Date.now();
|
||||
this._applyMaterialVariant();
|
||||
}, null, basePath);
|
||||
|
||||
this._updateOverlay();
|
||||
@@ -383,9 +391,11 @@ class FilamentViewer extends LitElement {
|
||||
|
||||
_updateAsset() {
|
||||
// Invoke the first glTF animation if it exists.
|
||||
if (this.animator && this.animator.getAnimationCount() > 0) {
|
||||
const ms = Date.now() - this.animationStartTime;
|
||||
this.animator.applyAnimation(0, ms / 1000);
|
||||
if (this.animator) {
|
||||
if (this.animator.getAnimationCount() > 0) {
|
||||
const ms = Date.now() - this.animationStartTime;
|
||||
this.animator.applyAnimation(0, ms / 1000);
|
||||
}
|
||||
this.animator.updateBoneMatrices();
|
||||
}
|
||||
|
||||
@@ -426,6 +436,20 @@ class FilamentViewer extends LitElement {
|
||||
|
||||
window.requestAnimationFrame(this._renderFrame.bind(this));
|
||||
}
|
||||
|
||||
_applyMaterialVariant() {
|
||||
if (!this.hasAttribute("materialVariant")) {
|
||||
return;
|
||||
}
|
||||
const names = this.asset.getMaterialVariantNames();
|
||||
const index = this.materialVariant;
|
||||
if (index < 0 || index >= names.length) {
|
||||
console.error(`Material variant ${index} does not exist in this asset.`);
|
||||
return;
|
||||
}
|
||||
console.info(this.src, `Applying material variant: ${names[index]}`);
|
||||
this.asset.applyMaterialVariant(index);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("filament-viewer", FilamentViewer);
|
||||
|
||||
@@ -43,7 +43,7 @@ filament-viewer::part(canvas) {
|
||||
</p>
|
||||
|
||||
</main>
|
||||
<script src="https://unpkg.com/filament/filament.js"></script>
|
||||
<script src="https://unpkg.com/filament@1.22.0/filament.js"></script>
|
||||
<script src="https://unpkg.com/gltumble"></script>
|
||||
<script src="filament-viewer.js" type="module"></script>
|
||||
</body>
|
||||
|
||||
@@ -63,6 +63,7 @@ set(SRCS
|
||||
src/FrameSkipper.cpp
|
||||
src/Froxelizer.cpp
|
||||
src/Frustum.cpp
|
||||
src/HwRenderPrimitiveFactory.cpp
|
||||
src/IndexBuffer.cpp
|
||||
src/IndirectLight.cpp
|
||||
src/LightManager.cpp
|
||||
@@ -77,6 +78,7 @@ set(SRCS
|
||||
src/RenderTarget.cpp
|
||||
src/RenderableManager.cpp
|
||||
src/Renderer.cpp
|
||||
src/RendererUtils.cpp
|
||||
src/ResourceAllocator.cpp
|
||||
src/ResourceList.cpp
|
||||
src/Scene.cpp
|
||||
@@ -130,6 +132,7 @@ set(SRCS
|
||||
|
||||
set(PRIVATE_HDRS
|
||||
src/Allocators.h
|
||||
src/BufferPoolAllocator.h
|
||||
src/ColorSpace.h
|
||||
src/Culler.h
|
||||
src/DFG.h
|
||||
@@ -138,11 +141,13 @@ set(PRIVATE_HDRS
|
||||
src/FrameInfo.h
|
||||
src/FrameSkipper.h
|
||||
src/Froxelizer.h
|
||||
src/HwRenderPrimitiveFactory.h
|
||||
src/Intersections.h
|
||||
src/MaterialParser.h
|
||||
src/PerViewUniforms.h
|
||||
src/PIDController.h
|
||||
src/PostProcessManager.h
|
||||
src/RendererUtils.h
|
||||
src/RenderPass.h
|
||||
src/RenderPrimitive.h
|
||||
src/ResourceAllocator.h
|
||||
@@ -454,6 +459,34 @@ add_custom_command(
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/separableGaussianBlur1L.filamat"
|
||||
DEPENDS src/materials/separableGaussianBlur.vs
|
||||
DEPENDS src/materials/separableGaussianBlur.fs
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/separableGaussianBlur2L.filamat"
|
||||
DEPENDS src/materials/separableGaussianBlur.vs
|
||||
DEPENDS src/materials/separableGaussianBlur.fs
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/separableGaussianBlur3L.filamat"
|
||||
DEPENDS src/materials/separableGaussianBlur.vs
|
||||
DEPENDS src/materials/separableGaussianBlur.fs
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/separableGaussianBlur4L.filamat"
|
||||
DEPENDS src/materials/separableGaussianBlur.vs
|
||||
DEPENDS src/materials/separableGaussianBlur.fs
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${RESGEN_OUTPUTS}
|
||||
COMMAND resgen ${RESGEN_FLAGS} ${MATERIAL_BINS}
|
||||
|
||||
@@ -49,6 +49,9 @@ To use the Vulkan backend on macOS you must also make the following libraries av
|
||||
- `libMoltenVK.dylib`
|
||||
- `libvulkan.1.dylib`
|
||||
|
||||
The easiest way to install those files is to use the macOS
|
||||
[LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) installer.
|
||||
|
||||
## Linking against Filament
|
||||
|
||||
This walkthrough will get you successfully compiling and linking native code
|
||||
|
||||
@@ -65,8 +65,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/gl_headers.h
|
||||
src/opengl/GLUtils.cpp
|
||||
src/opengl/GLUtils.h
|
||||
src/opengl/OpenGLBlitter.cpp
|
||||
src/opengl/OpenGLBlitter.h
|
||||
src/opengl/OpenGLContext.cpp
|
||||
src/opengl/OpenGLContext.h
|
||||
src/opengl/OpenGLDriver.cpp
|
||||
@@ -89,7 +87,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
endif ()
|
||||
if (ANDROID)
|
||||
list(APPEND SRCS src/opengl/platforms/ExternalStreamManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/android/ExternalTextureManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGLAndroid.cpp)
|
||||
elseif (IOS)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaTouchGL.mm)
|
||||
@@ -392,6 +389,7 @@ if (APPLE)
|
||||
test/test_MRT.cpp
|
||||
test/test_LoadImage.cpp
|
||||
test/test_RenderExternalImage.cpp
|
||||
test/test_StencilBuffer.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(backend_test PRIVATE
|
||||
@@ -440,16 +438,3 @@ if (APPLE AND NOT IOS)
|
||||
target_link_libraries(backend_test_mac PRIVATE -force_load backend_test)
|
||||
endif()
|
||||
|
||||
if (APPLE AND NOT Vulkan_LIBRARY AND NOT FILAMENT_USE_SWIFTSHADER)
|
||||
message(STATUS "No Vulkan SDK was found, using prebuilt MoltenVK.")
|
||||
set(MOLTENVK_DIR "../../third_party/moltenvk")
|
||||
configure_file(
|
||||
${MOLTENVK_DIR}/libvulkan.1.dylib
|
||||
${PROJECT_BINARY_DIR}/libvulkan.1.dylib COPYONLY)
|
||||
configure_file(
|
||||
${MOLTENVK_DIR}/MoltenVK_icd.json
|
||||
${PROJECT_BINARY_DIR}/MoltenVK_icd.json COPYONLY)
|
||||
configure_file(
|
||||
${MOLTENVK_DIR}/libMoltenVK.dylib
|
||||
${PROJECT_BINARY_DIR}/libMoltenVK.dylib COPYONLY)
|
||||
endif()
|
||||
|
||||
@@ -42,22 +42,22 @@
|
||||
*/
|
||||
namespace filament::backend {
|
||||
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
|
||||
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
|
||||
static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
|
||||
"The number of buffer objects that can be attached to a VertexBuffer must be "
|
||||
"less than or equal to the maximum number of vertex attributes.");
|
||||
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 8;
|
||||
static constexpr size_t CONFIG_BINDING_COUNT = 12; // This is guaranteed by OpenGL ES.
|
||||
|
||||
/**
|
||||
* Selects which driver a particular Engine should use.
|
||||
@@ -128,7 +128,6 @@ inline constexpr TargetBufferFlags getTargetBufferFlagsAt(size_t index) noexcept
|
||||
enum class BufferUsage : uint8_t {
|
||||
STATIC, //!< content modified once, used many times
|
||||
DYNAMIC, //!< content modified frequently, used many times
|
||||
STREAM, //!< content invalidated and modified frequently, used many times
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -719,7 +718,7 @@ enum class SamplerCompareMode : uint8_t {
|
||||
COMPARE_TO_TEXTURE = 1
|
||||
};
|
||||
|
||||
//! comparison function for the depth sampler
|
||||
//! comparison function for the depth / stencil sampler
|
||||
enum class SamplerCompareFunc : uint8_t {
|
||||
// don't change the enums values
|
||||
LE = 0, //!< Less or equal
|
||||
@@ -728,11 +727,11 @@ enum class SamplerCompareFunc : uint8_t {
|
||||
G, //!< Strictly greater than
|
||||
E, //!< Equal
|
||||
NE, //!< Not equal
|
||||
A, //!< Always. Depth testing is deactivated.
|
||||
N //!< Never. The depth test always fails.
|
||||
A, //!< Always. Depth / stencil testing is deactivated.
|
||||
N //!< Never. The depth / stencil test always fails.
|
||||
};
|
||||
|
||||
//! Sampler paramters
|
||||
//! Sampler parameters
|
||||
struct SamplerParams { // NOLINT
|
||||
union {
|
||||
struct {
|
||||
@@ -785,10 +784,21 @@ enum class BlendFunction : uint8_t {
|
||||
SRC_ALPHA_SATURATE //!< f(src, dst) = (1,1,1) * min(src.a, 1 - dst.a), 1
|
||||
};
|
||||
|
||||
//! stencil operation
|
||||
enum class StencilOperation : uint8_t {
|
||||
KEEP, //!< Keeps the current value.
|
||||
ZERO, //!< Sets the value to 0.
|
||||
REPLACE, //!< Sets the value to the stencil reference value.
|
||||
INCR, //!< Increments the current value. Clamps to the maximum representable unsigned value.
|
||||
INCR_WRAP, //!< Increments the current value. Wraps value to zero when incrementing the maximum representable unsigned value.
|
||||
DECR, //!< Decrements the current value. Clamps to 0.
|
||||
DECR_WRAP, //!< Decrements the current value. Wraps value to the maximum representable unsigned value when decrementing a value of zero.
|
||||
INVERT, //!< Bitwise inverts the current value.
|
||||
};
|
||||
|
||||
//! Stream for external textures
|
||||
enum class StreamType {
|
||||
NATIVE, //!< Not synchronized but copy-free. Good for video.
|
||||
TEXTURE_ID, //!< Synchronized, but GL-only and incurs copies. Good for AR on devices before API 26.
|
||||
ACQUIRED, //!< Synchronized, copy-free, and take a release callback. Good for AR but requires API 26+.
|
||||
};
|
||||
|
||||
@@ -818,9 +828,11 @@ struct RasterState {
|
||||
using DepthFunc = backend::SamplerCompareFunc;
|
||||
using BlendEquation = backend::BlendEquation;
|
||||
using BlendFunction = backend::BlendFunction;
|
||||
using StencilFunction = backend::SamplerCompareFunc;
|
||||
using StencilOperation = backend::StencilOperation;
|
||||
|
||||
RasterState() noexcept { // NOLINT
|
||||
static_assert(sizeof(RasterState) == sizeof(uint32_t),
|
||||
static_assert(sizeof(RasterState) == sizeof(uint64_t),
|
||||
"RasterState size not what was intended");
|
||||
culling = CullingMode::BACK;
|
||||
blendEquationRGB = BlendEquation::ADD;
|
||||
@@ -829,6 +841,10 @@ struct RasterState {
|
||||
blendFunctionSrcAlpha = BlendFunction::ONE;
|
||||
blendFunctionDstRGB = BlendFunction::ZERO;
|
||||
blendFunctionDstAlpha = BlendFunction::ZERO;
|
||||
stencilFunc = StencilFunction::A;
|
||||
stencilOpStencilFail = StencilOperation::KEEP;
|
||||
stencilOpDepthFail = StencilOperation::KEEP;
|
||||
stencilOpDepthStencilPass = StencilOperation::KEEP;
|
||||
}
|
||||
|
||||
bool operator == (RasterState rhs) const noexcept { return u == rhs.u; }
|
||||
@@ -857,40 +873,56 @@ struct RasterState {
|
||||
union {
|
||||
struct {
|
||||
//! culling mode
|
||||
CullingMode culling : 2; // 2
|
||||
CullingMode culling : 2; // 2
|
||||
|
||||
//! blend equation for the red, green and blue components
|
||||
BlendEquation blendEquationRGB : 3; // 5
|
||||
BlendEquation blendEquationRGB : 3; // 5
|
||||
//! blend equation for the alpha component
|
||||
BlendEquation blendEquationAlpha : 3; // 8
|
||||
BlendEquation blendEquationAlpha : 3; // 8
|
||||
|
||||
//! blending function for the source color
|
||||
BlendFunction blendFunctionSrcRGB : 4; // 12
|
||||
BlendFunction blendFunctionSrcRGB : 4; // 12
|
||||
//! blending function for the source alpha
|
||||
BlendFunction blendFunctionSrcAlpha : 4; // 16
|
||||
BlendFunction blendFunctionSrcAlpha : 4; // 16
|
||||
//! blending function for the destination color
|
||||
BlendFunction blendFunctionDstRGB : 4; // 20
|
||||
BlendFunction blendFunctionDstRGB : 4; // 20
|
||||
//! blending function for the destination alpha
|
||||
BlendFunction blendFunctionDstAlpha : 4; // 24
|
||||
BlendFunction blendFunctionDstAlpha : 4; // 24
|
||||
|
||||
//! Whether depth-buffer writes are enabled
|
||||
bool depthWrite : 1; // 25
|
||||
bool depthWrite : 1; // 25
|
||||
//! Depth test function
|
||||
DepthFunc depthFunc : 3; // 28
|
||||
DepthFunc depthFunc : 3; // 28
|
||||
|
||||
//! Whether color-buffer writes are enabled
|
||||
bool colorWrite : 1; // 29
|
||||
bool colorWrite : 1; // 29
|
||||
|
||||
//! use alpha-channel as coverage mask for anti-aliasing
|
||||
bool alphaToCoverage : 1; // 30
|
||||
bool alphaToCoverage : 1; // 30
|
||||
|
||||
//! whether front face winding direction must be inverted
|
||||
bool inverseFrontFaces : 1; // 31
|
||||
bool inverseFrontFaces : 1; // 31
|
||||
|
||||
//! Whether stencil-buffer writes are enabled
|
||||
bool stencilWrite : 1; // 32
|
||||
//! Stencil reference value
|
||||
uint8_t stencilRef : 8; // 40
|
||||
//! Stencil test function
|
||||
StencilFunction stencilFunc : 3; // 43
|
||||
//! Stencil operation when stencil test fails
|
||||
StencilOperation stencilOpStencilFail : 3; // 46
|
||||
//! padding, must be 0
|
||||
uint8_t padding : 1; // 32
|
||||
uint8_t padding0 : 2; // 48
|
||||
//! Stencil operation when stencil test passes but depth test fails
|
||||
StencilOperation stencilOpDepthFail : 3; // 51
|
||||
//! Stencil operation when both stencil and depth test pass
|
||||
StencilOperation stencilOpDepthStencilPass : 3; // 54
|
||||
//! padding, must be 0
|
||||
uint8_t padding1 : 2; // 56
|
||||
//! padding, must be 0
|
||||
uint8_t padding2 : 8; // 64
|
||||
};
|
||||
uint32_t u = 0;
|
||||
uint64_t u = 0;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -913,7 +945,7 @@ struct ShaderStageFlags {
|
||||
(fragment && type == ShaderType::FRAGMENT);
|
||||
}
|
||||
};
|
||||
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { .vertex = true, .fragment = true };
|
||||
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { true, true };
|
||||
|
||||
/**
|
||||
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ThreadUtils.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <thread>
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Command debugging off. debugging virtuals are not called.
|
||||
|
||||
@@ -217,7 +217,14 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, importTexture,
|
||||
DECL_DRIVER_API_R_N(backend::SamplerGroupHandle, createSamplerGroup,
|
||||
uint32_t, size)
|
||||
|
||||
DECL_DRIVER_API_R_0(backend::RenderPrimitiveHandle, createRenderPrimitive)
|
||||
DECL_DRIVER_API_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
|
||||
backend::VertexBufferHandle, vbh,
|
||||
backend::IndexBufferHandle, ibh,
|
||||
backend::PrimitiveType, pt,
|
||||
uint32_t, offset,
|
||||
uint32_t, minIndex,
|
||||
uint32_t, maxIndex,
|
||||
uint32_t, count)
|
||||
|
||||
DECL_DRIVER_API_R_N(backend::ProgramHandle, createProgram,
|
||||
backend::Program&&, program)
|
||||
@@ -246,11 +253,6 @@ DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
|
||||
uint32_t, height,
|
||||
uint64_t, flags)
|
||||
|
||||
DECL_DRIVER_API_R_N(backend::StreamHandle, createStreamFromTextureId,
|
||||
intptr_t, externalTextureId,
|
||||
uint32_t, width,
|
||||
uint32_t, height)
|
||||
|
||||
DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
|
||||
|
||||
|
||||
@@ -323,6 +325,14 @@ DECL_DRIVER_API_N(updateBufferObject,
|
||||
backend::BufferDescriptor&&, data,
|
||||
uint32_t, byteOffset)
|
||||
|
||||
DECL_DRIVER_API_N(updateBufferObjectUnsynchronized,
|
||||
backend::BufferObjectHandle, ibh,
|
||||
backend::BufferDescriptor&&, data,
|
||||
uint32_t, byteOffset)
|
||||
|
||||
DECL_DRIVER_API_N(resetBufferObject,
|
||||
backend::BufferObjectHandle, ibh)
|
||||
|
||||
DECL_DRIVER_API_N(updateSamplerGroup,
|
||||
backend::SamplerGroupHandle, ubh,
|
||||
backend::SamplerGroup&&, samplerGroup)
|
||||
@@ -382,19 +392,6 @@ DECL_DRIVER_API_0(endRenderPass)
|
||||
|
||||
DECL_DRIVER_API_0(nextSubpass)
|
||||
|
||||
DECL_DRIVER_API_N(setRenderPrimitiveBuffer,
|
||||
backend::RenderPrimitiveHandle, rph,
|
||||
backend::VertexBufferHandle, vbh,
|
||||
backend::IndexBufferHandle, ibh)
|
||||
|
||||
DECL_DRIVER_API_N(setRenderPrimitiveRange,
|
||||
backend::RenderPrimitiveHandle, rph,
|
||||
backend::PrimitiveType, pt,
|
||||
uint32_t, offset,
|
||||
uint32_t, minIndex,
|
||||
uint32_t, maxIndex,
|
||||
uint32_t, count)
|
||||
|
||||
DECL_DRIVER_API_N(beginTimerQuery,
|
||||
backend::TimerQueryHandle, query)
|
||||
|
||||
@@ -461,14 +458,6 @@ DECL_DRIVER_API_N(readPixels,
|
||||
uint32_t, height,
|
||||
backend::PixelBufferDescriptor&&, data)
|
||||
|
||||
DECL_DRIVER_API_N(readStreamPixels,
|
||||
backend::StreamHandle, sh,
|
||||
uint32_t, x,
|
||||
uint32_t, y,
|
||||
uint32_t, width,
|
||||
uint32_t, height,
|
||||
backend::PixelBufferDescriptor&&, data)
|
||||
|
||||
/*
|
||||
* Rendering operations
|
||||
* --------------------
|
||||
|
||||
@@ -82,15 +82,6 @@ public:
|
||||
virtual void detach(Stream* stream) noexcept = 0;
|
||||
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept = 0;
|
||||
|
||||
// external texture storage
|
||||
virtual ExternalTexture* createExternalTextureStorage() noexcept = 0;
|
||||
|
||||
// this is called synchronously in the application thread (NOT the Driver thread)
|
||||
virtual void reallocateExternalStorage(ExternalTexture* ets,
|
||||
uint32_t w, uint32_t h, TextureFormat format) noexcept = 0;
|
||||
|
||||
virtual void destroyExternalTextureStorage(ExternalTexture* ets) noexcept = 0;
|
||||
|
||||
// The method allows platforms to convert a user-supplied external image object into a new type
|
||||
// (e.g. HardwareBuffer => EGLImage). It makes sense for the default implementation to do nothing.
|
||||
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept { return source; }
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)>&& logger);
|
||||
|
||||
// sets one of the program's shader (e.g. vertex, fragment)
|
||||
// string-based shaders are null terminated, consequently the size parameter must include the
|
||||
// null terminating character.
|
||||
Program& shader(Shader shader, void const* data, size_t size) noexcept;
|
||||
|
||||
// sets the 'bindingPoint' uniform block's name for this program.
|
||||
@@ -84,10 +86,14 @@ public:
|
||||
Program& setSamplerGroup(size_t bindingPoint, ShaderStageFlags stageFlags,
|
||||
Sampler const* samplers, size_t count) noexcept;
|
||||
|
||||
// string-based shaders are null terminated, consequently the size parameter must include the
|
||||
// null terminating character.
|
||||
Program& withVertexShader(void const* data, size_t size) {
|
||||
return shader(Shader::VERTEX, data, size);
|
||||
}
|
||||
|
||||
// string-based shaders are null terminated, consequently the size parameter must include the
|
||||
// null terminating character.
|
||||
Program& withFragmentShader(void const* data, size_t size) {
|
||||
return shader(Shader::FRAGMENT, data, size);
|
||||
}
|
||||
|
||||
@@ -17,17 +17,18 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
|
||||
|
||||
#include <array>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/bitset.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class SamplerGroup {
|
||||
public:
|
||||
@@ -151,7 +152,6 @@ private:
|
||||
mutable utils::bitset32 mDirty;
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
|
||||
|
||||
@@ -58,26 +58,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a 4-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
|
||||
// Converts a n-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
|
||||
template<typename dstComponentType, typename srcComponentType>
|
||||
static void reshapeImage(uint8_t* dest, const uint8_t* src, size_t srcBytesPerRow,
|
||||
size_t dstBytesPerRow, size_t dstChannelCount, size_t height, bool swizzle, bool flip) {
|
||||
const size_t srcChannelCount = 4;
|
||||
size_t srcChannelCount, size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t width, size_t height, bool swizzle) {
|
||||
const dstComponentType dstMaxValue = getMaxValue<dstComponentType>();
|
||||
const srcComponentType srcMaxValue = getMaxValue<srcComponentType>();
|
||||
const size_t width = (srcBytesPerRow / sizeof(srcComponentType)) / srcChannelCount;
|
||||
const size_t minChannelCount = filament::math::min(srcChannelCount, dstChannelCount);
|
||||
assert_invariant(minChannelCount <= 4);
|
||||
const int inds[4] = {swizzle ? 2 : 0, 1, swizzle ? 0 : 2, 3};
|
||||
|
||||
int srcStride;
|
||||
if (flip) {
|
||||
src += srcBytesPerRow * (height - 1);
|
||||
srcStride = -srcBytesPerRow;
|
||||
} else {
|
||||
srcStride = srcBytesPerRow;
|
||||
}
|
||||
|
||||
for (size_t row = 0; row < height; ++row) {
|
||||
const srcComponentType* in = (const srcComponentType*) src;
|
||||
dstComponentType* out = (dstComponentType*) dest;
|
||||
@@ -97,15 +87,15 @@ public:
|
||||
in += srcChannelCount;
|
||||
out += dstChannelCount;
|
||||
}
|
||||
src += srcStride;
|
||||
src += srcBytesPerRow;
|
||||
dest += dstBytesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a 4-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
|
||||
// Converts a n-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
|
||||
static bool reshapeImage(PixelBufferDescriptor* dst, PixelDataType srcType,
|
||||
const uint8_t* srcBytes, int srcBytesPerRow, int width, int height, bool swizzle,
|
||||
bool flip) {
|
||||
uint32_t srcChannelCount, const uint8_t* srcBytes, int srcBytesPerRow, int width,
|
||||
int height, bool swizzle) {
|
||||
size_t dstChannelCount;
|
||||
switch (dst->format) {
|
||||
case PixelDataFormat::R_INTEGER: dstChannelCount = 1; break;
|
||||
@@ -118,8 +108,9 @@ public:
|
||||
case PixelDataFormat::RGBA: dstChannelCount = 4; break;
|
||||
default: return false;
|
||||
}
|
||||
void (*reshaper)(uint8_t*, const uint8_t*, size_t, size_t, size_t, size_t, bool, bool)
|
||||
= nullptr;
|
||||
void (*reshaper)(uint8_t* dest, const uint8_t* src, size_t srcBytesPerRow,
|
||||
size_t srcChannelCount, size_t dstBytesPerRow, size_t dstChannelCount,
|
||||
size_t width, size_t height, bool swizzle) = nullptr;
|
||||
constexpr auto UBYTE = PixelDataType::UBYTE, FLOAT = PixelDataType::FLOAT,
|
||||
UINT = PixelDataType::UINT, INT = PixelDataType::INT;
|
||||
switch (dst->type) {
|
||||
@@ -165,11 +156,10 @@ public:
|
||||
uint8_t* dstBytes = (uint8_t*) dst->buffer;
|
||||
const int dstBytesPerRow = PixelBufferDescriptor::computeDataSize(dst->format, dst->type,
|
||||
dst->stride ? dst->stride : width, 1, dst->alignment);
|
||||
reshaper(dstBytes, srcBytes, srcBytesPerRow, dstBytesPerRow, dstChannelCount, height,
|
||||
swizzle, flip);
|
||||
reshaper(dstBytes, srcBytes, srcBytesPerRow, srcChannelCount, dstBytesPerRow,
|
||||
dstChannelCount, width, height, swizzle);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<> inline float getMaxValue() { return 1.0f; }
|
||||
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "ExternalTextureManagerAndroid.h"
|
||||
|
||||
#include <utils/api_level.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
template <typename T>
|
||||
static void loadSymbol(T*& pfn, const char *symbol) noexcept {
|
||||
pfn = (T*)dlsym(RTLD_DEFAULT, symbol);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace ndk {
|
||||
/*
|
||||
* This mimics the GraphicBuffer class for pre-API 26
|
||||
*/
|
||||
template<typename NATIVE_TYPE, typename REF>
|
||||
struct ANativeObjectBase : public NATIVE_TYPE, public REF {
|
||||
};
|
||||
|
||||
struct android_native_base_t {
|
||||
unsigned int magic;
|
||||
unsigned int version;
|
||||
void* reserved[4];
|
||||
void (* incRef)(struct android_native_base_t* base);
|
||||
void (* decRef)(struct android_native_base_t* base);
|
||||
};
|
||||
|
||||
struct ANativeWindowBuffer {
|
||||
struct android_native_base_t common;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned int stride;
|
||||
unsigned int format;
|
||||
unsigned int usage_deprecated;
|
||||
uintptr_t layerCount;
|
||||
void* reserved[1];
|
||||
const void* handle;
|
||||
uint64_t usage;
|
||||
void* reserved_proc[8 - (sizeof(uint64_t) / sizeof(void*))];
|
||||
};
|
||||
|
||||
struct RefBase {
|
||||
virtual ~RefBase() = default;
|
||||
void* ref;
|
||||
};
|
||||
|
||||
struct GraphicBuffer : public ANativeObjectBase<ANativeWindowBuffer, RefBase> {
|
||||
};
|
||||
struct GraphicBufferWrapper {
|
||||
GraphicBuffer* graphicBuffer;
|
||||
};
|
||||
} // namespace ndk
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
using namespace ndk;
|
||||
|
||||
struct EGLExternalTexture : public ExternalTextureManagerAndroid::ExternalTexture {
|
||||
GraphicBufferWrapper* graphicBufferWrapper = nullptr;
|
||||
};
|
||||
|
||||
ExternalTextureManagerAndroid& ExternalTextureManagerAndroid::create() noexcept {
|
||||
return *(new ExternalTextureManagerAndroid{});
|
||||
}
|
||||
|
||||
void ExternalTextureManagerAndroid::destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept {
|
||||
delete pExternalTextureManager;
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
ExternalTextureManagerAndroid::ExternalTextureManagerAndroid() noexcept
|
||||
: mVm(VirtualMachineEnv::get()) {
|
||||
}
|
||||
|
||||
// not quite sure on which thread this is going to be called
|
||||
ExternalTextureManagerAndroid::~ExternalTextureManagerAndroid() noexcept {
|
||||
if (__builtin_available(android 26, *)) {
|
||||
} else {
|
||||
if (mGraphicBufferClass) {
|
||||
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
|
||||
if (env) {
|
||||
env->DeleteGlobalRef(mGraphicBufferClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
Platform::ExternalTexture* ExternalTextureManagerAndroid::createExternalTexture() noexcept {
|
||||
if (__builtin_available(android 26, *)) {
|
||||
} else {
|
||||
// initialize java stuff on-demand
|
||||
if (!mGraphicBufferClass) {
|
||||
JNIEnv* env = mVm.getEnvironment();
|
||||
mGraphicBufferClass = env->FindClass("android/view/GraphicBuffer");
|
||||
mGraphicBuffer_nCreateGraphicBuffer = env->GetStaticMethodID(
|
||||
mGraphicBufferClass, "nCreateGraphicBuffer", "(IIII)J");
|
||||
mGraphicBuffer_nDestroyGraphicBuffer = env->GetStaticMethodID(
|
||||
mGraphicBufferClass, "nDestroyGraphicBuffer", "(J)V");
|
||||
|
||||
mGraphicBufferClass = static_cast<jclass>(env->NewGlobalRef(mGraphicBufferClass));
|
||||
}
|
||||
}
|
||||
EGLExternalTexture* ets = new EGLExternalTexture;
|
||||
return ets;
|
||||
}
|
||||
|
||||
// called on app thread
|
||||
void ExternalTextureManagerAndroid::reallocate(
|
||||
Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
|
||||
TextureFormat format, uint64_t usage) noexcept {
|
||||
destroyStorage(ets);
|
||||
alloc(ets, w, h, format, usage);
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
void ExternalTextureManagerAndroid::destroy(Platform::ExternalTexture* ets) noexcept {
|
||||
destroyStorage(ets);
|
||||
delete static_cast<EGLExternalTexture*>(ets);
|
||||
}
|
||||
|
||||
// called on app thread
|
||||
void ExternalTextureManagerAndroid::alloc(
|
||||
Platform::ExternalTexture* t,
|
||||
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept {
|
||||
|
||||
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
|
||||
|
||||
AHardwareBuffer_Desc desc = { w, h, 1, 0, usage, 0, 0, 0 };
|
||||
switch (format) {
|
||||
case TextureFormat::RGB8:
|
||||
// don't use R8G8B8 here because some drivers produce garbled images
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGBA8:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGB565:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
|
||||
break;
|
||||
case TextureFormat::RGB10_A2:
|
||||
desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
|
||||
break;
|
||||
default:
|
||||
slog.e << "Unsupported format " << (int)format << ", use RGBA8 or RGB8 only."
|
||||
<< io::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (__builtin_available(android 26, *)) {
|
||||
// allocate new storage...
|
||||
AHardwareBuffer* buffer = nullptr;
|
||||
if (AHardwareBuffer_allocate(&desc, &buffer) < 0) {
|
||||
slog.e << "AHardwareBuffer_allocate() failed" << io::endl;
|
||||
return;
|
||||
}
|
||||
ets->hardwareBuffer = buffer;
|
||||
} else {
|
||||
// note: This is called on the application thread (not the GL thread)
|
||||
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
|
||||
if (!env) {
|
||||
return; // this should not happen
|
||||
}
|
||||
|
||||
jlong graphicBufferWrapperJni = env->CallStaticLongMethod(mGraphicBufferClass,
|
||||
mGraphicBuffer_nCreateGraphicBuffer, w, h, desc.format, usage);
|
||||
VirtualMachineEnv::handleException(env);
|
||||
|
||||
if (graphicBufferWrapperJni) {
|
||||
GraphicBuffer* const gb = ((GraphicBufferWrapper*)graphicBufferWrapperJni)->graphicBuffer;
|
||||
ets->graphicBufferWrapper = (GraphicBufferWrapper*)graphicBufferWrapperJni;
|
||||
ets->clientBuffer = static_cast<ANativeWindowBuffer*>(gb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called on gl thread
|
||||
void ExternalTextureManagerAndroid::destroyStorage(Platform::ExternalTexture* t) noexcept {
|
||||
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
|
||||
if (__builtin_available(android 26, *)) {
|
||||
// destroy the current storage if any
|
||||
if (ets->hardwareBuffer) {
|
||||
AHardwareBuffer_release(ets->hardwareBuffer);
|
||||
ets->hardwareBuffer = nullptr;
|
||||
}
|
||||
} else {
|
||||
if (ets->graphicBufferWrapper) {
|
||||
JNIEnv* env = VirtualMachineEnv::get().getEnvironment();
|
||||
env->CallStaticVoidMethod(mGraphicBufferClass,
|
||||
mGraphicBuffer_nDestroyGraphicBuffer, (jlong)ets->graphicBufferWrapper);
|
||||
VirtualMachineEnv::handleException(env);
|
||||
ets->graphicBufferWrapper = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
#define TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <android/api-level.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
/*
|
||||
* ExternalTextureManagerAndroid::ExternalTexture is basically a wrapper for AHardwareBuffer.
|
||||
*
|
||||
* This class doesn't rely on GL or EGL, and could be used for other Android platform if needed
|
||||
* (e.g. Vulkan).
|
||||
*
|
||||
* ExternalTextureManagerAndroid handle allocation/destruction using either Java or the NDK,
|
||||
* whichever is available.
|
||||
*/
|
||||
class ExternalTextureManagerAndroid {
|
||||
public:
|
||||
|
||||
struct ExternalTexture : public Platform::ExternalTexture {
|
||||
void* clientBuffer = nullptr;
|
||||
AHardwareBuffer* hardwareBuffer = nullptr;
|
||||
};
|
||||
|
||||
// must be called on backend thread
|
||||
static ExternalTextureManagerAndroid& create() noexcept;
|
||||
|
||||
// must be called on backend thread
|
||||
static void destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept;
|
||||
|
||||
// must be called on backend thread (only because we don't synchronize
|
||||
Platform::ExternalTexture* createExternalTexture() noexcept;
|
||||
|
||||
// called on app thread
|
||||
void reallocate(
|
||||
Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
|
||||
TextureFormat format, uint64_t usage) noexcept;
|
||||
|
||||
// must be called on backend thread
|
||||
void destroy(Platform::ExternalTexture* ets) noexcept;
|
||||
|
||||
private:
|
||||
ExternalTextureManagerAndroid() noexcept;
|
||||
~ExternalTextureManagerAndroid() noexcept;
|
||||
|
||||
// called on app thread
|
||||
void alloc(Platform::ExternalTexture* ets,
|
||||
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept;
|
||||
|
||||
// called on gl thread
|
||||
void destroyStorage(Platform::ExternalTexture* ets) noexcept;
|
||||
|
||||
VirtualMachineEnv& mVm;
|
||||
|
||||
jclass mGraphicBufferClass = nullptr;
|
||||
jmethodID mGraphicBuffer_nCreateGraphicBuffer = nullptr;
|
||||
jmethodID mGraphicBuffer_nDestroyGraphicBuffer = nullptr;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H
|
||||
@@ -42,7 +42,8 @@ public:
|
||||
* Update the buffer with data inside src. Potentially allocates a new buffer allocation to hold
|
||||
* the bytes which will be released when the current frame is finished.
|
||||
*/
|
||||
void copyIntoBuffer(void* src, size_t size, size_t byteOffset = 0);
|
||||
void copyIntoBuffer(void* src, size_t size, size_t byteOffset);
|
||||
void copyIntoBufferUnsynchronized(void* src, size_t size, size_t byteOffset);
|
||||
|
||||
/**
|
||||
* Denotes that this buffer is used for a draw call ensuring that its allocation remains valid
|
||||
@@ -57,12 +58,6 @@ public:
|
||||
*/
|
||||
id<MTLBuffer> getGpuBufferForDraw(id<MTLCommandBuffer> cmdBuffer) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the offset into the buffer returned by getGpuBufferForDraw. This is always 0 for
|
||||
* non-STREAM buffers.
|
||||
*/
|
||||
size_t getGpuBufferStreamOffset() noexcept { return mCurrentStreamStart; }
|
||||
|
||||
void* getCpuBuffer() const noexcept { return mCpuBuffer; }
|
||||
|
||||
enum Stage {
|
||||
@@ -84,13 +79,9 @@ private:
|
||||
|
||||
BufferUsage mUsage;
|
||||
size_t mBufferSize = 0;
|
||||
size_t mCurrentStreamStart = 0;
|
||||
size_t mCurrentStreamEnd = 0;
|
||||
const MetalBufferPoolEntry* mBufferPoolEntry = nullptr;
|
||||
void* mCpuBuffer = nullptr;
|
||||
MetalContext& mContext;
|
||||
|
||||
void copyIntoStreamBuffer(void* src, size_t size);
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
|
||||
@@ -28,11 +28,6 @@ MetalBuffer::MetalBuffer(MetalContext& context, BufferUsage usage, size_t size,
|
||||
// If the buffer is less than 4K in size and is updated frequently, we don't use an explicit
|
||||
// buffer. Instead, we use immediate command encoder methods like setVertexBytes:length:atIndex:.
|
||||
if (size <= 4 * 1024) {
|
||||
// We'll take the same approach for STREAM buffers under 4K.
|
||||
if (usage == BufferUsage::STREAM) {
|
||||
usage = BufferUsage::DYNAMIC;
|
||||
}
|
||||
|
||||
if (usage == BufferUsage::DYNAMIC && !forceGpuBuffer) {
|
||||
mBufferPoolEntry = nullptr;
|
||||
mCpuBuffer = malloc(size);
|
||||
@@ -61,13 +56,6 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
|
||||
"Attempting to copy %d bytes into a buffer of size %d at offset %d",
|
||||
size, mBufferSize, byteOffset);
|
||||
|
||||
if (mUsage == BufferUsage::STREAM) {
|
||||
// byteOffset must be 0 for STREAM buffers.
|
||||
assert_invariant(byteOffset == 0);
|
||||
copyIntoStreamBuffer(src, size);
|
||||
return;
|
||||
}
|
||||
|
||||
// Either copy into the Metal buffer or into our cpu buffer.
|
||||
if (mCpuBuffer) {
|
||||
memcpy(static_cast<uint8_t*>(mCpuBuffer) + byteOffset, src, size);
|
||||
@@ -84,32 +72,9 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
|
||||
memcpy(static_cast<uint8_t*>(mBufferPoolEntry->buffer.contents) + byteOffset, src, size);
|
||||
}
|
||||
|
||||
void MetalBuffer::copyIntoStreamBuffer(void* src, size_t size) {
|
||||
// Stream buffers are handled a bit differently. In STREAM mode, we have a single large buffer.
|
||||
// At each update we "advance" into the buffer, keeping track of the where we're at, and bind
|
||||
// the buffer at that location. Effectively, "byteOffset" is managed automatically.
|
||||
|
||||
assert_invariant(size <= mBufferSize);
|
||||
assert_invariant(!mCpuBuffer);
|
||||
|
||||
mCurrentStreamStart = mCurrentStreamEnd;
|
||||
mCurrentStreamEnd += size;
|
||||
|
||||
if (mCurrentStreamEnd > mBufferSize) {
|
||||
// Allocate a new buffer and reset the stream offset.
|
||||
mCurrentStreamStart = 0;
|
||||
mCurrentStreamEnd = size;
|
||||
|
||||
if (mBufferPoolEntry) { mContext.bufferPool->releaseBuffer(mBufferPoolEntry); }
|
||||
mBufferPoolEntry = mContext.bufferPool->acquireBuffer(mBufferSize);
|
||||
}
|
||||
|
||||
// Lazily acquire a new buffer if we haven't already.
|
||||
if (!mBufferPoolEntry) {
|
||||
mBufferPoolEntry = mContext.bufferPool->acquireBuffer(mBufferSize);
|
||||
}
|
||||
|
||||
memcpy(static_cast<uint8_t*>(mBufferPoolEntry->buffer.contents) + mCurrentStreamStart, src, size);
|
||||
void MetalBuffer::copyIntoBufferUnsynchronized(void* src, size_t size, size_t byteOffset) {
|
||||
// TODO: implement the unsynchronized version
|
||||
copyIntoBuffer(src, size, byteOffset);
|
||||
}
|
||||
|
||||
id<MTLBuffer> MetalBuffer::getGpuBufferForDraw(id<MTLCommandBuffer> cmdBuffer) noexcept {
|
||||
@@ -163,7 +128,7 @@ void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLRenderComman
|
||||
continue;
|
||||
}
|
||||
metalBuffers[b] = gpuBuffer;
|
||||
metalOffsets[b] = offsets[b] + buffer->mCurrentStreamStart;
|
||||
metalOffsets[b] = offsets[b];
|
||||
}
|
||||
|
||||
if (stages & Stage::VERTEX) {
|
||||
|
||||
@@ -118,6 +118,12 @@ private:
|
||||
mHandleAllocator.deallocate(handle, p);
|
||||
}
|
||||
|
||||
inline void setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph,
|
||||
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh);
|
||||
|
||||
inline void setRenderPrimitiveRange(Handle<HwRenderPrimitive> rph, PrimitiveType pt,
|
||||
uint32_t offset, uint32_t minIndex, uint32_t maxIndex, uint32_t count);
|
||||
|
||||
void enumerateSamplerGroups(const MetalProgram* program, ShaderType shaderType,
|
||||
const std::function<void(const SamplerGroup::Sampler*, size_t)>& f);
|
||||
void enumerateBoundUniformBuffers(const std::function<void(const UniformBufferState&,
|
||||
|
||||
@@ -262,10 +262,6 @@ void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
|
||||
ASSERT_PRECONDITION(metalTexture.mipmapLevelCount == levels,
|
||||
"Imported id<MTLTexture> levels (%d) != Filament texture levels (%d)",
|
||||
metalTexture.mipmapLevelCount, levels);
|
||||
MTLPixelFormat filamentMetalFormat = getMetalFormat(mContext, format);
|
||||
ASSERT_PRECONDITION(metalTexture.pixelFormat == filamentMetalFormat,
|
||||
"Imported id<MTLTexture> format (%d) != Filament texture format (%d)",
|
||||
metalTexture.pixelFormat, filamentMetalFormat);
|
||||
MTLTextureType filamentMetalType = getMetalType(target);
|
||||
ASSERT_PRECONDITION(metalTexture.textureType == filamentMetalType,
|
||||
"Imported id<MTLTexture> type (%d) != Filament texture type (%d)",
|
||||
@@ -278,8 +274,13 @@ void MetalDriver::createSamplerGroupR(Handle<HwSamplerGroup> sbh, uint32_t size)
|
||||
mContext->samplerGroups.insert(construct_handle<MetalSamplerGroup>(sbh, size));
|
||||
}
|
||||
|
||||
void MetalDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph, int dummy) {
|
||||
void MetalDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph,
|
||||
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh,
|
||||
PrimitiveType pt, uint32_t offset,
|
||||
uint32_t minIndex, uint32_t maxIndex, uint32_t count) {
|
||||
construct_handle<MetalRenderPrimitive>(rph);
|
||||
MetalDriver::setRenderPrimitiveBuffer(rph, vbh, ibh);
|
||||
MetalDriver::setRenderPrimitiveRange(rph, pt, offset, minIndex, maxIndex, count);
|
||||
}
|
||||
|
||||
void MetalDriver::createProgramR(Handle<HwProgram> rph, Program&& program) {
|
||||
@@ -359,10 +360,6 @@ void MetalDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
|
||||
construct_handle<MetalSwapChain>(sch, *mContext, width, height, flags);
|
||||
}
|
||||
|
||||
void MetalDriver::createStreamFromTextureIdR(Handle<HwStream>, intptr_t externalTextureId,
|
||||
uint32_t width, uint32_t height) {
|
||||
}
|
||||
|
||||
void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
|
||||
// nothing to do, timer query was constructed in createTimerQueryS
|
||||
}
|
||||
@@ -431,10 +428,6 @@ Handle<HwSwapChain> MetalDriver::createSwapChainHeadlessS() noexcept {
|
||||
return alloc_handle<MetalSwapChain>();
|
||||
}
|
||||
|
||||
Handle<HwStream> MetalDriver::createStreamFromTextureIdS() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
Handle<HwTimerQuery> MetalDriver::createTimerQueryS() noexcept {
|
||||
// The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen
|
||||
// before createTimerQueryR is executed.
|
||||
@@ -711,6 +704,22 @@ void MetalDriver::updateBufferObject(Handle<HwBufferObject> boh, BufferDescripto
|
||||
scheduleDestroy(std::move(data));
|
||||
}
|
||||
|
||||
void MetalDriver::updateBufferObjectUnsynchronized(Handle<HwBufferObject> boh,
|
||||
BufferDescriptor&& data, uint32_t byteOffset) {
|
||||
auto* bo = handle_cast<MetalBufferObject>(boh);
|
||||
bo->updateBufferUnsynchronized(data.buffer, data.size, byteOffset);
|
||||
scheduleDestroy(std::move(data));
|
||||
}
|
||||
|
||||
void MetalDriver::resetBufferObject(Handle<HwBufferObject> boh) {
|
||||
// TODO: implement resetBufferObject(). This is equivalent to calling
|
||||
// destroyBufferObject() followed by createBufferObject() keeping the same handle.
|
||||
// It is actually okay to keep a no-op implementation, the intention here is to "orphan" the
|
||||
// buffer (and possibly return it to a pool) and allocate a new one (or get it from a pool),
|
||||
// so that no further synchronization with the GPU is needed.
|
||||
// This is only useful if updateBufferObjectUnsynchronized() is implemented unsynchronizedly.
|
||||
}
|
||||
|
||||
void MetalDriver::setVertexBufferObject(Handle<HwVertexBuffer> vbh, uint32_t index,
|
||||
Handle<HwBufferObject> boh) {
|
||||
auto* vertexBuffer = handle_cast<MetalVertexBuffer>(vbh);
|
||||
@@ -1053,11 +1062,6 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
|
||||
}];
|
||||
}
|
||||
|
||||
void MetalDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
|
||||
uint32_t height, PixelBufferDescriptor&& data) {
|
||||
|
||||
}
|
||||
|
||||
void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
Handle<HwRenderTarget> dst, Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, Viewport srcRect,
|
||||
@@ -1081,33 +1085,13 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
dstRect.left >= 0 && dstRect.bottom >= 0,
|
||||
"Source and destination rects must be positive.");
|
||||
|
||||
// Metal's texture coordinates have (0, 0) at the top-left of the texture, but Filament's
|
||||
// coordinates have (0, 0) at bottom-left.
|
||||
const NSInteger srcHeight =
|
||||
srcTarget->isDefaultRenderTarget() ?
|
||||
mContext->currentReadSwapChain->getSurfaceHeight() : srcTarget->height;
|
||||
MTLRegion srcRegion = MTLRegionMake2D(
|
||||
(NSUInteger) srcRect.left,
|
||||
srcHeight - (NSUInteger) srcRect.bottom - srcRect.height,
|
||||
srcRect.width, srcRect.height);
|
||||
|
||||
const NSInteger dstHeight =
|
||||
dstTarget->isDefaultRenderTarget() ?
|
||||
mContext->currentDrawSwapChain->getSurfaceHeight() : dstTarget->height;
|
||||
MTLRegion dstRegion = MTLRegionMake2D(
|
||||
(NSUInteger) dstRect.left,
|
||||
dstHeight - (NSUInteger) dstRect.bottom - dstRect.height,
|
||||
dstRect.width, dstRect.height);
|
||||
|
||||
auto isBlitableTextureType = [](MTLTextureType t) {
|
||||
return t == MTLTextureType2D || t == MTLTextureType2DMultisample ||
|
||||
t == MTLTextureType2DArray;
|
||||
};
|
||||
|
||||
MetalBlitter::BlitArgs args;
|
||||
args.filter = filter;
|
||||
args.source.region = srcRegion;
|
||||
args.destination.region = dstRegion;
|
||||
// MetalBlitter supports blitting color and depth simultaneously, but for simplicitly we'll blit
|
||||
// them separately. In practice, Filament only ever blits a single buffer at a time anyway.
|
||||
|
||||
if (any(buffers & TargetBufferFlags::COLOR_ALL)) {
|
||||
// We always blit from/to the COLOR0 attachment.
|
||||
@@ -1119,12 +1103,17 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
isBlitableTextureType(dstColorAttachment.getTexture().textureType),
|
||||
"Metal does not support blitting to/from non-2D textures.");
|
||||
|
||||
MetalBlitter::BlitArgs args;
|
||||
args.filter = filter;
|
||||
args.source.region = srcColorAttachment.getRegionFromClientRect(srcRect);
|
||||
args.destination.region = dstColorAttachment.getRegionFromClientRect(dstRect);
|
||||
args.source.color = srcColorAttachment.getTexture();
|
||||
args.destination.color = dstColorAttachment.getTexture();
|
||||
args.source.level = srcColorAttachment.level;
|
||||
args.destination.level = dstColorAttachment.level;
|
||||
args.source.slice = srcColorAttachment.layer;
|
||||
args.destination.slice = dstColorAttachment.layer;
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1137,34 +1126,19 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
isBlitableTextureType(dstDepthAttachment.getTexture().textureType),
|
||||
"Metal does not support blitting to/from non-2D textures.");
|
||||
|
||||
MetalBlitter::BlitArgs args;
|
||||
args.filter = filter;
|
||||
args.source.region = srcDepthAttachment.getRegionFromClientRect(srcRect);
|
||||
args.destination.region = dstDepthAttachment.getRegionFromClientRect(dstRect);
|
||||
args.source.depth = srcDepthAttachment.getTexture();
|
||||
args.destination.depth = dstDepthAttachment.getTexture();
|
||||
|
||||
if (args.blitColor()) {
|
||||
// If blitting color, we've already set the source and destination levels and slices.
|
||||
// Check that they match the requested depth levels/slices.
|
||||
ASSERT_PRECONDITION(args.source.level == srcDepthAttachment.level,
|
||||
"Color and depth source LOD must match. (%d != %d)",
|
||||
args.source.level, srcDepthAttachment.level);
|
||||
ASSERT_PRECONDITION(args.destination.level == dstDepthAttachment.level,
|
||||
"Color and depth destination LOD must match. (%d != %d)",
|
||||
args.destination.level, dstDepthAttachment.level);
|
||||
ASSERT_PRECONDITION(args.source.slice == srcDepthAttachment.layer,
|
||||
"Color and depth source layer must match. (%d != %d)",
|
||||
args.source.slice, srcDepthAttachment.layer);
|
||||
ASSERT_PRECONDITION(args.destination.slice == dstDepthAttachment.layer,
|
||||
"Color and depth destination layer must match. (%d != %d)",
|
||||
args.destination.slice, dstDepthAttachment.layer);
|
||||
}
|
||||
|
||||
args.source.level = srcDepthAttachment.level;
|
||||
args.destination.level = dstDepthAttachment.level;
|
||||
args.source.slice = srcDepthAttachment.layer;
|
||||
args.destination.slice = dstDepthAttachment.layer;
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
}
|
||||
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
|
||||
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
|
||||
@@ -1415,12 +1389,11 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
|
||||
|
||||
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(mContext);
|
||||
id<MTLBuffer> metalIndexBuffer = indexBuffer->buffer.getGpuBufferForDraw(cmdBuffer);
|
||||
size_t offset = indexBuffer->buffer.getGpuBufferStreamOffset();
|
||||
[mContext->currentRenderPassEncoder drawIndexedPrimitives:getMetalPrimitiveType(primitive->type)
|
||||
indexCount:primitive->count
|
||||
indexType:getIndexType(indexBuffer->elementSize)
|
||||
indexBuffer:metalIndexBuffer
|
||||
indexBufferOffset:primitive->offset + offset
|
||||
indexBufferOffset:primitive->offset
|
||||
instanceCount:instanceCount];
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ private:
|
||||
// These two fields store a callback and user data to notify the client that a frame is ready
|
||||
// for presentation.
|
||||
// If frameScheduledCallback is nullptr, then the Metal backend automatically calls
|
||||
// presentDrawable when the frame is commited.
|
||||
// presentDrawable when the frame is committed.
|
||||
// Otherwise, the Metal backend will not automatically present the frame. Instead, clients bear
|
||||
// the responsibility of presenting the frame by calling the PresentCallable object.
|
||||
FrameScheduledCallback frameScheduledCallback = nullptr;
|
||||
@@ -117,6 +117,7 @@ public:
|
||||
MetalBufferObject(MetalContext& context, BufferUsage usage, uint32_t byteCount);
|
||||
|
||||
void updateBuffer(void* data, size_t size, uint32_t byteOffset);
|
||||
void updateBufferUnsynchronized(void* data, size_t size, uint32_t byteOffset);
|
||||
MetalBuffer* getBuffer() { return &buffer; }
|
||||
|
||||
// Tracks which uniform buffers this buffer object is bound into.
|
||||
@@ -257,6 +258,16 @@ public:
|
||||
return texture ? texture.pixelFormat : MTLPixelFormatInvalid;
|
||||
}
|
||||
|
||||
MTLRegion getRegionFromClientRect(Viewport rect) {
|
||||
// Convert the Filament rect into Metal texture coordinates, taking into account Metal's
|
||||
// inverted texture space and the mip level. Note that the underlying Texture could be
|
||||
// larger than the RenderTarget. Metal's texture coordinates have (0, 0) at the top-left
|
||||
// of the texture, but Filament's coordinates have (0, 0) at bottom-left.
|
||||
const auto mipheight = texture.height >> level;
|
||||
return MTLRegionMake2D((NSUInteger)rect.left,
|
||||
mipheight - (NSUInteger)rect.bottom - rect.height, rect.width, rect.height);
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return texture != nil;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include <utils/trap.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <math/vec2.h>
|
||||
#include <math/scalar.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace filament {
|
||||
@@ -273,6 +276,10 @@ void MetalBufferObject::updateBuffer(void* data, size_t size, uint32_t byteOffse
|
||||
buffer.copyIntoBuffer(data, size, byteOffset);
|
||||
}
|
||||
|
||||
void MetalBufferObject::updateBufferUnsynchronized(void* data, size_t size, uint32_t byteOffset) {
|
||||
buffer.copyIntoBufferUnsynchronized(data, size, byteOffset);
|
||||
}
|
||||
|
||||
MetalVertexBuffer::MetalVertexBuffer(MetalContext& context, uint8_t bufferCount,
|
||||
uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes)
|
||||
: HwVertexBuffer(bufferCount, attributeCount, vertexCount, attributes), buffers(bufferCount, nullptr) {}
|
||||
@@ -346,8 +353,11 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
|
||||
continue;
|
||||
}
|
||||
|
||||
assert_invariant( source[source.size() - 1] == '\0' );
|
||||
|
||||
// the shader string is null terminated and the length includes the null character
|
||||
NSString* objcSource = [[NSString alloc] initWithBytes:source.data()
|
||||
length:source.size()
|
||||
length:source.size() - 1
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSError* error = nil;
|
||||
// When options is nil, Metal uses the most recent language version available.
|
||||
@@ -367,7 +377,7 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
|
||||
*shaderFunctions[i] = [library newFunctionWithName:@"main0"];
|
||||
}
|
||||
|
||||
// All stages of the program have compiled successfuly, this is a valid program.
|
||||
// All stages of the program have compiled successfully, this is a valid program.
|
||||
isValid = true;
|
||||
|
||||
// This calculates Metal resource binding indices. Filament's sampler bindings range from 0-31
|
||||
@@ -803,6 +813,10 @@ void MetalTexture::updateLodRange(uint32_t level) {
|
||||
MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint32_t height,
|
||||
uint8_t samples, Attachment colorAttachments[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT], Attachment depthAttachment) :
|
||||
HwRenderTarget(width, height), context(context), samples(samples) {
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmin = {std::numeric_limits<size_t>::max()};
|
||||
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmax = {0};
|
||||
UTILS_UNUSED_IN_RELEASE size_t attachmentCount = 0;
|
||||
|
||||
for (size_t i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) {
|
||||
if (!colorAttachments[i]) {
|
||||
continue;
|
||||
@@ -813,6 +827,13 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
|
||||
"MetalRenderTarget was initialized with a MSAA COLOR%d texture, but sample count is %d.",
|
||||
i, samples);
|
||||
|
||||
auto t = color[i].metalTexture;
|
||||
const auto twidth = std::max(1u, t->width >> color[i].level);
|
||||
const auto theight = std::max(1u, t->height >> color[i].level);
|
||||
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
|
||||
tmax = { std::max(tmax.x, twidth), std::max(tmax.y, theight) };
|
||||
attachmentCount++;
|
||||
|
||||
// If we were given a single-sampled texture but the samples parameter is > 1, we create
|
||||
// a multisampled sidecar texture and do a resolve automatically.
|
||||
if (samples > 1 && color[i].getSampleCount() == 1) {
|
||||
@@ -831,6 +852,13 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
|
||||
"MetalRenderTarget was initialized with a MSAA DEPTH texture, but sample count is %d.",
|
||||
samples);
|
||||
|
||||
auto t = depth.metalTexture;
|
||||
const auto twidth = std::max(1u, t->width >> depth.level);
|
||||
const auto theight = std::max(1u, t->height >> depth.level);
|
||||
tmin = { math::min(tmin.x, twidth), math::min(tmin.y, theight) };
|
||||
tmax = { math::max(tmax.x, twidth), math::max(tmax.y, theight) };
|
||||
attachmentCount++;
|
||||
|
||||
// If we were given a single-sampled texture but the samples parameter is > 1, we create
|
||||
// a multisampled sidecar texture and do a resolve automatically.
|
||||
if (samples > 1 && depth.getSampleCount() == 1) {
|
||||
@@ -841,6 +869,10 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that all attachments have the same dimensions.
|
||||
assert_invariant(attachmentCount > 0);
|
||||
assert_invariant(tmin == tmax);
|
||||
}
|
||||
|
||||
void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* descriptor,
|
||||
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
};
|
||||
|
||||
// StateTracker keeps track of state changes made to a Metal command encoder.
|
||||
// Different kinds of state, like pipeline state, uniform buffer state, etc, are passed to the
|
||||
// Different kinds of state, like pipeline state, uniform buffer state, etc., are passed to the
|
||||
// current Metal command encoder and persist throughout the lifetime of the encoder (a frame).
|
||||
// StateTracker is used to prevent calling redundant state change methods.
|
||||
template<typename StateType>
|
||||
|
||||
@@ -195,6 +195,14 @@ void NoopDriver::updateBufferObject(Handle<HwBufferObject> ibh, BufferDescriptor
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::updateBufferObjectUnsynchronized(Handle<HwBufferObject> ibh, BufferDescriptor&& p,
|
||||
uint32_t byteOffset) {
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::resetBufferObject(Handle<HwBufferObject> boh) {
|
||||
}
|
||||
|
||||
void NoopDriver::setVertexBufferObject(Handle<HwVertexBuffer> vbh, uint32_t index,
|
||||
Handle<HwBufferObject> boh) {
|
||||
}
|
||||
@@ -262,15 +270,6 @@ void NoopDriver::endRenderPass(int) {
|
||||
void NoopDriver::nextSubpass(int) {
|
||||
}
|
||||
|
||||
void NoopDriver::setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph,
|
||||
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh) {
|
||||
}
|
||||
|
||||
void NoopDriver::setRenderPrimitiveRange(Handle<HwRenderPrimitive> rph,
|
||||
PrimitiveType pt, uint32_t offset,
|
||||
uint32_t minIndex, uint32_t maxIndex, uint32_t count) {
|
||||
}
|
||||
|
||||
void NoopDriver::makeCurrent(Handle<HwSwapChain> drawSch, Handle<HwSwapChain> readSch) {
|
||||
}
|
||||
|
||||
@@ -308,11 +307,6 @@ void NoopDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, uint32_t width,
|
||||
uint32_t height, PixelBufferDescriptor&& p) {
|
||||
scheduleDestroy(std::move(p));
|
||||
}
|
||||
|
||||
void NoopDriver::blit(TargetBufferFlags buffers,
|
||||
Handle<HwRenderTarget> dst, Viewport dstRect,
|
||||
Handle<HwRenderTarget> src, Viewport srcRect,
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
private:
|
||||
ShaderModel getShaderModel() const noexcept final;
|
||||
|
||||
uint64_t nextFakeHandle = 1;
|
||||
|
||||
/*
|
||||
* Driver interface
|
||||
*/
|
||||
@@ -50,7 +52,7 @@ private:
|
||||
|
||||
#define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
|
||||
RetType methodName##S() noexcept override { \
|
||||
return RetType((RetType::HandleId)0xDEAD0000); } \
|
||||
return RetType((RetType::HandleId)nextFakeHandle++); } \
|
||||
UTILS_ALWAYS_INLINE inline void methodName##R(RetType, paramsDecl) { }
|
||||
|
||||
#include "private/backend/DriverAPI.inc"
|
||||
|
||||
@@ -42,9 +42,11 @@ void assertFramebufferStatus(utils::io::ostream& out, GLenum target, const char*
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define CHECK_GL_ERROR(out)
|
||||
# define CHECK_GL_ERROR_NON_FATAL(out)
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target)
|
||||
#else
|
||||
# define CHECK_GL_ERROR(out) { GLUtils::assertGLError(out, __func__, __LINE__); }
|
||||
# define CHECK_GL_ERROR_NON_FATAL(out) { GLUtils::checkGLError(out, __func__, __LINE__); }
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __func__, __LINE__); }
|
||||
#endif
|
||||
|
||||
@@ -106,8 +108,7 @@ constexpr inline GLenum getBufferUsage(BufferUsage usage) noexcept {
|
||||
switch (usage) {
|
||||
case BufferUsage::STATIC:
|
||||
return GL_STATIC_DRAW;
|
||||
case BufferUsage::DYNAMIC:
|
||||
case BufferUsage::STREAM:
|
||||
default:
|
||||
return GL_DYNAMIC_DRAW;
|
||||
}
|
||||
}
|
||||
@@ -253,6 +254,23 @@ constexpr inline GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
|
||||
return getTextureCompareFunc(func);
|
||||
}
|
||||
|
||||
constexpr inline GLenum getStencilFunc(SamplerCompareFunc func) noexcept {
|
||||
return getTextureCompareFunc(func);
|
||||
}
|
||||
|
||||
constexpr inline GLenum getStencilOp(StencilOperation op) noexcept {
|
||||
switch (op) {
|
||||
case StencilOperation::KEEP: return GL_KEEP;
|
||||
case StencilOperation::ZERO: return GL_ZERO;
|
||||
case StencilOperation::REPLACE: return GL_REPLACE;
|
||||
case StencilOperation::INCR: return GL_INCR;
|
||||
case StencilOperation::INCR_WRAP: return GL_INCR_WRAP;
|
||||
case StencilOperation::DECR: return GL_DECR;
|
||||
case StencilOperation::DECR_WRAP: return GL_DECR_WRAP;
|
||||
case StencilOperation::INVERT: return GL_INVERT;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline GLenum getFormat(PixelDataFormat format) noexcept {
|
||||
using PixelDataFormat = PixelDataFormat;
|
||||
switch (format) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user