Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dbee125b3 |
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/linux && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/mac && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
os: [macos-latest, ubuntu-18.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat presubmit
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh presubmit
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/ios && printf "y" | ./build.sh presubmit
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh presubmit
|
||||
|
||||
@@ -41,27 +41,22 @@ jobs:
|
||||
TAG=${REF##*/}
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
|
||||
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
|
||||
cd ../..
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
|
||||
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
|
||||
- uses: actions/github-script@v6
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
@@ -76,25 +71,20 @@ jobs:
|
||||
TAG=${REF##*/}
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh release
|
||||
cd ../..
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
|
||||
- uses: actions/github-script@v6
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
@@ -109,20 +99,12 @@ jobs:
|
||||
TAG=${REF##*/}
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh release
|
||||
cd ../..
|
||||
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
|
||||
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/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
- name: Sign sample-gltf-viewer
|
||||
run: |
|
||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||
@@ -137,15 +119,18 @@ jobs:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
APK_KEYSTORE_BASE64: ${{ secrets.APK_KEYSTORE_BASE64 }}
|
||||
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
|
||||
- uses: actions/github-script@v6
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
|
||||
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/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create(['out/*.aar', 'out/*.apk'].join('\n'));
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
@@ -160,25 +145,20 @@ jobs:
|
||||
TAG=${REF##*/}
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
cd build/ios && printf "y" | ./build.sh release
|
||||
cd ../..
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
|
||||
- uses: actions/github-script@v6
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
@@ -194,23 +174,19 @@ jobs:
|
||||
echo "ref=${REF}" >> $GITHUB_OUTPUT
|
||||
echo "tag=${TAG}" >> $GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
build\windows\build-github.bat release
|
||||
cd ..\..
|
||||
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
|
||||
shell: cmd
|
||||
- uses: actions/github-script@v6
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install PyGithub
|
||||
mv out/filament-windows.tgz out/filament-${TAG}-windows.tgz
|
||||
python build/common/upload-assets.py ${TAG} out/*.tgz
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
with:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create('out/*.tgz');
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/checkout@v2.0.0
|
||||
- name: Run build script
|
||||
run: |
|
||||
build\windows\build-github.bat continuous
|
||||
|
||||
@@ -92,8 +92,6 @@ Make sure you've installed the following dependencies:
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
|
||||
- `libxxf86vm-dev` (`libXxf86vm-devel` on Fedora)
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
+9
-13
@@ -74,18 +74,18 @@ if (CCACHE_PROGRAM)
|
||||
configure_file(build/launch-cxx.in launch-cxx)
|
||||
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/launch-cxx"
|
||||
"${CMAKE_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_BINARY_DIR}/launch-cxx"
|
||||
)
|
||||
|
||||
if (CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
else()
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -99,10 +99,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
# ==================================================================================================
|
||||
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
|
||||
set(LINUX TRUE)
|
||||
else()
|
||||
# since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, which the android
|
||||
# cmake files are setting to "Linux".
|
||||
set(LINUX FALSE)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
@@ -554,7 +550,7 @@ function(list_licenses OUTPUT MODULES)
|
||||
endif()
|
||||
endforeach()
|
||||
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
|
||||
endfunction()
|
||||
endfunction(list_licenses)
|
||||
|
||||
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/linux/combine-static-libs.sh")
|
||||
if (WIN32)
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.31.4'
|
||||
implementation 'com.google.android.filament:filament-android:1.28.2'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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.31.4'
|
||||
pod 'Filament', '~> 1.28.2'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -117,9 +117,9 @@ steps:
|
||||
- Image-based lighting
|
||||
- Physically-based camera (shutter speed, sensitivity and aperture)
|
||||
- Physical light units
|
||||
- Point lights, spot lights, and directional light
|
||||
- Point lights, spot lights and directional light
|
||||
- Specular anti-aliasing
|
||||
- Point, spot, and directional light shadows
|
||||
- Spot and directional light shadows
|
||||
- Cascaded shadows
|
||||
- EVSM, PCSS, DPCF, or PCF shadows
|
||||
- Transparent shadows
|
||||
|
||||
+4
-48
@@ -5,56 +5,12 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## main branch
|
||||
|
||||
## v1.31.4
|
||||
|
||||
- engine: fix broken picking [⚠️ **Recompile Materials to get the fix**]
|
||||
- engine: added support for sRGB swapchains. See `SwapChain.h`
|
||||
- bluegl: support Windows32
|
||||
|
||||
## v1.31.3
|
||||
|
||||
- vulkan: fix memory leak in readPixels
|
||||
- engine: added support for draw-commands channels (stronger ordering of commands/renderables)
|
||||
|
||||
## v1.31.2
|
||||
|
||||
## v1.31.1
|
||||
|
||||
- gltfio: expose joint inverse bind matrices via method on FilamentInstance
|
||||
- filamesh: add error when uv coords size does not match num of vertices. (#6351)
|
||||
|
||||
## v1.31.0
|
||||
|
||||
- java: fix confusing typo in Camera documentation
|
||||
- engine: the output color space can be set on `ColorGrading`. This API currently has limitations,
|
||||
please refer to the documentation for more details
|
||||
- Support for RGTC and BPTC texture compression
|
||||
- engine: fix TransformManager high precision mode when using transactions
|
||||
- web: added TypeScript definition for `Engine.destroy`
|
||||
- materials: `getNormalizedViewportCoord()` now returns the logical (i.e. user) viewport
|
||||
normalized position and keeps z reversed [⚠️ **Recompile Materials**]
|
||||
- backend: workaround Adreno shader compiler bug (#6355) [⚠️ **Recompile Materials**]
|
||||
- geometry: change computing tangent basis from normal vector to use Frisvad's method
|
||||
|
||||
## v1.30.0
|
||||
|
||||
- engine: optimize per-shadow UBO [⚠️ **Recompile Materials**]
|
||||
- engine: fix potential memory corruption with larger scenes
|
||||
- engine: VSM's MSAA setting is now per-view instead of per-light [⚠️ **API Change**]
|
||||
|
||||
## v1.29.0
|
||||
|
||||
- gltfio: calculate primitive's AABB correctly.
|
||||
- gltfio: recompute bounding boxes with morph targets
|
||||
- engine: add missing getters on `MaterialInstance`
|
||||
- WebGL: add missing `ColorGrading` JS bindings
|
||||
- engine: improvements/cleanup of Shadow mapping code [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.28.3
|
||||
|
||||
|
||||
- backend: add support for GGP platform
|
||||
- gltfio: calculate primitive's AABB correctly.
|
||||
- gltfio: fix glTF breaking issue
|
||||
- gltfio: recompute bounding boxes with morph targets
|
||||
- engine: primitives with `CullingMode::FRONT_AND_BACK` are now skipped.
|
||||
- engine: add missing getters on `MaterialInstance`
|
||||
|
||||
## v1.28.2
|
||||
|
||||
|
||||
@@ -75,9 +75,9 @@ buildscript {
|
||||
'minSdk': 19,
|
||||
'targetSdk': 33,
|
||||
'compileSdk': 33,
|
||||
'kotlin': '1.8.0',
|
||||
'kotlin_coroutines': '1.6.4',
|
||||
'buildTools': '33.0.1',
|
||||
'kotlin': '1.7.10',
|
||||
'kotlin_coroutines': '1.6.1',
|
||||
'buildTools': '33.0.0',
|
||||
'ndk': '25.1.8937393',
|
||||
'androidx_core': '1.9.0',
|
||||
'androidx_annotations': '1.3.0'
|
||||
@@ -96,7 +96,8 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.0'
|
||||
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
|
||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
jfloat shadowFarHint, jboolean stable, jboolean lispsm,
|
||||
jfloat polygonOffsetConstant, jfloat polygonOffsetSlope,
|
||||
jboolean screenSpaceContactShadows, jint stepCount,
|
||||
jfloat maxShadowDistance, jboolean elvsm, jfloat blurWidth, jfloat shadowBulbRadius) {
|
||||
jfloat maxShadowDistance, jint vsmMsaaSamples, jboolean elvsm, jfloat blurWidth, jfloat shadowBulbRadius) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
LightManager::ShadowOptions shadowOptions {
|
||||
.mapSize = (uint32_t)mapSize,
|
||||
@@ -97,6 +97,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
.stepCount = uint8_t(stepCount),
|
||||
.maxShadowDistance = maxShadowDistance,
|
||||
.vsm = {
|
||||
.msaaSamples = (uint8_t) vsmMsaaSamples,
|
||||
.elvsm = (bool)elvsm,
|
||||
.blurWidth = blurWidth
|
||||
},
|
||||
|
||||
@@ -150,13 +150,6 @@ Java_com_google_android_filament_RenderableManager_nBuilderPriority(JNIEnv*, jcl
|
||||
builder->priority((uint8_t) priority);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderChannel(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint channel) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->channel((uint8_t) channel);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderCulling(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
@@ -346,13 +339,6 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
|
||||
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint channel) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/SwapChain.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
@@ -33,9 +32,3 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
}, callback);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(JNIEnv *, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (bool)SwapChain::isSRGBSwapChainSupported(*engine);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ public class Camera {
|
||||
* By default, this is an identity matrix.
|
||||
* </p>
|
||||
*
|
||||
* @param inScaling diagonal of the scaling matrix to be applied after the projection matrix.
|
||||
* @param scaling diagonal of the scaling matrix to be applied after the projection matrix.
|
||||
*
|
||||
* @see Camera#setProjection
|
||||
* @see Camera#setLensProjection
|
||||
@@ -409,7 +409,7 @@ public class Camera {
|
||||
*
|
||||
* <pre>
|
||||
* engine.getTransformManager().setTransform(
|
||||
* engine.getTransformManager().getInstance(camera->getEntity()), modelMatrix);
|
||||
* engine.getTransformManager().getInstance(camera->getEntity()), viewMatrix);
|
||||
* </pre>
|
||||
*
|
||||
* @param modelMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
|
||||
|
||||
+18
-2
@@ -349,6 +349,20 @@ public class LightManager {
|
||||
* @see View#setShadowType
|
||||
*/
|
||||
|
||||
/**
|
||||
* The number of MSAA samples to use when rendering VSM shadow maps.
|
||||
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
|
||||
* off MSAA.
|
||||
* Higher values may not be available depending on the underlying hardware.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Warning: This API is still experimental and subject to change.</strong>
|
||||
* </p>
|
||||
*/
|
||||
@IntRange(from = 1)
|
||||
public int vsmMsaaSamples = 1;
|
||||
|
||||
|
||||
/**
|
||||
* When elvsm is set to true, "Exponential Layered VSM without Layers" are used. It is
|
||||
* an improvement to the default EVSM which suffers important light leaks. Enabling
|
||||
@@ -505,7 +519,7 @@ public class LightManager {
|
||||
options.shadowFarHint, options.stable, options.lispsm,
|
||||
options.polygonOffsetConstant, options.polygonOffsetSlope,
|
||||
options.screenSpaceContactShadows,
|
||||
options.stepCount, options.maxShadowDistance,
|
||||
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
|
||||
options.elvsm, options.blurWidth, options.shadowBulbRadius);
|
||||
return this;
|
||||
}
|
||||
@@ -1004,6 +1018,8 @@ public class LightManager {
|
||||
* lightbulbs.
|
||||
*
|
||||
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
public void setIntensity(@EntityInstance int i, float watts, float efficiency) {
|
||||
nSetIntensity(mNativeObject, i , watts, efficiency);
|
||||
@@ -1169,7 +1185,7 @@ public class LightManager {
|
||||
boolean stable, boolean lispsm,
|
||||
float polygonOffsetConstant, float polygonOffsetSlope,
|
||||
boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance,
|
||||
boolean elvsm, float blurWidth, float shadowBulbRadius);
|
||||
int vsmMsaaSamples, boolean elvsm, float blurWidth, float shadowBulbRadius);
|
||||
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
|
||||
|
||||
+1
-63
@@ -257,74 +257,23 @@ public class RenderableManager {
|
||||
* Provides coarse-grained control over draw order.
|
||||
*
|
||||
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
|
||||
* rendering. However clients can control ordering at a coarse level using \em priority.
|
||||
* The priority is applied separately for opaque and translucent objects, that is, opaque
|
||||
* objects are always drawn before translucent objects regardless of the priority.</p>
|
||||
* rendering. However clients can control ordering at a coarse level using <em>priority</em>.</p>
|
||||
*
|
||||
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
|
||||
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
|
||||
* {@link Builder#layerMask}, which merely controls visibility.</p>
|
||||
|
||||
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
|
||||
* performance.</p>
|
||||
*
|
||||
* <p>The priority is clamped to the range [0..7], defaults to 4; 7 is lowest priority
|
||||
* (rendered last).</p>
|
||||
*
|
||||
* @see Builder#blendOrder
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides coarse-grained control over draw order.
|
||||
*
|
||||
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
|
||||
* rendering. However clients can control ordering at a coarse level using priority.
|
||||
* The priority is applied separately for opaque and translucent objects, that is, opaque
|
||||
* objects are always drawn before translucent objects regardless of the priority.</p>
|
||||
*
|
||||
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
|
||||
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
|
||||
* {@link Builder#layerMask}, which merely controls visibility.</p>
|
||||
|
||||
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
|
||||
* performance.</p>
|
||||
*
|
||||
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
|
||||
* (rendered last).
|
||||
*
|
||||
* @return Builder reference for chaining calls.
|
||||
*
|
||||
* @see Builder#channel
|
||||
* @see Builder#blendOrder
|
||||
* @see #setPriority
|
||||
* @see #setBlendOrderAt
|
||||
*/
|
||||
@NonNull
|
||||
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
|
||||
nBuilderPriority(mNativeBuilder, priority);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the channel this renderable is associated to. There can be 4 channels.
|
||||
* All renderables in a given channel are rendered together, regardless of anything else.
|
||||
* They are sorted as usual withing a channel.
|
||||
* Channels work similarly to priorities, except that they enforce the strongest ordering.
|
||||
*
|
||||
* @param channel clamped to the range [0..3], defaults to 0.
|
||||
*
|
||||
* @return Builder reference for chaining calls.
|
||||
*
|
||||
* @see Builder::blendOrder()
|
||||
* @see Builder::priority()
|
||||
* @see RenderableManager::setBlendOrderAt()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder channel(@IntRange(from = 0, to = 3) int channel) {
|
||||
nBuilderChannel(mNativeBuilder, channel);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls frustum culling, true by default.
|
||||
*
|
||||
@@ -706,15 +655,6 @@ public class RenderableManager {
|
||||
nSetPriority(mNativeObject, i, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the channel of a renderable
|
||||
*
|
||||
* @see Builder#channel
|
||||
*/
|
||||
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 3) int channel) {
|
||||
nSetChannel(mNativeObject, i, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether or not frustum culling is on.
|
||||
*
|
||||
@@ -936,7 +876,6 @@ public class RenderableManager {
|
||||
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);
|
||||
private static native void nBuilderChannel(long nativeBuilder, int channel);
|
||||
private static native void nBuilderCulling(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderCastShadows(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderReceiveShadows(long nativeBuilder, boolean enabled);
|
||||
@@ -959,7 +898,6 @@ public class RenderableManager {
|
||||
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
|
||||
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
|
||||
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
|
||||
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);
|
||||
|
||||
@@ -124,24 +124,7 @@ public class Renderer {
|
||||
*/
|
||||
public static class ClearOptions {
|
||||
/**
|
||||
* Color (sRGB linear) to use to clear the RenderTarget (typically the SwapChain).
|
||||
*
|
||||
* The RenderTarget is cleared using this color, which won't be tone-mapped since
|
||||
* tone-mapping is part of View rendering (this is not).
|
||||
*
|
||||
* When a View is rendered, there are 3 scenarios to consider:
|
||||
* - Pixels rendered by the View replace the clear color (or blend with it in
|
||||
* `BlendMode.TRANSLUCENT` mode).
|
||||
*
|
||||
* - With blending mode set to `BlendMode.TRANSLUCENT`, Pixels untouched by the View
|
||||
* are considered fulling transparent and let the clear color show through.
|
||||
*
|
||||
* - With blending mode set to `BlendMode.OPAQUE`, Pixels untouched by the View
|
||||
* are set to the clear color. However, because it is now used in the context of a View,
|
||||
* it will go through the post-processing stage, which includes tone-mapping.
|
||||
*
|
||||
* For consistency, it is recommended to always use a Skybox to clear an opaque View's
|
||||
* background, or to use black or fully-transparent (i.e. {0,0,0,0}) as the clear color.
|
||||
* Color to use to clear the SwapChain
|
||||
*/
|
||||
@NonNull
|
||||
public float[] clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
@@ -91,34 +91,11 @@ public class SwapChain {
|
||||
*/
|
||||
public static final long CONFIG_ENABLE_XCB = 0x4;
|
||||
|
||||
/**
|
||||
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
|
||||
*
|
||||
* This flag is ignored if isSRGBSwapChainSupported() is false.
|
||||
*
|
||||
* When using this flag, post-processing should be disabled.
|
||||
*
|
||||
* @see SwapChain#isSRGBSwapChainSupported
|
||||
* @see View#setPostProcessingEnabled
|
||||
*/
|
||||
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
|
||||
|
||||
SwapChain(long nativeSwapChain, Object surface) {
|
||||
mNativeObject = nativeSwapChain;
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
|
||||
* The default implementation returns false.
|
||||
*
|
||||
* @param engine A reference to the filament Engine
|
||||
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
|
||||
*/
|
||||
public static boolean isSRGBSwapChainSupported(@NonNull Engine engine) {
|
||||
return nIsSRGBSwapChainSupported(engine.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
|
||||
* for a headless SwapChain.
|
||||
@@ -164,5 +141,4 @@ public class SwapChain {
|
||||
}
|
||||
|
||||
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
|
||||
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
|
||||
}
|
||||
|
||||
@@ -250,19 +250,7 @@ public class Texture {
|
||||
SRGB8_ALPHA8_ASTC_10x8,
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12,
|
||||
|
||||
// RGTC formats available with a GLES extension
|
||||
RED_RGTC1, // BC4 unsigned
|
||||
SIGNED_RED_RGTC1, // BC4 signed
|
||||
RED_GREEN_RGTC2, // BC5 unsigned
|
||||
SIGNED_RED_GREEN_RGTC2, // BC5 signed
|
||||
|
||||
// BPTC formats available with a GLES extension
|
||||
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
|
||||
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
|
||||
RGBA_BPTC_UNORM, // BC7
|
||||
SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
|
||||
SRGB8_ALPHA8_ASTC_12x12
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,19 +296,7 @@ public class Texture {
|
||||
SRGB8_ALPHA8_ASTC_10x8,
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12,
|
||||
|
||||
// RGTC formats available with a GLES extension
|
||||
RED_RGTC1, // BC4 unsigned
|
||||
SIGNED_RED_RGTC1, // BC4 signed
|
||||
RED_GREEN_RGTC2, // BC5 unsigned
|
||||
SIGNED_RED_GREEN_RGTC2, // BC5 signed
|
||||
|
||||
// BPTC formats available with a GLES extension
|
||||
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
|
||||
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
|
||||
RGBA_BPTC_UNORM, // BC7
|
||||
SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
|
||||
SRGB8_ALPHA8_ASTC_12x12
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1817,13 +1817,6 @@ public class View {
|
||||
* Whether to generate mipmaps for all VSM shadow maps.
|
||||
*/
|
||||
public boolean mipmapping = false;
|
||||
/**
|
||||
* The number of MSAA samples to use when rendering VSM shadow maps.
|
||||
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
|
||||
* off MSAA.
|
||||
* Higher values may not be available depending on the underlying hardware.
|
||||
*/
|
||||
public int msaaSamples = 1;
|
||||
/**
|
||||
* Whether to use a 32-bits or 16-bits texture format for VSM shadow maps. 32-bits
|
||||
* precision is rarely needed, but it does reduces light leaks as well as "fading"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.31.4
|
||||
VERSION_NAME=1.28.2
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
@@ -22,4 +22,3 @@ android.useAndroidX=true
|
||||
com.google.android.filament.tools-dir=../../../out/release/filament
|
||||
com.google.android.filament.dist-dir=../out/android-release/filament
|
||||
com.google.android.filament.abis=all
|
||||
#com.google.android.filament.matdbg=true
|
||||
|
||||
+1
-1
@@ -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.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+15
-18
@@ -27,7 +27,6 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.Renderer.ClearOptions
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
@@ -65,6 +64,7 @@ class MainActivity : Activity() {
|
||||
private lateinit var view0: View
|
||||
private lateinit var view1: View
|
||||
private lateinit var view2: View
|
||||
private lateinit var view3: View
|
||||
private lateinit var view4: View
|
||||
// We need skybox to set the background color
|
||||
private lateinit var skybox: Skybox
|
||||
@@ -119,19 +119,15 @@ class MainActivity : Activity() {
|
||||
view0 = engine.createView()
|
||||
view1 = engine.createView()
|
||||
view2 = engine.createView()
|
||||
view3 = engine.createView()
|
||||
view4 = engine.createView()
|
||||
|
||||
view0.setName("view0");
|
||||
view1.setName("view1");
|
||||
view2.setName("view2");
|
||||
view3.setName("view3");
|
||||
view4.setName("view4");
|
||||
|
||||
// Useful for debugging issues
|
||||
// view0.isPostProcessingEnabled = false
|
||||
// view1.isPostProcessingEnabled = false
|
||||
// view2.isPostProcessingEnabled = false
|
||||
// view4.isPostProcessingEnabled = false
|
||||
|
||||
view4.blendMode = View.BlendMode.TRANSLUCENT;
|
||||
|
||||
skybox = Skybox.Builder().build(engine);
|
||||
@@ -144,11 +140,13 @@ class MainActivity : Activity() {
|
||||
view0.camera = camera
|
||||
view1.camera = camera
|
||||
view2.camera = camera
|
||||
view3.camera = camera
|
||||
view4.camera = camera
|
||||
|
||||
view0.scene = scene
|
||||
view1.scene = scene
|
||||
view2.scene = scene
|
||||
view3.scene = scene
|
||||
view4.scene = scene
|
||||
}
|
||||
|
||||
@@ -381,6 +379,7 @@ class MainActivity : Activity() {
|
||||
engine.destroyView(view0)
|
||||
engine.destroyView(view1)
|
||||
engine.destroyView(view2)
|
||||
engine.destroyView(view3)
|
||||
engine.destroyView(view4)
|
||||
engine.destroySkybox(skybox)
|
||||
engine.destroyScene(scene)
|
||||
@@ -408,18 +407,19 @@ class MainActivity : Activity() {
|
||||
// If beginFrame() returns false you should skip the frame
|
||||
// This means you are sending frames too quickly to the GPU
|
||||
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
|
||||
scene.skybox = skybox
|
||||
skybox.setColor(0.35f, 0.35f, 0.35f, 1.0f);
|
||||
|
||||
skybox.setColor(0.035f, 0.035f, 0.035f, 1.0f);
|
||||
renderer.render(view0)
|
||||
|
||||
skybox.setColor(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
skybox.setColor(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
renderer.render(view1)
|
||||
|
||||
scene.skybox = null
|
||||
|
||||
skybox.setColor(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
renderer.render(view2)
|
||||
|
||||
skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
renderer.render(view3)
|
||||
|
||||
skybox.setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
renderer.render(view4)
|
||||
|
||||
renderer.endFrame()
|
||||
@@ -433,10 +433,6 @@ class MainActivity : Activity() {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface)
|
||||
renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
|
||||
renderer.clearOptions = renderer.clearOptions.apply {
|
||||
clear = true
|
||||
clearColor = floatArrayOf( 0.0f, 0.0f, 1.0f, 0.0f )
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromSurface() {
|
||||
@@ -457,6 +453,7 @@ class MainActivity : Activity() {
|
||||
view0.viewport = Viewport(0, 0, width / 2, height / 2)
|
||||
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
|
||||
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
|
||||
view3.viewport = Viewport(width / 2, height / 2, width / 2, height / 2)
|
||||
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 848 KiB After Width: | Height: | Size: 848 KiB |
@@ -44,10 +44,6 @@ FILAMENT_HEADERS="$1"
|
||||
includes=()
|
||||
pushd "$FILAMENT_HEADERS" >/dev/null
|
||||
for f in $(find . -name '*.h'); do
|
||||
# Ignore platform headers. These may contain platform-specific includes.
|
||||
if [[ "$f" == *backend/platforms/* ]]; then
|
||||
continue
|
||||
fi
|
||||
include_path="${f#./}" # strip leading ./
|
||||
includes+=("${include_path}")
|
||||
done
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
setuptools==40.6.2
|
||||
wheel==0.37.1
|
||||
certifi==2021.10.8
|
||||
cffi==1.15.0
|
||||
charset-normalizer==2.0.12
|
||||
Deprecated==1.2.13
|
||||
idna==3.3
|
||||
pycparser==2.21
|
||||
PyGithub==1.55
|
||||
PyJWT==2.4.0
|
||||
PyNaCl==1.5.0
|
||||
requests==2.27.1
|
||||
urllib3==1.26.9
|
||||
wrapt==1.14.0
|
||||
Executable
+93
@@ -0,0 +1,93 @@
|
||||
# Copyright (C) 2019 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
# requirements.txt created via:
|
||||
#
|
||||
# pip3 install virtualenv
|
||||
# python3 -m venv env
|
||||
# pip3 install PyGithub
|
||||
# pip3 install wheel
|
||||
# --all includes wheel and setuputils, which is needed for GitHub Actions
|
||||
# pip3 freeze --all > requirements.txt
|
||||
# Manually move 'setuptools' and 'wheel' lines to the beginning of the file.
|
||||
# Manually remove the 'pip' line.
|
||||
#
|
||||
# Requirements are installed in GitHub Actions via:
|
||||
# xargs -L 1 sudo pip3 install < build/common/requirements.txt
|
||||
# xargs must be used because the ordering of the dependencies matters (namely, setuptools).
|
||||
# sudo must be used to uninstall non-matching versions of packages.
|
||||
# pip is removed to avoid conflicts with the pre-installed pip version on Actions.
|
||||
# This technique does not work with Windows, unfortunately.
|
||||
|
||||
from github import Github
|
||||
import os, sys
|
||||
|
||||
def print_usage():
|
||||
print('Upload assets to a Filament GitHub release.')
|
||||
print()
|
||||
print('Usage:')
|
||||
print(' upload-assets.py <tag> <asset>...')
|
||||
print()
|
||||
print('Notes:')
|
||||
print(' The GitHub release must already be created prior to running this script. This is typically done')
|
||||
print(' through the GitHub web UI.')
|
||||
print()
|
||||
print(' <tag> is the Git tag for the desired release to attach assets to, for example, "v1.4.2".')
|
||||
print()
|
||||
print(' <asset> is a path to the asset file to upload. The file name will be used as the name of the')
|
||||
print(' asset.')
|
||||
print()
|
||||
print(' The GITHUB_API_KEY environment variable must be set to a valid authentication token for a')
|
||||
print(' collaborator account of the Filament repository.')
|
||||
|
||||
# The first argument is the path to this script.
|
||||
if len(sys.argv) < 3:
|
||||
print_usage()
|
||||
sys.exit(1)
|
||||
|
||||
tag = sys.argv[1]
|
||||
assets = sys.argv[2:]
|
||||
|
||||
authentication_token = os.environ.get('GITHUB_API_KEY')
|
||||
if not authentication_token:
|
||||
sys.stderr.write('Error: the GITHUB_API_KEY is not set.\n')
|
||||
sys.exit(1)
|
||||
|
||||
g = Github(authentication_token)
|
||||
|
||||
FILAMENT_REPO = "google/filament"
|
||||
filament = g.get_repo(FILAMENT_REPO)
|
||||
|
||||
def find_release_from_tag(repo, tag):
|
||||
""" Find a release in the repo for the given Git tag string. """
|
||||
releases = repo.get_releases()
|
||||
for r in releases:
|
||||
if r.tag_name == tag:
|
||||
return r
|
||||
return None
|
||||
|
||||
release = find_release_from_tag(filament, tag)
|
||||
if not release:
|
||||
sys.stderr.write(f"Error: Could not find release with tag '{tag}'.\n")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Found release with tag '{tag}'.")
|
||||
|
||||
for asset_path in assets:
|
||||
sys.stdout.write(f'Uploding asset: {asset_path}... ')
|
||||
asset_name = os.path.basename(asset_path)
|
||||
asset = release.upload_asset(asset_path, name=asset_name)
|
||||
if asset:
|
||||
sys.stdout.write('Success!\n')
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const uploadReleaseAssets = async ({github, context}, assetPathsToUpload, releaseTag) => {
|
||||
const fs = require('fs/promises');
|
||||
const path = require('path');
|
||||
|
||||
const filesToUpload = assetPathsToUpload.map(assetPath => ({
|
||||
buffer: fs.readFile(assetPath),
|
||||
assetName: path.basename(assetPath)
|
||||
}));
|
||||
|
||||
const findReleaseMatchingTag = async tag => {
|
||||
const { data: releases } = await github.rest.repos.listReleases(context.repo);
|
||||
const release = releases.find(release => release.tag_name === releaseTag);
|
||||
if (!release) {
|
||||
throw new Error(`Could not locate release with tag '${releaseTag}'`);
|
||||
}
|
||||
return release;
|
||||
};
|
||||
|
||||
const release = await findReleaseMatchingTag(releaseTag);
|
||||
|
||||
console.log(`Found release named '${release.name}' matching tag '${release.tag_name}'.`);
|
||||
|
||||
const uploadPromises = [];
|
||||
for (const file of filesToUpload) {
|
||||
console.log(`Uploading asset ${file.assetName}.`);
|
||||
const p = github.rest.repos.uploadReleaseAsset({
|
||||
...context.repo,
|
||||
release_id: release.id,
|
||||
name: file.assetName,
|
||||
data: await file.buffer
|
||||
});
|
||||
uploadPromises.push(p);
|
||||
}
|
||||
|
||||
await Promise.all(uploadPromises);
|
||||
console.log("Done!");
|
||||
}
|
||||
|
||||
module.exports = uploadReleaseAssets;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// To test this script locally, uncomment the code below and run:
|
||||
//
|
||||
// npm install
|
||||
// node index.js
|
||||
|
||||
// const { Octokit } = require("@octokit/rest");
|
||||
// const glob = require("@actions/glob");
|
||||
// (async () => {
|
||||
// const github = new Octokit({
|
||||
// auth: "" // <-- paste GitHub auth token here
|
||||
// });
|
||||
// const context = {
|
||||
// repo: {
|
||||
// owner: "bejado",
|
||||
// repo: "filament",
|
||||
// },
|
||||
// };
|
||||
// const globber = await glob.create('*.txt');
|
||||
// await uploadReleaseAssets({ github, context }, await globber.glob(), 'vtest-28');
|
||||
// })();
|
||||
-546
@@ -1,546 +0,0 @@
|
||||
{
|
||||
"name": "upload-release-assets",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@actions/glob": "^0.3.0",
|
||||
"@octokit/rest": "^19.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/glob": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.3.0.tgz",
|
||||
"integrity": "sha512-tJP1ZhF87fd6LBnaXWlahkyvdgvsLl7WnreW1EZaC8JWjpMXmzqWzQVe/IEYslrkT9ymibVrKyJN4UMD7uQM2w==",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.2.tgz",
|
||||
"integrity": "sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^3.0.0",
|
||||
"@octokit/graphql": "^5.0.0",
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.3.tgz",
|
||||
"integrity": "sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.4.tgz",
|
||||
"integrity": "sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
|
||||
"integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
|
||||
"integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz",
|
||||
"integrity": "sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"deprecation": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
||||
"integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^7.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.2.tgz",
|
||||
"integrity": "sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/rest": {
|
||||
"version": "19.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.5.tgz",
|
||||
"integrity": "sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow==",
|
||||
"dependencies": {
|
||||
"@octokit/core": "^4.1.0",
|
||||
"@octokit/plugin-paginate-rest": "^5.0.0",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^6.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz",
|
||||
"integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"@actions/glob": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.3.0.tgz",
|
||||
"integrity": "sha512-tJP1ZhF87fd6LBnaXWlahkyvdgvsLl7WnreW1EZaC8JWjpMXmzqWzQVe/IEYslrkT9ymibVrKyJN4UMD7uQM2w==",
|
||||
"requires": {
|
||||
"@actions/core": "^1.2.6",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"requires": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.2.tgz",
|
||||
"integrity": "sha512-pq7CwIMV1kmzkFTimdwjAINCXKTajZErLB4wMLYapR2nuB/Jpr66+05wOTZMSCBXP6n4DdDWT2W19Bm17vU69Q==",
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.1.0.tgz",
|
||||
"integrity": "sha512-Czz/59VefU+kKDy+ZfDwtOIYIkFjExOKf+HA92aiTZJ6EfWpFzYQWw0l54ji8bVmyhc+mGaLUbSUmXazG7z5OQ==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^3.0.0",
|
||||
"@octokit/graphql": "^5.0.0",
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.3.tgz",
|
||||
"integrity": "sha512-57gRlb28bwTsdNXq+O3JTQ7ERmBTuik9+LelgcLIVfYwf235VHbN9QNo4kXExtp/h8T423cR5iJThKtFYxC7Lw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.4.tgz",
|
||||
"integrity": "sha512-amO1M5QUQgYQo09aStR/XO7KAl13xpigcy/kI8/N1PnZYSS69fgte+xA4+c2DISKqUZfsh0wwjc2FaCt99L41A==",
|
||||
"requires": {
|
||||
"@octokit/request": "^6.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-14.0.0.tgz",
|
||||
"integrity": "sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-5.0.1.tgz",
|
||||
"integrity": "sha512-7A+rEkS70pH36Z6JivSlR7Zqepz3KVucEFVDnSrgHXzG7WLAzYwcHZbKdfTXHwuTHbkT1vKvz7dHl1+HNf6Qyw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-request-log": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
|
||||
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.7.0.tgz",
|
||||
"integrity": "sha512-orxQ0fAHA7IpYhG2flD2AygztPlGYNAdlzYz8yrD8NDgelPfOYoRPROfEyIe035PlxvbYrgkfUZIhSBKju/Cvw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.2.tgz",
|
||||
"integrity": "sha512-6VDqgj0HMc2FUX2awIs+sM6OwLgwHvAi4KCK3mT2H2IKRt6oH9d0fej5LluF5mck1lRR/rFWN0YIDSYXYSylbw==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^7.0.0",
|
||||
"@octokit/request-error": "^3.0.0",
|
||||
"@octokit/types": "^8.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.2.tgz",
|
||||
"integrity": "sha512-WMNOFYrSaX8zXWoJg9u/pKgWPo94JXilMLb2VManNOby9EZxrQaBe/QSC4a1TzpAlpxofg2X/jMnCyZgL6y7eg==",
|
||||
"requires": {
|
||||
"@octokit/types": "^8.0.0",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/rest": {
|
||||
"version": "19.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.5.tgz",
|
||||
"integrity": "sha512-+4qdrUFq2lk7Va+Qff3ofREQWGBeoTKNqlJO+FGjFP35ZahP+nBenhZiGdu8USSgmq4Ky3IJ/i4u0xbLqHaeow==",
|
||||
"requires": {
|
||||
"@octokit/core": "^4.1.0",
|
||||
"@octokit/plugin-paginate-rest": "^5.0.0",
|
||||
"@octokit/plugin-request-log": "^1.0.4",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^6.7.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz",
|
||||
"integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^14.0.0"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
|
||||
"integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "upload-release-assets",
|
||||
"version": "1.0.0",
|
||||
"description": "Upload Filament release assets",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Google",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@actions/glob": "^0.3.0",
|
||||
"@octokit/rest": "^19.0.5"
|
||||
}
|
||||
}
|
||||
@@ -3821,7 +3821,7 @@ Since $\left< cos \theta \right>$ does not depend on $\phi$ (azimuthal independe
|
||||
|
||||
$$\begin{align*}
|
||||
C^0_l &= 2\pi \int_0^{\pi} \left< cos \theta \right> y^0_l(\theta) sin \theta d\theta \\
|
||||
C^0_l &= 2\pi K^m_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
|
||||
C^0_l &= 2\pi K^)_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
|
||||
C^m_l &= 0, m != 0
|
||||
\end{align*}$$
|
||||
|
||||
|
||||
@@ -2263,7 +2263,7 @@ type aliases:
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getResolution()** | float4 | Dimensions of the view's effective (physical) viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands.
|
||||
**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
|
||||
@@ -2301,7 +2301,7 @@ The following APIs are only available from the fragment block:
|
||||
**getWorldNormalVector()** | float3 | Normalized normal in world space, after bump mapping (must be used after `prepareMaterial()`)
|
||||
**getWorldGeometricNormalVector()** | float3 | Normalized normal in world space, before bump mapping (can be used before `prepareMaterial()`)
|
||||
**getWorldReflectedVector()** | float3 | Reflection of the view vector about the normal (must be used after `prepareMaterial()`)
|
||||
**getNormalizedViewportCoord()** | float3 | Normalized user viewport position (i.e. NDC coordinates normalized to [0, 1] for the position, [1, 0] for the depth), can be used before `prepareMaterial()`). Because the user viewport is smaller than the actual physical viewport, these coordinates can be negative or superior to 1 in the non-visible area of the physical viewport.
|
||||
**getNormalizedViewportCoord()** | float3 | Normalized viewport position (i.e. NDC coordinates normalized to [0, 1], can be used before `prepareMaterial()`)
|
||||
**getNdotV()** | float | The result of `dot(normal, view)`, always strictly greater than 0 (must be used after `prepareMaterial()`)
|
||||
**getColor()** | float4 | Interpolated color of the fragment, if the color attribute is required
|
||||
**getUV0()** | float2 | First interpolated set of UV coordinates, only available if the uv0 attribute is required
|
||||
|
||||
+157
-343
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -261,7 +261,7 @@ class App {
|
||||
this.renderer.setClearOptions({clearColor: kBackgroundColor, clear: true});
|
||||
|
||||
this.render = this.render.bind(this);
|
||||
this.simpleViewer = new Filament.ViewerGui(engine, scene, view, kInitialSidebarWidth);
|
||||
this.simpleViewer = new Filament.SimpleViewer(engine, scene, view, kInitialSidebarWidth);
|
||||
|
||||
this.mouseX = -1;
|
||||
this.mouseY = -1;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+153
-330
File diff suppressed because one or more lines are too long
Binary file not shown.
Vendored
-1
File diff suppressed because one or more lines are too long
+20
-21
@@ -10,7 +10,7 @@ html, body { height: 100%; }
|
||||
body { margin: 0; overflow: hidden; }
|
||||
#container { position: relative; height: 100%; }
|
||||
canvas { position: absolute; width: 100%; height: 100%; }
|
||||
#messages { position: absolute; width: 100%; height: 100%; padding-left: 10px; color:blue; pointer-events: none; }
|
||||
#messages { position: absolute; width: 100%; height: 100%; padding-left: 10px; color:white; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -20,7 +20,7 @@ canvas { position: absolute; width: 100%; height: 100%; }
|
||||
</div>
|
||||
<script src="filament.js"></script>
|
||||
<script src="gl-matrix-min.js"></script>
|
||||
<script src="gltumble.min.js"></script>
|
||||
<script src="https://unpkg.com/gltumble"></script>
|
||||
<script>
|
||||
|
||||
const env = 'default_env';
|
||||
@@ -43,19 +43,7 @@ class App {
|
||||
const scene = this.scene = engine.createScene();
|
||||
this.trackball = new Trackball(canvas, {startSpin: 0.035});
|
||||
|
||||
const messages = document.getElementById('messages');
|
||||
|
||||
canvas.addEventListener('pointerdown', evt => {
|
||||
const x = evt.clientX;
|
||||
const y = this.canvas.getBoundingClientRect().height - 1 - evt.clientY;
|
||||
const dpr = window.devicePixelRatio;
|
||||
this.view.pick(x * dpr, y * dpr, (results) => {
|
||||
const name = this.asset.getName(results.renderable);
|
||||
messages.innerText = name ? ('Picked ' + name) : '';
|
||||
});
|
||||
});
|
||||
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx1(ibl_url);
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
|
||||
this.scene.setIndirectLight(indirectLight);
|
||||
|
||||
const iblDirection = IndirectLight.getDirectionEstimate(indirectLight.shfloats);
|
||||
@@ -70,7 +58,7 @@ class App {
|
||||
mat3.fromRotation(mat, radians, [0, 1, 0]);
|
||||
indirectLight.setRotation(mat);
|
||||
|
||||
const skybox = engine.createSkyFromKtx1(sky_url);
|
||||
const skybox = engine.createSkyFromKtx(sky_url);
|
||||
this.scene.setSkybox(skybox);
|
||||
|
||||
const sunlight = Filament.EntityManager.get().create();
|
||||
@@ -88,17 +76,28 @@ class App {
|
||||
const loader = this.loader = engine.createAssetLoader();
|
||||
|
||||
this.allowRefresh = false;
|
||||
const asset = this.asset = loader.createAsset(mesh_url);
|
||||
const asset = this.asset = loader.createAssetFromJson(mesh_url);
|
||||
this.assetRoot = this.asset.getRoot();
|
||||
|
||||
const messages = document.getElementById('messages');
|
||||
|
||||
// Crudely indicate progress by printing the URI of each resource as it is loaded.
|
||||
const onFetched = (uri) => messages.innerText += `Downloaded ${uri}\n`;
|
||||
|
||||
const onDone = () => {
|
||||
this.allowRefresh = true;
|
||||
|
||||
// Clear the progress indication messages.
|
||||
messages.innerText = "";
|
||||
// Enable shadows on every renderable.
|
||||
const entities = asset.getEntities();
|
||||
const rm = engine.getRenderableManager();
|
||||
for (const entity of entities) {
|
||||
const instance = rm.getInstance(entity);
|
||||
rm.setCastShadows(instance, true);
|
||||
instance.delete();
|
||||
}
|
||||
|
||||
// Hide the HUD.
|
||||
messages.remove();
|
||||
};
|
||||
asset.loadResources(onDone, onFetched);
|
||||
|
||||
@@ -138,7 +137,7 @@ class App {
|
||||
this.allowRefresh = false;
|
||||
this.scene.removeEntities(this.asset.getEntities());
|
||||
this.loader.destroyAsset(this.asset);
|
||||
this.asset = this.loader.createAsset(mesh_url);
|
||||
this.asset = this.loader.createAssetFromJson(mesh_url);
|
||||
const onDone = () => { this.allowRefresh = true; }
|
||||
this.asset.loadResources(onDone);
|
||||
}
|
||||
@@ -150,7 +149,7 @@ class App {
|
||||
tcm.setTransform(inst, this.trackball.getMatrix());
|
||||
inst.delete();
|
||||
|
||||
// Gradually add renderables to the scene as their textures become ready.
|
||||
// Add renderable entities to the scene as they become ready.
|
||||
let entity;
|
||||
const popRenderable = () => {
|
||||
entity = this.asset.popRenderable();
|
||||
|
||||
Binary file not shown.
@@ -54,14 +54,14 @@ class App {
|
||||
.build(engine, sunlight);
|
||||
this.scene.addEntity(sunlight);
|
||||
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx1(iblfile);
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx(iblfile);
|
||||
this.scene.setIndirectLight(indirectLight);
|
||||
|
||||
const radians = 1.0;
|
||||
indirectLight.setRotation(mat3.fromRotation(mat3.create(), radians, [0, 1, 0]))
|
||||
indirectLight.setIntensity(10000);
|
||||
|
||||
const skybox = engine.createSkyFromKtx1(skyfile);
|
||||
const skybox = engine.createSkyFromKtx(skyfile);
|
||||
this.scene.setSkybox(skybox);
|
||||
|
||||
const material = engine.createMaterial('parquet.filamat');
|
||||
|
||||
Binary file not shown.
+128
-137
@@ -49,7 +49,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#EntityManager">EntityManager</a></td>
|
||||
<td align="left">Singleton used for constructing entities in Filament's ECS.</td>
|
||||
<td align="left">Singleton used for constructing entities in Filament's ECS.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Frustum">Frustum</a></td>
|
||||
@@ -69,7 +69,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#KtxInfo">KtxInfo</a></td>
|
||||
<td align="left">Property accessor for KTX1 header.</td>
|
||||
<td align="left">Property accessor for KTX header.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#LightManager%24Instance">LightManager$Instance</a></td>
|
||||
@@ -89,7 +89,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Renderer">Renderer</a></td>
|
||||
<td align="left">Represents the platform's native window.</td>
|
||||
<td align="left">Represents the platform's native window.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Scene">Scene</a></td>
|
||||
@@ -97,7 +97,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#SwapChain">SwapChain</a></td>
|
||||
<td align="left">Represents the platform's native rendering surface.</td>
|
||||
<td align="left">Represents the platform's native rendering surface.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Texture">Texture</a></td>
|
||||
@@ -190,10 +190,6 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#ColorGrading%24LutFormat">ColorGrading$LutFormat</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#ColorGrading%24QualityLevel">ColorGrading$QualityLevel</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -218,10 +214,6 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#FeatureLevel">FeatureLevel</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Frustum%24Plane">Frustum$Plane</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -230,14 +222,6 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Ktx2Reader%24Result">Ktx2Reader$Result</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Ktx2Reader%24TransferFunction">Ktx2Reader$TransferFunction</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#LightManager%24Type">LightManager$Type</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -274,14 +258,6 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#StencilFace">StencilFace</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#StencilOperation">StencilOperation</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#Texture%24CubemapFace">Texture$CubemapFace</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -298,10 +274,6 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#TransparencyMode">TransparencyMode</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#VertexAttribute">VertexAttribute</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -314,6 +286,26 @@
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#View%24AntiAliasing">View$AntiAliasing</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#View%24BlendMode">View$BlendMode</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#View%24BloomOptions%24BlendMode">View$BloomOptions$BlendMode</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#View%24DepthOfFieldOptions%24Filter">View$DepthOfFieldOptions$Filter</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#View%24QualityLevel">View$QualityLevel</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><a href="#WrapMode">WrapMode</a></td>
|
||||
<td align="left"></td>
|
||||
</tr>
|
||||
@@ -379,7 +371,7 @@
|
||||
<li><em>returns</em> an instance of <a href="#Camera">Camera</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.createIblFromKtx1(buffer, options)</strong>
|
||||
<li><strong>engine.createIblFromKtx(buffer, options)</strong>
|
||||
<ul>
|
||||
<li>Utility that creates an [IndirectLight] from a KTX file.</li>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
|
||||
@@ -403,7 +395,7 @@
|
||||
<li><em>returns</em> an instance of <a href="#Scene">Scene</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.createSkyFromKtx1(buffer, options)</strong>
|
||||
<li><strong>engine.createSkyFromKtx(buffer, options)</strong>
|
||||
<ul>
|
||||
<li>Utility function that creates a [Skybox] from a KTX file.</li>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
|
||||
@@ -424,18 +416,10 @@
|
||||
<li><em>returns</em> <a href="#Texture">Texture</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.createTextureFromKtx1(buffer, options)</strong>
|
||||
<li><strong>engine.createTextureFromKtx(buffer, options)</strong>
|
||||
<ul>
|
||||
<li>Utility function that creates a [Texture] from a KTX1 file.</li>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX1 file contents</li>
|
||||
<li><em>options</em> Options dictionary.</li>
|
||||
<li><em>returns</em> <a href="#Texture">Texture</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.createTextureFromKtx2(buffer, options)</strong>
|
||||
<ul>
|
||||
<li>Utility function that creates a [Texture] from a KTX2 file.</li>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX2 file contents</li>
|
||||
<li>Utility function that creates a [Texture] from a KTX file.</li>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
|
||||
<li><em>options</em> Options dictionary.</li>
|
||||
<li><em>returns</em> <a href="#Texture">Texture</a></li>
|
||||
</ul>
|
||||
@@ -569,26 +553,57 @@
|
||||
<li><em>entities</em> array of entities</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setAmbientOcclusionOptions()</strong></li>
|
||||
<li><strong>engine.setBloomOptions()</strong></li>
|
||||
<li><strong>engine.setAmbientOcclusionOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: radius, power, bias, resolution, intensity, quality.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setBloomOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, strength, resolution, anomorphism, levels, blendMode, threshold, highlight.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setClearOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: clearColor, clear, discard.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setDepthOfFieldOptions()</strong></li>
|
||||
<li><strong>engine.setFogOptions()</strong></li>
|
||||
<li><strong>engine.setGuardBandOptions()</strong></li>
|
||||
<li><strong>engine.setMultiSampleAntiAliasingOptions()</strong></li>
|
||||
<li><strong>engine.setScreenSpaceReflectionsOptions()</strong></li>
|
||||
<li><strong>engine.setDepthOfFieldOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: cocScale, maxApertureDiameter, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setFogOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: distance, maximumOpacity, height, heightFalloff, color, density, inScatteringStart,</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setMultiSampleAntiAliasingOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, sampleCount, customResolve.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setScreenSpaceReflectionsOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: thickness, bias, maxDistance, stride, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setShadowOptions(instance, overrides)</strong>
|
||||
<ul>
|
||||
<li><em>instance</em> Instance of a light component obtained from <code>getInstance</code>.</li>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: mapSize, shadowCascades, constantBias, normalBias, shadowFar, shadowNearHint, shadowFarHint, stable, polygonOffsetConstant, polygonOffsetSlope, \</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setTemporalAntiAliasingOptions()</strong></li>
|
||||
<li><strong>engine.setVignetteOptions()</strong></li>
|
||||
<li><strong>engine.setTemporalAntiAliasingOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: filterWidth, feedback, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>engine.setVignetteOptions(overrides)</strong>
|
||||
<ul>
|
||||
<li><em>overrides</em> Dictionary with one or more of the following properties: midPoint, roundness, feather, color, enabled.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
@@ -603,11 +618,11 @@
|
||||
</ul>
|
||||
<p>To create an entity with no components, use <a href="#EntityManager">EntityManager</a>.
|
||||
TODO: It would be better to expose these as JS numbers rather than as JS objects.
|
||||
This would also be more consistent with Filament's Java bindings.</p>
|
||||
This would also be more consistent with Filament's Java bindings.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='EntityManager' href='#EntityManager'>EntityManager</a></h2>
|
||||
<p>Singleton used for constructing entities in Filament's ECS.</p>
|
||||
<p>Singleton used for constructing entities in Filament's ECS.</p>
|
||||
<ul>
|
||||
<li><strong>entityManager.create()</strong>
|
||||
<ul>
|
||||
@@ -712,9 +727,15 @@ wrapper rather than interacting with <code>Ktx1Bundle</code> directly.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='KtxInfo' href='#KtxInfo'>KtxInfo</a></h2>
|
||||
<p>Property accessor for KTX1 header.</p>
|
||||
<p>Property accessor for KTX header.</p>
|
||||
<ul>
|
||||
<li><strong>ktxInfo.createAsset(buffer)</strong>
|
||||
<li><strong>ktxInfo.createAssetFromBinary(buffer)</strong>
|
||||
<ul>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a></li>
|
||||
<li><em>returns</em> an instance of <a href="#FilamentAsset">FilamentAsset</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>ktxInfo.createAssetFromJson(buffer)</strong>
|
||||
<ul>
|
||||
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a></li>
|
||||
<li><em>returns</em> an instance of <a href="#FilamentAsset">FilamentAsset</a></li>
|
||||
@@ -741,7 +762,7 @@ properties.</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='PixelBufferDescriptor' href='#PixelBufferDescriptor'>PixelBufferDescriptor</a></h2>
|
||||
@@ -779,11 +800,11 @@ properties.</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='Renderer' href='#Renderer'>Renderer</a></h2>
|
||||
<p>Represents the platform's native window.</p>
|
||||
<p>Represents the platform's native window.</p>
|
||||
<ul>
|
||||
<li><strong>renderer.render(swapChain, view)</strong>
|
||||
<ul>
|
||||
@@ -802,7 +823,7 @@ properties.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='SwapChain' href='#SwapChain'>SwapChain</a></h2>
|
||||
<p>Represents the platform's native rendering surface.</p>
|
||||
<p>Represents the platform's native rendering surface.</p>
|
||||
<p>See also the <a href="#Engine">Engine</a> methods <code>createSwapChain</code> and <code>destroySwapChain</code>.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
@@ -846,7 +867,7 @@ properties.</p>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
|
||||
</div>
|
||||
<div class='classdoc'>
|
||||
<h2>class <a id='VertexBuffer' href='#VertexBuffer'>VertexBuffer</a></h2>
|
||||
@@ -943,7 +964,7 @@ See also the <a href="#Engine">Engine</a> methods <code>createView</code> and <c
|
||||
<ul>
|
||||
<li><strong>assets</strong>
|
||||
<ul>
|
||||
<li>Array of strings containing URL's of required assets.</li>
|
||||
<li>Array of strings containing URL's of required assets.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>onDone</strong>
|
||||
@@ -953,7 +974,7 @@ See also the <a href="#Engine">Engine</a> methods <code>createView</code> and <c
|
||||
</li>
|
||||
<li><strong>onFetched</strong>
|
||||
<ul>
|
||||
<li>optional callback that's invoked after each asset is downloaded.</li>
|
||||
<li>optional callback that's invoked after each asset is downloaded.</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1000,7 +1021,7 @@ useful for compressed textures. For example, some platforms accept ETC and other
|
||||
<ul>
|
||||
<li><strong>assets</strong>
|
||||
<ul>
|
||||
<li>Array of strings containing URL's of required assets.</li>
|
||||
<li>Array of strings containing URL's of required assets.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>onready</strong>
|
||||
@@ -1009,12 +1030,12 @@ useful for compressed textures. For example, some platforms accept ETC and other
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>All JavaScript clients must call the init function, passing in a list of asset URL's and a
|
||||
<p>All JavaScript clients must call the init function, passing in a list of asset URL's and a
|
||||
callback. This callback gets invoked only after all assets have been downloaded and the Filament
|
||||
WebAssembly module has been loaded. Clients should only pass asset URL's that absolutely must
|
||||
WebAssembly module has been loaded. Clients should only pass asset URL's that absolutely must
|
||||
be ready at initialization time.
|
||||
When the callback is called, each downloaded asset is available in the <code>Filament.assets</code> global
|
||||
object, which contains a mapping from URL's to Uint8Array objects.</p>
|
||||
object, which contains a mapping from URL's to Uint8Array objects.</p>
|
||||
</div>
|
||||
<div class='funcdoc'>
|
||||
<h2>function <a id='loadMathExtensions' href='#loadMathExtensions'>loadMathExtensions</a>()</h2>
|
||||
@@ -1064,13 +1085,6 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='ColorGrading$LutFormat' href='#ColorGrading$LutFormat'>ColorGrading$LutFormat</a></h2>
|
||||
<ul>
|
||||
<li>INTEGER</li>
|
||||
<li>FLOAT</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='ColorGrading$QualityLevel' href='#ColorGrading$QualityLevel'>ColorGrading$QualityLevel</a></h2>
|
||||
<ul>
|
||||
<li>LOW</li>
|
||||
@@ -1126,10 +1140,6 @@ This defines the following functions:</p>
|
||||
<li>DXT1_RGBA</li>
|
||||
<li>DXT3_RGBA</li>
|
||||
<li>DXT5_RGBA</li>
|
||||
<li>DXT1_SRGB</li>
|
||||
<li>DXT1_SRGBA</li>
|
||||
<li>DXT3_SRGBA</li>
|
||||
<li>DXT5_SRGBA</li>
|
||||
<li>RGBA_ASTC_4x4</li>
|
||||
<li>RGBA_ASTC_5x4</li>
|
||||
<li>RGBA_ASTC_5x5</li>
|
||||
@@ -1170,13 +1180,6 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='FeatureLevel' href='#FeatureLevel'>FeatureLevel</a></h2>
|
||||
<ul>
|
||||
<li>FEATURE_LEVEL_1</li>
|
||||
<li>FEATURE_LEVEL_2</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='Frustum$Plane' href='#Frustum$Plane'>Frustum$Plane</a></h2>
|
||||
<ul>
|
||||
<li>LEFT</li>
|
||||
@@ -1195,23 +1198,6 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='Ktx2Reader$Result' href='#Ktx2Reader$Result'>Ktx2Reader$Result</a></h2>
|
||||
<ul>
|
||||
<li>SUCCESS</li>
|
||||
<li>COMPRESSED_TRANSCODE_FAILURE</li>
|
||||
<li>UNCOMPRESSED_TRANSCODE_FAILURE</li>
|
||||
<li>FORMAT_UNSUPPORTED</li>
|
||||
<li>FORMAT_ALREADY_REQUESTED</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='Ktx2Reader$TransferFunction' href='#Ktx2Reader$TransferFunction'>Ktx2Reader$TransferFunction</a></h2>
|
||||
<ul>
|
||||
<li>LINEAR</li>
|
||||
<li>sRGB</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='LightManager$Type' href='#LightManager$Type'>LightManager$Type</a></h2>
|
||||
<ul>
|
||||
<li>SUN</li>
|
||||
@@ -1289,6 +1275,7 @@ This defines the following functions:</p>
|
||||
<li>LINE_STRIP</li>
|
||||
<li>TRIANGLES</li>
|
||||
<li>TRIANGLE_STRIP</li>
|
||||
<li>NONE</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
@@ -1308,27 +1295,6 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='StencilFace' href='#StencilFace'>StencilFace</a></h2>
|
||||
<ul>
|
||||
<li>FRONT</li>
|
||||
<li>BACK</li>
|
||||
<li>FRONT_AND_BACK</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='StencilOperation' href='#StencilOperation'>StencilOperation</a></h2>
|
||||
<ul>
|
||||
<li>KEEP</li>
|
||||
<li>ZERO</li>
|
||||
<li>REPLACE</li>
|
||||
<li>INCR_CLAMP</li>
|
||||
<li>INCR_WRAP</li>
|
||||
<li>DECR_CLAMP</li>
|
||||
<li>DECR_WRAP</li>
|
||||
<li>INVERT</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='Texture$CubemapFace' href='#Texture$CubemapFace'>Texture$CubemapFace</a></h2>
|
||||
<ul>
|
||||
<li>POSITIVE_X</li>
|
||||
@@ -1411,10 +1377,6 @@ This defines the following functions:</p>
|
||||
<li>DXT1_RGBA</li>
|
||||
<li>DXT3_RGBA</li>
|
||||
<li>DXT5_RGBA</li>
|
||||
<li>DXT1_SRGB</li>
|
||||
<li>DXT1_SRGBA</li>
|
||||
<li>DXT3_SRGBA</li>
|
||||
<li>DXT5_SRGBA</li>
|
||||
<li>RGBA_ASTC_4x4</li>
|
||||
<li>RGBA_ASTC_5x4</li>
|
||||
<li>RGBA_ASTC_5x5</li>
|
||||
@@ -1466,14 +1428,6 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='TransparencyMode' href='#TransparencyMode'>TransparencyMode</a></h2>
|
||||
<ul>
|
||||
<li>DEFAULT</li>
|
||||
<li>TWO_PASSES_ONE_SIDE</li>
|
||||
<li>TWO_PASSES_TWO_SIDES</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='VertexAttribute' href='#VertexAttribute'>VertexAttribute</a></h2>
|
||||
<ul>
|
||||
<li>POSITION</li>
|
||||
@@ -1540,6 +1494,43 @@ This defines the following functions:</p>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='View$AntiAliasing' href='#View$AntiAliasing'>View$AntiAliasing</a></h2>
|
||||
<ul>
|
||||
<li>NONE</li>
|
||||
<li>FXAA</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='View$BlendMode' href='#View$BlendMode'>View$BlendMode</a></h2>
|
||||
<ul>
|
||||
<li>OPAQUE</li>
|
||||
<li>TRANSLUCENT</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='View$BloomOptions$BlendMode' href='#View$BloomOptions$BlendMode'>View$BloomOptions$BlendMode</a></h2>
|
||||
<ul>
|
||||
<li>ADD</li>
|
||||
<li>INTERPOLATE</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='View$DepthOfFieldOptions$Filter' href='#View$DepthOfFieldOptions$Filter'>View$DepthOfFieldOptions$Filter</a></h2>
|
||||
<ul>
|
||||
<li>NONE</li>
|
||||
<li>MEDIAN</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='View$QualityLevel' href='#View$QualityLevel'>View$QualityLevel</a></h2>
|
||||
<ul>
|
||||
<li>LOW</li>
|
||||
<li>MEDIUM</li>
|
||||
<li>HIGH</li>
|
||||
<li>ULTRA</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='enumdoc'>
|
||||
<h2>enum <a id='WrapMode' href='#WrapMode'>WrapMode</a></h2>
|
||||
<ul>
|
||||
<li>CLAMP_TO_EDGE</li>
|
||||
|
||||
Binary file not shown.
+20
-27
@@ -16,14 +16,17 @@ canvas { touch-action: none; width: 100%; height: 100%; }
|
||||
<script src="gl-matrix-min.js"></script>
|
||||
<script>
|
||||
|
||||
const albedo_suffix = Filament.getSupportedFormatSuffix('astc s3tc_srgb');
|
||||
const texture_suffix = Filament.getSupportedFormatSuffix('etc');
|
||||
|
||||
const env = 'default_env'
|
||||
const ibl_url = `${env}/${env}_ibl.ktx`;
|
||||
const sky_url = `${env}/${env}_skybox.ktx`;
|
||||
const albedo_url = `albedo.ktx2`;
|
||||
const ao_url = `ao.ktx2`;
|
||||
const metallic_url = `metallic.ktx2`;
|
||||
const normal_url = `normal.ktx2`;
|
||||
const roughness_url = `roughness.ktx2`;
|
||||
const albedo_url = `albedo${albedo_suffix}.ktx`;
|
||||
const ao_url = `ao${texture_suffix}.ktx`;
|
||||
const metallic_url = `metallic${texture_suffix}.ktx`;
|
||||
const normal_url = `normal${texture_suffix}.ktx`;
|
||||
const roughness_url = `roughness${texture_suffix}.ktx`;
|
||||
const filamat_url = 'textured.filamat';
|
||||
const filamesh_url = 'suzanne.filamesh';
|
||||
|
||||
@@ -38,13 +41,12 @@ Filament.init([
|
||||
ibl_url,
|
||||
sky_url
|
||||
], () => {
|
||||
window.AttributeType = Filament.VertexBuffer$AttributeType;
|
||||
window.Format = Filament.Texture$InternalFormat;
|
||||
window.Fov = Filament.Camera$Fov;
|
||||
window.IndexType = Filament.IndexBuffer$IndexType;
|
||||
window.LightType = Filament.LightManager$Type;
|
||||
window.PrimitiveType = Filament.RenderableManager$PrimitiveType;
|
||||
window.VertexAttribute = Filament.VertexAttribute;
|
||||
window.AttributeType = Filament.VertexBuffer$AttributeType;
|
||||
window.PrimitiveType = Filament.RenderableManager$PrimitiveType;
|
||||
window.IndexType = Filament.IndexBuffer$IndexType;
|
||||
window.Fov = Filament.Camera$Fov;
|
||||
window.LightType = Filament.LightManager$Type;
|
||||
window.app = new App(document.getElementsByTagName('canvas')[0]);
|
||||
});
|
||||
|
||||
@@ -66,11 +68,11 @@ class App {
|
||||
.build(engine, sunlight);
|
||||
this.scene.addEntity(sunlight);
|
||||
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx1(ibl_url);
|
||||
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
|
||||
this.scene.setIndirectLight(indirectLight);
|
||||
indirectLight.setIntensity(80000);
|
||||
|
||||
const skybox = engine.createSkyFromKtx1(sky_url);
|
||||
const skybox = engine.createSkyFromKtx(sky_url);
|
||||
this.scene.setSkybox(skybox);
|
||||
|
||||
const material = engine.createMaterial(filamat_url);
|
||||
@@ -81,20 +83,11 @@ class App {
|
||||
Filament.MagFilter.LINEAR,
|
||||
Filament.WrapMode.CLAMP_TO_EDGE);
|
||||
|
||||
// Filament requests support for the following extensions, but none are guaranteed.
|
||||
// WEBGL_compressed_texture_s3tc, WEBGL_compressed_texture_s3tc_srgb
|
||||
// WEBGL_compressed_texture_astc, WEBGL_compressed_texture_etc
|
||||
const albedo = engine.createTextureFromKtx2(albedo_url, {
|
||||
srgb: true,
|
||||
formats: [ Format.DXT5_RGBA, Format.DXT5_SRGBA, Format.ETC2_EAC_SRGBA8 ]
|
||||
});
|
||||
|
||||
console.assert(albedo, "Unable to create albedo texture.")
|
||||
|
||||
const roughness = engine.createTextureFromKtx2(roughness_url);
|
||||
const metallic = engine.createTextureFromKtx2(metallic_url);
|
||||
const ao = engine.createTextureFromKtx2(ao_url);
|
||||
const normal = engine.createTextureFromKtx2(normal_url);
|
||||
const albedo = engine.createTextureFromKtx(albedo_url, {srgb: true});
|
||||
const roughness = engine.createTextureFromKtx(roughness_url);
|
||||
const metallic = engine.createTextureFromKtx(metallic_url);
|
||||
const normal = engine.createTextureFromKtx(normal_url);
|
||||
const ao = engine.createTextureFromKtx(ao_url);
|
||||
|
||||
matinstance.setTextureParameter('albedo', albedo, sampler)
|
||||
matinstance.setTextureParameter('roughness', roughness, sampler)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+155
-155
@@ -10,7 +10,7 @@
|
||||
textures.</p>
|
||||
<p>For starters, create a text file called <code>redball.html</code> and copy over the HTML that we used in the
|
||||
<a href="tutorial_triangle.html">previous tutorial</a>. Change the last script tag from <code>triangle.js</code> to <code>redball.js</code>.</p>
|
||||
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
|
||||
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
|
||||
appropriate <a href="//github.com/google/filament/releases">Filament release</a>. You should choose the
|
||||
archive that corresponds to your development machine rather than the one for web, and the version
|
||||
that matches the <code>unpkg.com/filament@x.x.x</code> url in the script tag of <code>redball.html</code> (you may check
|
||||
@@ -19,7 +19,7 @@ out the last available release of <a href="https://www.npmjs.com/package/filamen
|
||||
<p>The <code>matc</code> tool consumes a text file containing a high-level description of a PBR material, and
|
||||
produces a binary material package that contains shader code and associated metadata. For more
|
||||
information, see the official document describing the <a href="https://google.github.io/filament/Materials.md.html">Filament Material System</a>.</p>
|
||||
<p>Let's try out <code>matc</code>. Create the following file in your favorite text editor and call it
|
||||
<p>Let's try out <code>matc</code>. Create the following file in your favorite text editor and call it
|
||||
<code>plastic.mat</code>.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>material {
|
||||
name : Lit,
|
||||
@@ -47,10 +47,10 @@ fragment {
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc -a opengl -p mobile -o plastic.filamat plastic.mat
|
||||
</pre></div>
|
||||
|
||||
<p>You should now have a material archive in your working directory, which we'll use later in the
|
||||
<p>You should now have a material archive in your working directory, which we'll use later in the
|
||||
tutorial.</p>
|
||||
<h2>Bake environment map</h2>
|
||||
<p>Next we'll use Filament's <code>cmgen</code> tool to consume a HDR environment map in latlong format, and
|
||||
<p>Next we'll use Filament's <code>cmgen</code> tool to consume a HDR environment map in latlong format, and
|
||||
produce two cubemap files: a mipmapped IBL and a blurry skybox.</p>
|
||||
<p>Download <a href="//github.com/google/filament/blob/main/third_party/environments/pillars_2k.hdr">pillars_2k.hdr</a>, then invoke the following command in your terminal.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen -x pillars_2k --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=256</span> --extract-blur<span style="color: #666666">=0</span>.1 pillars_2k.hdr
|
||||
@@ -61,84 +61,84 @@ well as a text file with spherical harmonics coefficients. You can discard the t
|
||||
IBL KTX contains these coefficients in its metadata.</p>
|
||||
<h2>Create JavaScript</h2>
|
||||
<p>Next, create <code>redball.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">'pillars_2k'</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">'plastic.filamat'</span><span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'pillars_2k'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'plastic.filamat'</span>
|
||||
|
||||
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>ibl_url,<span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.VertexAttribute<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexAttribute;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.AttributeType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer$AttributeType;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.PrimitiveType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.RenderableManager$PrimitiveType;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.IndexType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer$IndexType;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.LightType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.LightManager$Type;<span style="color: #bbbbbb"></span>
|
||||
Filament.init([ filamat_url, ibl_url, sky_url ], () => {
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
|
||||
<span style="color: #008000">window</span>.VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
|
||||
<span style="color: #008000">window</span>.AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
|
||||
<span style="color: #008000">window</span>.PrimitiveType <span style="color: #666666">=</span> Filament.RenderableManager$PrimitiveType;
|
||||
<span style="color: #008000">window</span>.IndexType <span style="color: #666666">=</span> Filament.IndexBuffer$IndexType;
|
||||
<span style="color: #008000">window</span>.Fov <span style="color: #666666">=</span> Filament.Camera$Fov;
|
||||
<span style="color: #008000">window</span>.LightType <span style="color: #666666">=</span> Filament.LightManager$Type;
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(canvas);<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"> </span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> canvas <span style="color: #666666">=</span> <span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(canvas);
|
||||
} );
|
||||
|
||||
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createScene();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">class</span> App {
|
||||
<span style="color: #008000; font-weight: bold">constructor</span>(canvas) {
|
||||
<span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</span> canvas;
|
||||
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
|
||||
<span style="color: #008000; font-weight: bold">const</span> scene <span style="color: #666666">=</span> engine.createScene();
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create material</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create material</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span>
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSwapChain();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createRenderer();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createCamera(Filament.EntityManager.get().create());<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createView();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(scene);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> engine.createCamera(Filament.EntityManager.get().create());
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> engine.createView();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(scene);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
|
||||
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>radians<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Date</span>.now()<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">10000</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>vec3.rotateY(eye,<span style="color: #bbbbbb"> </span>eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>radians);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
render() {
|
||||
<span style="color: #008000; font-weight: bold">const</span> eye <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>], center <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>], up <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>];
|
||||
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">10000</span>;
|
||||
vec3.rotateY(eye, eye, center, radians);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye, center, up);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
|
||||
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>Fov.VERTICAL);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"></span>
|
||||
resize() {
|
||||
<span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
|
||||
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>, width <span style="color: #666666">/</span> height, <span style="color: #666666">1.0</span>, <span style="color: #666666">10.0</span>, Fov.VERTICAL);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>The above boilerplate should be familiar to you from the previous tutorial, although it loads in a
|
||||
new set of assets. We also added some animation to the camera.</p>
|
||||
<p>Next let's create a material instance from the package that we built at the beginning the tutorial.
|
||||
<p>Next let's create a material instance from the package that we built at the beginning the tutorial.
|
||||
Replace the <strong>create material</strong> comment with the following snippet.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createMaterial(filamat_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> material <span style="color: #666666">=</span> engine.createMaterial(filamat_url);
|
||||
<span style="color: #008000; font-weight: bold">const</span> matinstance <span style="color: #666666">=</span> material.createInstance();
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>red<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0.8</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>];<span style="color: #bbbbbb"></span>
|
||||
matinstance.setColor3Parameter(<span style="color: #BA2121">'baseColor'</span>,<span style="color: #bbbbbb"> </span>Filament.RgbType.sRGB,<span style="color: #bbbbbb"> </span>red);<span style="color: #bbbbbb"></span>
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'roughness'</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.5</span>);<span style="color: #bbbbbb"></span>
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'clearCoat'</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>);<span style="color: #bbbbbb"></span>
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'clearCoatRoughness'</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.3</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> red <span style="color: #666666">=</span> [<span style="color: #666666">0.8</span>, <span style="color: #666666">0.0</span>, <span style="color: #666666">0.0</span>];
|
||||
matinstance.setColor3Parameter(<span style="color: #BA2121">'baseColor'</span>, Filament.RgbType.sRGB, red);
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'roughness'</span>, <span style="color: #666666">0.5</span>);
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'clearCoat'</span>, <span style="color: #666666">1.0</span>);
|
||||
matinstance.setFloatParameter(<span style="color: #BA2121">'clearCoatRoughness'</span>, <span style="color: #666666">0.3</span>);
|
||||
</pre></div>
|
||||
|
||||
<p>The next step is to create a renderable for the sphere. To help with this, we'll use the <code>IcoSphere</code>
|
||||
<p>The next step is to create a renderable for the sphere. To help with this, we'll use the <code>IcoSphere</code>
|
||||
utility class, whose constructor takes a LOD. Its job is to subdivide an icosadedron, producing
|
||||
three arrays:</p>
|
||||
<ul>
|
||||
@@ -147,137 +147,137 @@ three arrays:</p>
|
||||
as quaternions.</li>
|
||||
<li><code>icosphere.triangles</code> Uint16Array with triangle indices.</li>
|
||||
</ul>
|
||||
<p>Let's go ahead use these arrays to build the vertex buffer and index buffer. Replace <strong>create
|
||||
<p>Let's go ahead use these arrays to build the vertex buffer and index buffer. Replace <strong>create
|
||||
sphere</strong> with the following snippet.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>renderable<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
|
||||
scene.addEntity(renderable);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> renderable <span style="color: #666666">=</span> Filament.EntityManager.get().create();
|
||||
scene.addEntity(renderable);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>icosphere<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.IcoSphere(<span style="color: #666666">5</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> icosphere <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.IcoSphere(<span style="color: #666666">5</span>);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>vb<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.vertexCount(icosphere.vertices.length<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.bufferCount(<span style="color: #666666">2</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.POSITION,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>AttributeType.FLOAT3,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.TANGENTS,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>AttributeType.SHORT4,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.normalized(VertexAttribute.TANGENTS)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> vb <span style="color: #666666">=</span> Filament.VertexBuffer.Builder()
|
||||
.vertexCount(icosphere.vertices.length <span style="color: #666666">/</span> <span style="color: #666666">3</span>)
|
||||
.bufferCount(<span style="color: #666666">2</span>)
|
||||
.attribute(VertexAttribute.POSITION, <span style="color: #666666">0</span>, AttributeType.FLOAT3, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>)
|
||||
.attribute(VertexAttribute.TANGENTS, <span style="color: #666666">1</span>, AttributeType.SHORT4, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>)
|
||||
.normalized(VertexAttribute.TANGENTS)
|
||||
.build(engine);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ib<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.indexCount(icosphere.triangles.length)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.bufferType(IndexType.USHORT)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ib <span style="color: #666666">=</span> Filament.IndexBuffer.Builder()
|
||||
.indexCount(icosphere.triangles.length)
|
||||
.bufferType(IndexType.USHORT)
|
||||
.build(engine);
|
||||
|
||||
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>icosphere.vertices);<span style="color: #bbbbbb"></span>
|
||||
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>icosphere.tangents);<span style="color: #bbbbbb"></span>
|
||||
ib.setBuffer(engine,<span style="color: #bbbbbb"> </span>icosphere.triangles);<span style="color: #bbbbbb"></span>
|
||||
vb.setBufferAt(engine, <span style="color: #666666">0</span>, icosphere.vertices);
|
||||
vb.setBufferAt(engine, <span style="color: #666666">1</span>, icosphere.tangents);
|
||||
ib.setBuffer(engine, icosphere.triangles);
|
||||
|
||||
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.boundingBox({<span style="color: #bbbbbb"> </span>center<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>],<span style="color: #bbbbbb"> </span>halfExtent<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>]<span style="color: #bbbbbb"> </span>})<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.material(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>matinstance)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.geometry(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>PrimitiveType.TRIANGLES,<span style="color: #bbbbbb"> </span>vb,<span style="color: #bbbbbb"> </span>ib)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>renderable);<span style="color: #bbbbbb"></span>
|
||||
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)
|
||||
.boundingBox({ center<span style="color: #666666">:</span> [<span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>], halfExtent<span style="color: #666666">:</span> [<span style="color: #666666">1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">1</span>] })
|
||||
.material(<span style="color: #666666">0</span>, matinstance)
|
||||
.geometry(<span style="color: #666666">0</span>, PrimitiveType.TRIANGLES, vb, ib)
|
||||
.build(engine, renderable);
|
||||
</pre></div>
|
||||
|
||||
<p>At this point, the app is rendering a sphere, but it is black so it doesn't show up. To prove that
|
||||
<p>At this point, the app is rendering a sphere, but it is black so it doesn't show up. To prove that
|
||||
the sphere is there, you can try changing the background color to blue via <code>setClearColor</code>, like we
|
||||
did in the first tutorial.</p>
|
||||
<h2>Add lighting</h2>
|
||||
<p>In this section we will create some directional light sources, as well as an image-based light (IBL)
|
||||
defined by one of the KTX files we built at the start of the demo. First, replace the <strong>create
|
||||
lights</strong> comment with the following snippet.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sunlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
|
||||
scene.addEntity(sunlight);<span style="color: #bbbbbb"></span>
|
||||
Filament.LightManager.Builder(LightType.SUN)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.color([<span style="color: #666666">0.98</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.92</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.89</span>])<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">110000.0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">0.6</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-0.8</span>])<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.sunAngularRadius(<span style="color: #666666">1.9</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.sunHaloSize(<span style="color: #666666">10.0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.sunHaloFalloff(<span style="color: #666666">80.0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>sunlight);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> sunlight <span style="color: #666666">=</span> Filament.EntityManager.get().create();
|
||||
scene.addEntity(sunlight);
|
||||
Filament.LightManager.Builder(LightType.SUN)
|
||||
.color([<span style="color: #666666">0.98</span>, <span style="color: #666666">0.92</span>, <span style="color: #666666">0.89</span>])
|
||||
.intensity(<span style="color: #666666">110000.0</span>)
|
||||
.direction([<span style="color: #666666">0.6</span>, <span style="color: #666666">-1.0</span>, <span style="color: #666666">-0.8</span>])
|
||||
.sunAngularRadius(<span style="color: #666666">1.9</span>)
|
||||
.sunHaloSize(<span style="color: #666666">10.0</span>)
|
||||
.sunHaloFalloff(<span style="color: #666666">80.0</span>)
|
||||
.build(engine, sunlight);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>backlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
|
||||
scene.addEntity(backlight);<span style="color: #bbbbbb"></span>
|
||||
Filament.LightManager.Builder(LightType.DIRECTIONAL)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>])<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>backlight);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> backlight <span style="color: #666666">=</span> Filament.EntityManager.get().create();
|
||||
scene.addEntity(backlight);
|
||||
Filament.LightManager.Builder(LightType.DIRECTIONAL)
|
||||
.direction([<span style="color: #666666">-1</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>])
|
||||
.intensity(<span style="color: #666666">50000.0</span>)
|
||||
.build(engine, backlight);
|
||||
</pre></div>
|
||||
|
||||
<p>The <code>SUN</code> light source is similar to the <code>DIRECTIONAL</code> light source, but has some extra
|
||||
parameters because Filament will automatically draw a disk into the skybox.</p>
|
||||
<p>Next we need to create an <code>IndirectLight</code> object from the KTX IBL. One way of doing this is the
|
||||
following (don't type this out, there's an easier way).</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>format<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataFormat.RGB;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>datatype<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataType.UINT_10F_11F_11F_REV;<span style="color: #bbbbbb"></span>
|
||||
following (don't type this out, there's an easier way).</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> format <span style="color: #666666">=</span> Filament.PixelDataFormat.RGB;
|
||||
<span style="color: #008000; font-weight: bold">const</span> datatype <span style="color: #666666">=</span> Filament.PixelDataType.UINT_10F_11F_11F_REV;
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[ibl_url]);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>iblktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(ibl_package);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[ibl_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(ibl_package);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibltex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.width(iblktx.info().pixelWidth)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.height(iblktx.info().pixelHeight)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.levels(iblktx.getNumMipLevels())<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibltex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(iblktx.info().pixelWidth)
|
||||
.height(iblktx.info().pixelHeight)
|
||||
.levels(iblktx.getNumMipLevels())
|
||||
.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
|
||||
.format(Filament.Texture$InternalFormat.RGBA8)
|
||||
.build(engine);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">for</span><span style="color: #bbbbbb"> </span>(<span style="color: #008000; font-weight: bold">let</span><span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666"><</span><span style="color: #bbbbbb"> </span>iblktx.getNumMipLevels();<span style="color: #bbbbbb"> </span><span style="color: #666666">++</span>level)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getCubeBlob(level).getBytes();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>ibltex.setImageCube(engine,<span style="color: #bbbbbb"> </span>level,<span style="color: #bbbbbb"> </span>pixelbuffer);<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">for</span> (<span style="color: #008000; font-weight: bold">let</span> level <span style="color: #666666">=</span> <span style="color: #666666">0</span>; level <span style="color: #666666"><</span> iblktx.getNumMipLevels(); <span style="color: #666666">++</span>level) {
|
||||
<span style="color: #008000; font-weight: bold">const</span> uint8array <span style="color: #666666">=</span> iblktx.getCubeBlob(level).getBytes();
|
||||
<span style="color: #008000; font-weight: bold">const</span> pixelbuffer <span style="color: #666666">=</span> Filament.PixelBuffer(uint8array, format, datatype);
|
||||
ibltex.setImageCube(engine, level, pixelbuffer);
|
||||
}
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shstring<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getMetadata(<span style="color: #BA2121">'sh'</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shfloats<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>shstring.split(<span style="color: #A45A77">/\s/</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">9</span><span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> shstring <span style="color: #666666">=</span> iblktx.getMetadata(<span style="color: #BA2121">'sh'</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #A45A77">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndirectLight.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.reflections(ibltex)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.irradianceSh(<span style="color: #666666">3</span>,<span style="color: #bbbbbb"> </span>shfloats)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> Filament.IndirectLight.Builder()
|
||||
.reflections(ibltex)
|
||||
.irradianceSh(<span style="color: #666666">3</span>, shfloats)
|
||||
.intensity(<span style="color: #666666">50000.0</span>)
|
||||
.build(engine);
|
||||
|
||||
scene.setIndirectLight(indirectLight);<span style="color: #bbbbbb"></span>
|
||||
scene.setIndirectLight(indirectLight);
|
||||
</pre></div>
|
||||
|
||||
<p>Filament provides a JavaScript utility to make this simpler,
|
||||
simply replace the <strong>create IBL</strong> comment with the following snippet.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createIblFromKtx1(ibl_url);<span style="color: #bbbbbb"></span>
|
||||
indirectLight.setIntensity(<span style="color: #666666">50000</span>);<span style="color: #bbbbbb"></span>
|
||||
scene.setIndirectLight(indirectLight);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> engine.createIblFromKtx(ibl_url);
|
||||
indirectLight.setIntensity(<span style="color: #666666">50000</span>);
|
||||
scene.setIndirectLight(indirectLight);
|
||||
</pre></div>
|
||||
|
||||
<h2>Add background</h2>
|
||||
<p>At this point you can run the demo and you should see a red plastic ball against a black background.
|
||||
Without a skybox, the reflections on the ball are not representative of its surroundings.
|
||||
Here's one way to create a texture for the skybox:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[sky_url]);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skyktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(sky_package);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skytex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.width(skyktx.info().pixelWidth)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.height(skyktx.info().pixelHeight)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.levels(<span style="color: #666666">1</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
Here's one way to create a texture for the skybox:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> sky_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[sky_url]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(sky_package);
|
||||
<span style="color: #008000; font-weight: bold">const</span> skytex <span style="color: #666666">=</span> Filament.Texture.Builder()
|
||||
.width(skyktx.info().pixelWidth)
|
||||
.height(skyktx.info().pixelHeight)
|
||||
.levels(<span style="color: #666666">1</span>)
|
||||
.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
|
||||
.format(Filament.Texture$InternalFormat.RGBA8)
|
||||
.build(engine);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>skyktx.getCubeBlob(<span style="color: #666666">0</span>).getBytes();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);<span style="color: #bbbbbb"></span>
|
||||
skytex.setImageCube(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>pixelbuffer);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> uint8array <span style="color: #666666">=</span> skyktx.getCubeBlob(<span style="color: #666666">0</span>).getBytes();
|
||||
<span style="color: #008000; font-weight: bold">const</span> pixelbuffer <span style="color: #666666">=</span> Filament.PixelBuffer(uint8array, format, datatype);
|
||||
skytex.setImageCube(engine, <span style="color: #666666">0</span>, pixelbuffer);
|
||||
</pre></div>
|
||||
|
||||
<p>Filament provides a Javascript utility to make this easier.
|
||||
Replace <strong>create skybox</strong> with the following.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSkyFromKtx1(sky_url);<span style="color: #bbbbbb"></span>
|
||||
scene.setSkybox(skybox);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> skybox <span style="color: #666666">=</span> engine.createSkyFromKtx(sky_url);
|
||||
scene.setSkybox(skybox);
|
||||
</pre></div>
|
||||
|
||||
<p>That's it, we now have a shiny red ball floating in an environment! The complete JavaScript file is
|
||||
<p>That's it, we now have a shiny red ball floating in an environment! The complete JavaScript file is
|
||||
available <a href="tutorial_redball.js">here</a>.</p>
|
||||
<p>In the <a href="tutorial_suzanne.html">next tutorial</a>, we'll take a closer look at textures and interaction.</p>
|
||||
<p>In the <a href="tutorial_suzanne.html">next tutorial</a>, we'll take a closer look at textures and interaction.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -70,10 +70,10 @@ class App {
|
||||
.direction([-1, 0, 1])
|
||||
.intensity(50000.0)
|
||||
.build(engine, backlight);
|
||||
const indirectLight = engine.createIblFromKtx1(ibl_url);
|
||||
const indirectLight = engine.createIblFromKtx(ibl_url);
|
||||
indirectLight.setIntensity(50000);
|
||||
scene.setIndirectLight(indirectLight);
|
||||
const skybox = engine.createSkyFromKtx1(sky_url);
|
||||
const skybox = engine.createSkyFromKtx(sky_url);
|
||||
scene.setSkybox(skybox);
|
||||
this.swapChain = engine.createSwapChain();
|
||||
this.renderer = engine.createRenderer();
|
||||
|
||||
+102
-102
@@ -8,18 +8,18 @@
|
||||
<div class="demo_frame"><iframe src="demo_suzanne.html"></iframe><a href="demo_suzanne.html">🔗</a></div>
|
||||
<p>This tutorial will describe how to create the <strong>suzanne</strong> demo, introducing you to compressed
|
||||
textures, mipmap generation, asynchronous texture loading, and trackball rotation.</p>
|
||||
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a>, you'll need to use the command-line tools that can be found in
|
||||
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a>, you'll need to use the command-line tools that can be found in
|
||||
the appropriate <a href="//github.com/google/filament/releases">Filament release</a> for your development machine. In addition to <code>matc</code> and <code>cmgen</code>,
|
||||
we'll also be using <code>filamesh</code> and <code>mipgen</code>.</p>
|
||||
we'll also be using <code>filamesh</code> and <code>mipgen</code>.</p>
|
||||
<h2>Create filamesh file</h2>
|
||||
<p>Filament does not have an asset loading system, but it does provide a binary mesh format
|
||||
called <code>filamesh</code> for simple use cases. Let's create a compressed filamesh file for suzanne by
|
||||
called <code>filamesh</code> for simple use cases. Let's create a compressed filamesh file for suzanne by
|
||||
converting <a href="https://github.com/google/filament/blob/main/assets/models/monkey/monkey.obj">this OBJ file</a>:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>filamesh --compress monkey.obj suzanne.filamesh
|
||||
</pre></div>
|
||||
|
||||
<h2>Create mipmapped textures</h2>
|
||||
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
|
||||
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
|
||||
non-compressed variants for each texture, since not all platforms support the same compression
|
||||
formats. First copy over the PNG files from the <a href="https://github.com/google/filament/blob/main/assets/models/monkey">monkey folder</a>, then do:</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
|
||||
@@ -45,10 +45,10 @@ mipgen --grayscale ao.png ao.ktx
|
||||
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
|
||||
</pre></div>
|
||||
|
||||
<p>For more information on mipgen's arguments and supported formats, do <code>mipgen --help</code>.</p>
|
||||
<p>In a production setting, you'd want to invoke these commands with a script or build system.</p>
|
||||
<p>For more information on mipgen's arguments and supported formats, do <code>mipgen --help</code>.</p>
|
||||
<p>In a production setting, you'd want to invoke these commands with a script or build system.</p>
|
||||
<h2>Bake environment map</h2>
|
||||
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a> we need to use Filament's <code>cmgen</code> tool to produce cubemap files.</p>
|
||||
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a> we need to use Filament's <code>cmgen</code> tool to produce cubemap files.</p>
|
||||
<p>Download <a href="//github.com/google/filament/blob/main/third_party/environments/venetian_crossroads_2k.hdr">venetian_crossroads_2k.hdr</a>, then invoke the following commands in your terminal.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=64</span> --extract-blur<span style="color: #666666">=0</span>.1 venetian_crossroads_2k.hdr
|
||||
<span style="color: #008000">cd</span> venetian* ; mv venetian*_ibl.ktx venetian_crossroads_2k_skybox_tiny.ktx ; <span style="color: #008000">cd</span> -
|
||||
@@ -60,7 +60,7 @@ cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="c
|
||||
|
||||
<h2>Define textured material</h2>
|
||||
<p>You might recall the <code>filamat</code> file we generated in the previous tutorial for red plastic. For this
|
||||
demo, we'll create a material that uses textures for several parameters.</p>
|
||||
demo, we'll create a material that uses textures for several parameters.</p>
|
||||
<p>Create the following text file and call it <code>textured.mat</code>. Note that our material definition now
|
||||
requires a <code>uv0</code> attribute.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>material {
|
||||
@@ -101,65 +101,65 @@ materials, consult the official document describing the <a href="https://google.
|
||||
<p>Create a text file called <code>suzanne.html</code> and copy over the HTML that we used in the <a href="tutorial_redball.html">previous
|
||||
tutorial</a>. Change the last script tag from <code>redball.js</code> to <code>suzanne.js</code>. Next, create <code>suzanne.js</code>
|
||||
with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span><span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span>
|
||||
|
||||
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>filamesh_url,<span style="color: #bbbbbb"> </span>sky_small_url,<span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>]);<span style="color: #bbbbbb"></span>
|
||||
});<span style="color: #bbbbbb"></span>
|
||||
Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () => {
|
||||
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>]);
|
||||
});
|
||||
|
||||
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createScene();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">class</span> App {
|
||||
<span style="color: #008000; font-weight: bold">constructor</span>(canvas) {
|
||||
<span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</span> canvas;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createScene();
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createMaterial(filamat_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> material <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createMaterial(filamat_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance <span style="color: #666666">=</span> material.createInstance();
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.suzanne<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>filamesh.renderable;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url, <span style="color: #008000; font-weight: bold">this</span>.matinstance);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.suzanne <span style="color: #666666">=</span> filamesh.renderable;
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span>
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createCamera(Filament.EntityManager.get().create());<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createView();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createCamera(Filament.EntityManager.get().create());
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createView();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> eye <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>], center <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>], up <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>];
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye, center, up);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
|
||||
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
render() {
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
|
||||
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);<span style="color: #bbbbbb"></span>
|
||||
resize() {
|
||||
<span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
|
||||
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov,<span style="color: #bbbbbb"> </span>fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666"><</span><span style="color: #bbbbbb"> </span><span style="color: #666666">1</span><span style="color: #bbbbbb"> </span><span style="color: #666666">?</span><span style="color: #bbbbbb"> </span>Fov.HORIZONTAL<span style="color: #bbbbbb"> </span><span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>Fov.VERTICAL;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>aspect,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>fov);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> aspect <span style="color: #666666">=</span> width <span style="color: #666666">/</span> height;
|
||||
<span style="color: #008000; font-weight: bold">const</span> Fov <span style="color: #666666">=</span> Filament.Camera$Fov, fov <span style="color: #666666">=</span> aspect <span style="color: #666666"><</span> <span style="color: #666666">1</span> <span style="color: #666666">?</span> Fov.HORIZONTAL <span style="color: #666666">:</span> Fov.VERTICAL;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>, aspect, <span style="color: #666666">1.0</span>, <span style="color: #666666">10.0</span>, fov);
|
||||
}
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>Our app will only require a subset of assets to be present for <code>App</code> construction. We'll download
|
||||
<p>Our app will only require a subset of assets to be present for <code>App</code> construction. We'll download
|
||||
the other assets after construction. By using a progressive loading strategy, we can reduce the
|
||||
perceived load time.</p>
|
||||
<p>Next we need to supply the URLs for various assets. This is actually a bit tricky, because different
|
||||
@@ -172,65 +172,65 @@ string -- which might be empty.</p>
|
||||
<p>In our case, we know that our web server will have <code>astc</code> and <code>s3tc</code> variants for albedo, and <code>etc</code>
|
||||
variants for the other textures. The uncompressed variants (empty string) are always available as a
|
||||
last resort. Go ahead and replace the <strong>declare asset URLs</strong> comment with the following snippet.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'astc s3tc_srgb'</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>texture_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'etc'</span>);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> albedo_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'astc s3tc_srgb'</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> texture_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">'etc'</span>);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">'venetian_crossroads_2k'</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_small_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_large_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">'textured.filamat'</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">'suzanne.filamesh'</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">'venetian_crossroads_2k'</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_small_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> sky_large_url <span style="color: #666666">=</span> <span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo_url <span style="color: #666666">=</span> <span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao_url <span style="color: #666666">=</span> <span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic_url <span style="color: #666666">=</span> <span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal_url <span style="color: #666666">=</span> <span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness_url <span style="color: #666666">=</span> <span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">'textured.filamat'</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> filamesh_url <span style="color: #666666">=</span> <span style="color: #BA2121">'suzanne.filamesh'</span>;
|
||||
</pre></div>
|
||||
|
||||
<h2>Create skybox and IBL</h2>
|
||||
<p>Next, let's create the low-resolution skybox and IBL in the <code>App</code> constructor.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_small_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createIblFromKtx1(ibl_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.indirectLight.setIntensity(<span style="color: #666666">100000</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setIndirectLight(<span style="color: #008000; font-weight: bold">this</span>.indirectLight);<span style="color: #bbbbbb"></span>
|
||||
<p>Next, let's create the low-resolution skybox and IBL in the <code>App</code> constructor.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_small_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.indirectLight <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createIblFromKtx(ibl_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.indirectLight.setIntensity(<span style="color: #666666">100000</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setIndirectLight(<span style="color: #008000; font-weight: bold">this</span>.indirectLight);
|
||||
</pre></div>
|
||||
|
||||
<p>This allows users to see a reasonable background fairly quickly, before larger assets have finished
|
||||
loading in.</p>
|
||||
<h2>Fetch assets asychronously</h2>
|
||||
<p>Next we'll invoke the <code>Filament.fetch</code> function from within the app constructor. This function is
|
||||
<p>Next we'll invoke the <code>Filament.fetch</code> function from within the app constructor. This function is
|
||||
very similar to <code>Filament.init</code>. It takes a list of asset URLs and a callback function that triggers
|
||||
when the assets have finished downloading.</p>
|
||||
<p>In our callback, we'll make several <code>setTextureParameter</code> calls on the material instance, then we'll
|
||||
<p>In our callback, we'll make several <code>setTextureParameter</code> calls on the material instance, then we'll
|
||||
recreate the skybox using a higher-resolution texture. As a last step we unhide the renderable that
|
||||
was created in the app constructor.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>Filament.fetch([sky_large_url,<span style="color: #bbbbbb"> </span>albedo_url,<span style="color: #bbbbbb"> </span>roughness_url,<span style="color: #bbbbbb"> </span>metallic_url,<span style="color: #bbbbbb"> </span>normal_url,<span style="color: #bbbbbb"> </span>ao_url],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(albedo_url,<span style="color: #bbbbbb"> </span>{srgb<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">true</span>});<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(roughness_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(metallic_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(normal_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(ao_url);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>Filament.fetch([sky_large_url, albedo_url, roughness_url, metallic_url, normal_url, ao_url], () => {
|
||||
<span style="color: #008000; font-weight: bold">const</span> albedo <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(albedo_url, {srgb<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
|
||||
<span style="color: #008000; font-weight: bold">const</span> roughness <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(roughness_url);
|
||||
<span style="color: #008000; font-weight: bold">const</span> metallic <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(metallic_url);
|
||||
<span style="color: #008000; font-weight: bold">const</span> normal <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(normal_url);
|
||||
<span style="color: #008000; font-weight: bold">const</span> ao <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(ao_url);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sampler<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.TextureSampler(<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>Filament.MinFilter.LINEAR_MIPMAP_LINEAR,<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>Filament.MagFilter.LINEAR,<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>Filament.WrapMode.CLAMP_TO_EDGE);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> sampler <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.TextureSampler(
|
||||
Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
|
||||
Filament.MagFilter.LINEAR,
|
||||
Filament.WrapMode.CLAMP_TO_EDGE);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'albedo'</span>,<span style="color: #bbbbbb"> </span>albedo,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'roughness'</span>,<span style="color: #bbbbbb"> </span>roughness,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'metallic'</span>,<span style="color: #bbbbbb"> </span>metallic,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'normal'</span>,<span style="color: #bbbbbb"> </span>normal,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'ao'</span>,<span style="color: #bbbbbb"> </span>ao,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'albedo'</span>, albedo, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'roughness'</span>, roughness, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'metallic'</span>, metallic, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'normal'</span>, normal, sampler);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">'ao'</span>, ao, sampler);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_large_url);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_large_url);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
|
||||
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.suzanne);<span style="color: #bbbbbb"></span>
|
||||
});<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.suzanne);
|
||||
});
|
||||
</pre></div>
|
||||
|
||||
<h2>Introduce trackball rotation</h2>
|
||||
@@ -241,16 +241,16 @@ listens for drag events and computes a rotation matrix.</p>
|
||||
|
||||
<p>Next, replace the <strong>initialize gltumble</strong> and <strong>apply gltumble matrix</strong> comments with the following
|
||||
two code snippets.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.trackball<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Trackball(canvas,<span style="color: #bbbbbb"> </span>{startSpin<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0.035</span>});<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.trackball <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Trackball(canvas, {startSpin<span style="color: #666666">:</span> <span style="color: #666666">0.035</span>});
|
||||
</pre></div>
|
||||
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>tcm<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>inst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.suzanne);<span style="color: #bbbbbb"></span>
|
||||
tcm.setTransform(inst,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.trackball.getMatrix());<span style="color: #bbbbbb"></span>
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
|
||||
<span style="color: #008000; font-weight: bold">const</span> inst <span style="color: #666666">=</span> tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.suzanne);
|
||||
tcm.setTransform(inst, <span style="color: #008000; font-weight: bold">this</span>.trackball.getMatrix());
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
|
||||
</pre></div>
|
||||
|
||||
<p>That's it, we now have a fast-loading interactive demo. The complete JavaScript file is available
|
||||
<p>That's it, we now have a fast-loading interactive demo. The complete JavaScript file is available
|
||||
<a href="tutorial_suzanne.js">here</a>.</p>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -23,9 +23,9 @@ class App {
|
||||
this.matinstance = material.createInstance();
|
||||
const filamesh = this.engine.loadFilamesh(filamesh_url, this.matinstance);
|
||||
this.suzanne = filamesh.renderable;
|
||||
this.skybox = this.engine.createSkyFromKtx1(sky_small_url);
|
||||
this.skybox = this.engine.createSkyFromKtx(sky_small_url);
|
||||
this.scene.setSkybox(this.skybox);
|
||||
this.indirectLight = this.engine.createIblFromKtx1(ibl_url);
|
||||
this.indirectLight = this.engine.createIblFromKtx(ibl_url);
|
||||
this.indirectLight.setIntensity(100000);
|
||||
this.scene.setIndirectLight(this.indirectLight);
|
||||
this.trackball = new Trackball(canvas, {
|
||||
@@ -33,13 +33,13 @@ class App {
|
||||
});
|
||||
Filament.fetch([sky_large_url, albedo_url, roughness_url, metallic_url, normal_url, ao_url],
|
||||
() => {
|
||||
const albedo = this.engine.createTextureFromKtx1(albedo_url, {
|
||||
const albedo = this.engine.createTextureFromKtx(albedo_url, {
|
||||
srgb: true
|
||||
});
|
||||
const roughness = this.engine.createTextureFromKtx1(roughness_url);
|
||||
const metallic = this.engine.createTextureFromKtx1(metallic_url);
|
||||
const normal = this.engine.createTextureFromKtx1(normal_url);
|
||||
const ao = this.engine.createTextureFromKtx1(ao_url);
|
||||
const roughness = this.engine.createTextureFromKtx(roughness_url);
|
||||
const metallic = this.engine.createTextureFromKtx(metallic_url);
|
||||
const normal = this.engine.createTextureFromKtx(normal_url);
|
||||
const ao = this.engine.createTextureFromKtx(ao_url);
|
||||
const sampler = new Filament.TextureSampler(Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
|
||||
Filament.MagFilter.LINEAR, Filament.WrapMode.CLAMP_TO_EDGE);
|
||||
this.matinstance.setTextureParameter('albedo', albedo, sampler);
|
||||
@@ -49,7 +49,7 @@ class App {
|
||||
this.matinstance.setTextureParameter('ao', ao, sampler);
|
||||
// Replace low-res skybox with high-res skybox.
|
||||
this.engine.destroySkybox(this.skybox);
|
||||
this.skybox = this.engine.createSkyFromKtx1(sky_large_url);
|
||||
this.skybox = this.engine.createSkyFromKtx(sky_large_url);
|
||||
this.scene.setSkybox(this.skybox);
|
||||
this.scene.addEntity(this.suzanne);
|
||||
});
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
<div class="demo_frame"><iframe src="demo_triangle.html"></iframe><a href="demo_triangle.html">🔗</a></div>
|
||||
<h2>Literate programming</h2>
|
||||
<p>The markdown source for this tutorial is not only used to generate this
|
||||
web page, it's also used to generate the JavaScript for the above demo.
|
||||
web page, it's also used to generate the JavaScript for the above demo.
|
||||
We use a small Python script for weaving (generating HTML) and tangling
|
||||
(generating JS). In the code samples, you'll often see
|
||||
(generating JS). In the code samples, you'll often see
|
||||
<code>// TODO: <some task></code>. These are special markers that get replaced by
|
||||
subsequent code blocks.</p>
|
||||
<h2>Start your project</h2>
|
||||
@@ -48,36 +48,36 @@ a mobile-friendly page with a full-screen canvas.</p>
|
||||
<li><code>triangle.js</code> will contain your application code.</li>
|
||||
</ul>
|
||||
<p>Go ahead and create <code>triangle.js</code> with the following content.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">class</span> App {
|
||||
<span style="color: #008000; font-weight: bold">constructor</span>() {
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
|
||||
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">'resize'</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
render() {
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
resize() {
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span>
|
||||
}
|
||||
}
|
||||
|
||||
Filament.init([<span style="color: #BA2121">'triangle.filamat'</span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=><span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App()<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"> </span>);<span style="color: #bbbbbb"></span>
|
||||
Filament.init([<span style="color: #BA2121">'triangle.filamat'</span>], () => { <span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App() } );
|
||||
</pre></div>
|
||||
|
||||
<p>The two calls to <code>bind()</code> allow us to pass instance methods as callbacks for animation and resize
|
||||
events.</p>
|
||||
<p><code>Filament.init()</code> consumes two things: a list of asset URLs and a callback.</p>
|
||||
<p>The callback will be triggered only after all assets finish downloading and the Filament module has
|
||||
become ready. In our callback, we simply instantiated the <code>App</code> object, since we'll do most of the
|
||||
become ready. In our callback, we simply instantiated the <code>App</code> object, since we'll do most of the
|
||||
work in its constructor. We also set the app instance into a <code>Window</code> property to make it accessible
|
||||
from the developer console.</p>
|
||||
<p>Go ahead and download <a href="triangle.filamat">triangle.filamat</a> and place it in your project folder.
|
||||
This is a <em>material package</em>, which is a binary file that contains shaders and other bits of data
|
||||
that define a PBR material. We'll learn more about material packages in the next tutorial.</p>
|
||||
that define a PBR material. We'll learn more about material packages in the next tutorial.</p>
|
||||
<h2>Spawn a local server</h2>
|
||||
<p>Because of CORS restrictions, your web app cannot fetch the material package directly from the
|
||||
file system. One way around this is to create a temporary server using Python or node:</p>
|
||||
@@ -88,23 +88,23 @@ npx http-server -p <span style="color: #666666">8000</span> <span style="colo
|
||||
|
||||
<p>To see if this works, navigate to <a href="http://localhost:8000">http://localhost:8000</a> and check if you
|
||||
can load the page without any errors appearing in the developer console.</p>
|
||||
<p>Take care not to use Python's simple server in production since it does not serve WebAssembly files
|
||||
<p>Take care not to use Python's simple server in production since it does not serve WebAssembly files
|
||||
with the correct MIME type.</p>
|
||||
<h2>Create the Engine and Scene</h2>
|
||||
<p>We now have a basic skeleton that can respond to paint and resize events. Let's start adding
|
||||
<p>We now have a basic skeleton that can respond to paint and resize events. Let's start adding
|
||||
Filament objects to the app. Insert the following code into the top of the app constructor.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(<span style="color: #008000; font-weight: bold">this</span>.canvas);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</span> <span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">'canvas'</span>)[<span style="color: #666666">0</span>];
|
||||
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(<span style="color: #008000; font-weight: bold">this</span>.canvas);
|
||||
</pre></div>
|
||||
|
||||
<p>The above snippet creates the <code>Engine</code> by passing it a canvas DOM object. The engine needs the
|
||||
canvas in order to create a WebGL 2.0 context in its contructor.</p>
|
||||
<p>The engine is a factory for many Filament entities, including <code>Scene</code>, which is a flat container of
|
||||
entities. Let's go ahead and create a scene, then add a blank entity called <code>triangle</code> into the
|
||||
entities. Let's go ahead and create a scene, then add a blank entity called <code>triangle</code> into the
|
||||
scene.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createScene();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.triangle<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.triangle);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.scene <span style="color: #666666">=</span> engine.createScene();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.triangle <span style="color: #666666">=</span> Filament.EntityManager.get().create();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.triangle);
|
||||
</pre></div>
|
||||
|
||||
<p>Filament uses an <a href="//en.wikipedia.org/wiki/Entity-component-system">Entity-Component System</a>.
|
||||
@@ -112,30 +112,30 @@ The triangle entity in the above snippet does not yet have an associated compone
|
||||
tutorial we will make it into a <em>renderable</em>. Renderables are entities that have associated draw
|
||||
calls.</p>
|
||||
<h2>Construct typed arrays</h2>
|
||||
<p>Next we'll create two typed arrays: a positions array with XY coordinates for each vertex, and a
|
||||
<p>Next we'll create two typed arrays: a positions array with XY coordinates for each vertex, and a
|
||||
colors array with a 32-bit word for each vertex.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>TRIANGLE_POSITIONS<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Float32Array</span>([<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">2</span><span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>),<span style="color: #bbbbbb"> </span><span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">2</span><span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>),<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">4</span><span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>),<span style="color: #bbbbbb"> </span><span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">4</span><span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>),<span style="color: #bbbbbb"></span>
|
||||
]);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> TRIANGLE_POSITIONS <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Float32Array</span>([
|
||||
<span style="color: #666666">1</span>, <span style="color: #666666">0</span>,
|
||||
<span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">2</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>), <span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">2</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>),
|
||||
<span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">4</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>), <span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">4</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>),
|
||||
]);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>TRIANGLE_COLORS<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Uint32Array</span>([<span style="color: #666666">0xffff0000</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0xff00ff00</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0xff0000ff</span>]);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> TRIANGLE_COLORS <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Uint32Array</span>([<span style="color: #666666">0xffff0000</span>, <span style="color: #666666">0xff00ff00</span>, <span style="color: #666666">0xff0000ff</span>]);
|
||||
</pre></div>
|
||||
|
||||
<p>Next we'll use the positions and colors buffers to create a single <code>VertexBuffer</code> object.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>VertexAttribute<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexAttribute;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>AttributeType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer$AttributeType;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.vertexCount(<span style="color: #666666">3</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.bufferCount(<span style="color: #666666">2</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.POSITION,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>AttributeType.FLOAT2,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">8</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.COLOR,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>AttributeType.UBYTE4,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.normalized(VertexAttribute.COLOR)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<p>Next we'll use the positions and colors buffers to create a single <code>VertexBuffer</code> object.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
|
||||
<span style="color: #008000; font-weight: bold">const</span> AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb <span style="color: #666666">=</span> Filament.VertexBuffer.Builder()
|
||||
.vertexCount(<span style="color: #666666">3</span>)
|
||||
.bufferCount(<span style="color: #666666">2</span>)
|
||||
.attribute(VertexAttribute.POSITION, <span style="color: #666666">0</span>, AttributeType.FLOAT2, <span style="color: #666666">0</span>, <span style="color: #666666">8</span>)
|
||||
.attribute(VertexAttribute.COLOR, <span style="color: #666666">1</span>, AttributeType.UBYTE4, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>)
|
||||
.normalized(VertexAttribute.COLOR)
|
||||
.build(engine);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>TRIANGLE_POSITIONS);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>TRIANGLE_COLORS);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine, <span style="color: #666666">0</span>, TRIANGLE_POSITIONS);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine, <span style="color: #666666">1</span>, TRIANGLE_COLORS);
|
||||
</pre></div>
|
||||
|
||||
<p>The above snippet first creates aliases for two enum types, then constructs the vertex buffer using
|
||||
@@ -147,74 +147,74 @@ self-documenting.</p>
|
||||
<p>Our app sets up two buffer slots in the vertex buffer, and each slot is associated with a single
|
||||
attribute. Alternatively, we could have interleaved or concatenated these attributes into a single
|
||||
buffer slot.</p>
|
||||
<p>Next we'll construct an index buffer. The index buffer for our triangle is trivial: it simply holds
|
||||
<p>Next we'll construct an index buffer. The index buffer for our triangle is trivial: it simply holds
|
||||
the integers 0,1,2.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.ib<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer.Builder()<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.indexCount(<span style="color: #666666">3</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.bufferType(Filament.IndexBuffer$IndexType.USHORT)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.ib <span style="color: #666666">=</span> Filament.IndexBuffer.Builder()
|
||||
.indexCount(<span style="color: #666666">3</span>)
|
||||
.bufferType(Filament.IndexBuffer$IndexType.USHORT)
|
||||
.build(engine);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">this</span>.ib.setBuffer(engine,<span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Uint16Array</span>([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">2</span>]));<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.ib.setBuffer(engine, <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Uint16Array</span>([<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">2</span>]));
|
||||
</pre></div>
|
||||
|
||||
<p>Note that constructing an index buffer is similar to constructing a vertex buffer, but it only has
|
||||
one buffer slot, and it can only contain two types of data (USHORT or UINT).</p>
|
||||
<h2>Finish up initialization</h2>
|
||||
<p>Next let's construct an actual <code>Material</code> from the material package that was downloaded (the
|
||||
<p>Next let's construct an actual <code>Material</code> from the material package that was downloaded (the
|
||||
material is an object; the package is just a binary blob), then extract the default
|
||||
<code>MaterialInstance</code> from the material object. Material instances have concrete values for their
|
||||
parameters, and they can be bound to renderables. We'll learn more about material instances in the
|
||||
parameters, and they can be bound to renderables. We'll learn more about material instances in the
|
||||
next tutorial.</p>
|
||||
<p>After extracting the material instance, we can finally create a renderable component for the
|
||||
triangle by setting up a bounding box and passing in the vertex and index buffers.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>mat<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createMaterial(<span style="color: #BA2121">'triangle.filamat'</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>matinst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>mat.getDefaultInstance();<span style="color: #bbbbbb"></span>
|
||||
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.boundingBox({<span style="color: #bbbbbb"> </span>center<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>],<span style="color: #bbbbbb"> </span>halfExtent<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>]<span style="color: #bbbbbb"> </span>})<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.material(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>matinst)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.geometry(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>Filament.RenderableManager$PrimitiveType.TRIANGLES,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.vb,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.ib)<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.triangle);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> mat <span style="color: #666666">=</span> engine.createMaterial(<span style="color: #BA2121">'triangle.filamat'</span>);
|
||||
<span style="color: #008000; font-weight: bold">const</span> matinst <span style="color: #666666">=</span> mat.getDefaultInstance();
|
||||
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)
|
||||
.boundingBox({ center<span style="color: #666666">:</span> [<span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>], halfExtent<span style="color: #666666">:</span> [<span style="color: #666666">1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">1</span>] })
|
||||
.material(<span style="color: #666666">0</span>, matinst)
|
||||
.geometry(<span style="color: #666666">0</span>, Filament.RenderableManager$PrimitiveType.TRIANGLES, <span style="color: #008000; font-weight: bold">this</span>.vb, <span style="color: #008000; font-weight: bold">this</span>.ib)
|
||||
.build(engine, <span style="color: #008000; font-weight: bold">this</span>.triangle);
|
||||
</pre></div>
|
||||
|
||||
<p>Next let's wrap up the initialization routine by creating the swap chain, renderer, camera, and
|
||||
<p>Next let's wrap up the initialization routine by creating the swap chain, renderer, camera, and
|
||||
view.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSwapChain();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createRenderer();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createCamera(Filament.EntityManager.get().create());<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createView();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> engine.createCamera(Filament.EntityManager.get().create());
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> engine.createView();
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.2</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>],<span style="color: #bbbbbb"> </span>clear<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">true</span>});<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span> [<span style="color: #666666">0.0</span>, <span style="color: #666666">0.1</span>, <span style="color: #666666">0.2</span>, <span style="color: #666666">1.0</span>], clear<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.resize();
|
||||
</pre></div>
|
||||
|
||||
<p>At this point, we're done creating all Filament entities, and the code should run without errors.
|
||||
<p>At this point, we're done creating all Filament entities, and the code should run without errors.
|
||||
However the canvas is still blank!</p>
|
||||
<h2>Render and resize handlers</h2>
|
||||
<p>Recall that our App class has a skeletal render method, which the browser calls every time it needs
|
||||
to repaint. Often this is 60 times a second.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
|
||||
}<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render() {
|
||||
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
|
||||
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
|
||||
}
|
||||
</pre></div>
|
||||
|
||||
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
|
||||
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
|
||||
code to the top of the render method.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>radians<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Date</span>.now()<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">1000</span>;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>transform<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>mat4.fromRotation(mat4.create(),<span style="color: #bbbbbb"> </span>radians,<span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>]);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>tcm<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>inst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.triangle);<span style="color: #bbbbbb"></span>
|
||||
tcm.setTransform(inst,<span style="color: #bbbbbb"> </span>transform);<span style="color: #bbbbbb"></span>
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">1000</span>;
|
||||
<span style="color: #008000; font-weight: bold">const</span> transform <span style="color: #666666">=</span> mat4.fromRotation(mat4.create(), radians, [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>]);
|
||||
<span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
|
||||
<span style="color: #008000; font-weight: bold">const</span> inst <span style="color: #666666">=</span> tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.triangle);
|
||||
tcm.setTransform(inst, transform);
|
||||
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
|
||||
|
||||
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</span><span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
|
||||
</pre></div>
|
||||
|
||||
<p>The first half of our render method obtains the transform component of the triangle entity and uses
|
||||
@@ -225,19 +225,19 @@ that it wants to skip a frame, hence the <code>if</code> statement.</p>
|
||||
<p>One last step. Add the following code to the resize method. This adjusts the resolution of the
|
||||
rendering surface when the window size changes, taking <code>devicePixelRatio</code> into account for high-DPI
|
||||
displays. It also adjusts the camera frustum accordingly.</p>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);<span style="color: #bbbbbb"></span>
|
||||
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
|
||||
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
|
||||
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>Projection<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Projection;<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjection(Projection.ORTHO,<span style="color: #bbbbbb"> </span><span style="color: #666666">-</span>aspect,<span style="color: #bbbbbb"> </span>aspect,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>);<span style="color: #bbbbbb"></span>
|
||||
<span style="color: #008000; font-weight: bold">const</span> aspect <span style="color: #666666">=</span> width <span style="color: #666666">/</span> height;
|
||||
<span style="color: #008000; font-weight: bold">const</span> Projection <span style="color: #666666">=</span> Filament.Camera$Projection;
|
||||
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjection(Projection.ORTHO, <span style="color: #666666">-</span>aspect, aspect, <span style="color: #666666">-1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>);
|
||||
</pre></div>
|
||||
|
||||
<p>You should now have a spinning triangle! The completed JavaScript is available
|
||||
<a href="tutorial_triangle.js">here</a>.</p>
|
||||
<p>In the <a href="tutorial_redball.html">next tutorial</a>, we'll take a closer look at Filament materials and 3D rendering.</p>
|
||||
<p>In the <a href="tutorial_redball.html">next tutorial</a>, we'll take a closer look at Filament materials and 3D rendering.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -17,7 +17,6 @@ set(PUBLIC_HDRS
|
||||
include/filament/Camera.h
|
||||
include/filament/Color.h
|
||||
include/filament/ColorGrading.h
|
||||
include/filament/ColorSpace.h
|
||||
include/filament/DebugRegistry.h
|
||||
include/filament/Engine.h
|
||||
include/filament/Exposure.h
|
||||
@@ -54,7 +53,7 @@ set(SRCS
|
||||
src/BufferObject.cpp
|
||||
src/Camera.cpp
|
||||
src/Color.cpp
|
||||
src/ColorSpaceUtils.cpp
|
||||
src/ColorSpace.cpp
|
||||
src/Culler.cpp
|
||||
src/DFG.cpp
|
||||
src/DebugRegistry.cpp
|
||||
@@ -136,7 +135,7 @@ set(SRCS
|
||||
set(PRIVATE_HDRS
|
||||
src/Allocators.h
|
||||
src/BufferPoolAllocator.h
|
||||
src/ColorSpaceUtils.h
|
||||
src/ColorSpace.h
|
||||
src/Culler.h
|
||||
src/DFG.h
|
||||
src/FilamentAPI-impl.h
|
||||
|
||||
@@ -9,7 +9,6 @@ set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR})
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
set(PUBLIC_HDRS
|
||||
include/backend/AcquiredImage.h
|
||||
include/backend/BufferDescriptor.h
|
||||
include/backend/CallbackHandler.h
|
||||
include/backend/DriverApiForward.h
|
||||
@@ -37,12 +36,12 @@ set(SRCS
|
||||
src/noop/NoopDriver.cpp
|
||||
src/noop/PlatformNoop.cpp
|
||||
src/Platform.cpp
|
||||
src/PlatformFactory.cpp
|
||||
src/Program.cpp
|
||||
src/SamplerGroup.cpp
|
||||
)
|
||||
|
||||
set(PRIVATE_HDRS
|
||||
include/private/backend/AcquiredImage.h
|
||||
include/private/backend/CircularBuffer.h
|
||||
include/private/backend/CommandBufferQueue.h
|
||||
include/private/backend/CommandStream.h
|
||||
@@ -51,7 +50,6 @@ set(PRIVATE_HDRS
|
||||
include/private/backend/DriverApi.h
|
||||
include/private/backend/DriverAPI.inc
|
||||
include/private/backend/HandleAllocator.h
|
||||
include/private/backend/PlatformFactory.h
|
||||
include/private/backend/SamplerGroup.h
|
||||
src/CommandStreamDispatcher.h
|
||||
src/DataReshaper.h
|
||||
@@ -64,7 +62,6 @@ set(PRIVATE_HDRS
|
||||
|
||||
if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMENT_USE_SWIFTSHADER)
|
||||
list(APPEND SRCS
|
||||
include/backend/platforms/OpenGLPlatform.h
|
||||
src/opengl/gl_headers.cpp
|
||||
src/opengl/gl_headers.h
|
||||
src/opengl/GLUtils.cpp
|
||||
@@ -79,6 +76,7 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
src/opengl/OpenGLPlatform.cpp
|
||||
src/opengl/OpenGLTimerQuery.cpp
|
||||
src/opengl/OpenGLTimerQuery.h
|
||||
include/private/backend/OpenGLPlatform.h
|
||||
)
|
||||
if (EGL)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformEGL.cpp)
|
||||
@@ -152,7 +150,6 @@ endif()
|
||||
# See root CMakeLists.txt for platforms that support Vulkan
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
list(APPEND SRCS
|
||||
include/backend/platforms/VulkanPlatform.h
|
||||
src/vulkan/VulkanBlitter.cpp
|
||||
src/vulkan/VulkanBlitter.h
|
||||
src/vulkan/VulkanBuffer.cpp
|
||||
@@ -176,6 +173,7 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
src/vulkan/VulkanPipelineCache.cpp
|
||||
src/vulkan/VulkanPipelineCache.h
|
||||
src/vulkan/VulkanPlatform.cpp
|
||||
src/vulkan/VulkanPlatform.h
|
||||
src/vulkan/VulkanSamplerCache.cpp
|
||||
src/vulkan/VulkanSamplerCache.h
|
||||
src/vulkan/VulkanStagePool.cpp
|
||||
@@ -407,7 +405,6 @@ if (APPLE)
|
||||
backend
|
||||
getopt
|
||||
gtest
|
||||
filamat
|
||||
SPIRV
|
||||
spirv-cross-glsl)
|
||||
|
||||
|
||||
@@ -42,42 +42,11 @@
|
||||
*/
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
* Requests a SwapChain with an alpha channel.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
|
||||
|
||||
/**
|
||||
* This flag indicates that the swap chain may be used as a source surface
|
||||
* for reading back render results. This config flag must be set when creating
|
||||
* any SwapChain that will be used as the source for a blit operation.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
|
||||
|
||||
/**
|
||||
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
|
||||
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
|
||||
|
||||
/**
|
||||
* Indicates that the native window is a CVPixelBufferRef.
|
||||
*
|
||||
* This is only supported by the Metal backend. The CVPixelBuffer must be in the
|
||||
* kCVPixelFormatType_32BGRA format.
|
||||
*
|
||||
* It is not necessary to add an additional retain call before passing the pixel buffer to
|
||||
* Filament. Filament will call CVPixelBufferRetain during Engine::createSwapChain, and
|
||||
* CVPixelBufferRelease when the swap chain is destroyed.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
|
||||
|
||||
/**
|
||||
* Indicates that the SwapChain must automatically perform linear to srgb encoding.
|
||||
*/
|
||||
static constexpr uint64_t SWAP_CHAIN_CONFIG_SRGB_COLORSPACE = 0x10;
|
||||
|
||||
|
||||
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
|
||||
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
|
||||
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
|
||||
@@ -429,18 +398,6 @@ enum class CompressedPixelDataType : uint16_t {
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12,
|
||||
|
||||
// RGTC formats available with a GLES extension
|
||||
RED_RGTC1, // BC4 unsigned
|
||||
SIGNED_RED_RGTC1, // BC4 signed
|
||||
RED_GREEN_RGTC2, // BC5 unsigned
|
||||
SIGNED_RED_GREEN_RGTC2, // BC5 signed
|
||||
|
||||
// BPTC formats available with a GLES extension
|
||||
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
|
||||
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
|
||||
RGBA_BPTC_UNORM, // BC7
|
||||
SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB
|
||||
};
|
||||
|
||||
/** Supported texel formats
|
||||
@@ -595,18 +552,6 @@ enum class TextureFormat : uint16_t {
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12,
|
||||
|
||||
// RGTC formats available with a GLES extension
|
||||
RED_RGTC1, // BC4 unsigned
|
||||
SIGNED_RED_RGTC1, // BC4 signed
|
||||
RED_GREEN_RGTC2, // BC5 unsigned
|
||||
SIGNED_RED_GREEN_RGTC2, // BC5 signed
|
||||
|
||||
// BPTC formats available with a GLES extension
|
||||
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
|
||||
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
|
||||
RGBA_BPTC_UNORM, // BC7
|
||||
SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB
|
||||
};
|
||||
|
||||
//! Bitmask describing the intended Texture Usage
|
||||
@@ -687,7 +632,7 @@ static constexpr bool isSignedIntFormat(TextureFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
//! returns whether this format is a compressed format
|
||||
//! returns whether this format a compressed format
|
||||
static constexpr bool isCompressedFormat(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::EAC_R11;
|
||||
}
|
||||
@@ -697,7 +642,7 @@ static constexpr bool isETC2Compression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::EAC_R11 && format <= TextureFormat::ETC2_EAC_SRGBA8;
|
||||
}
|
||||
|
||||
//! returns whether this format is an S3TC compressed format
|
||||
//! returns whether this format is an ETC3 compressed format
|
||||
static constexpr bool isS3TCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::DXT1_RGB && format <= TextureFormat::DXT5_SRGBA;
|
||||
}
|
||||
@@ -706,16 +651,6 @@ static constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::DXT1_SRGB && format <= TextureFormat::DXT5_SRGBA;
|
||||
}
|
||||
|
||||
//! returns whether this format is an RGTC compressed format
|
||||
static constexpr bool isRGTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RED_RGTC1 && format <= TextureFormat::SIGNED_RED_GREEN_RGTC2;
|
||||
}
|
||||
|
||||
//! returns whether this format is an BPTC compressed format
|
||||
static constexpr bool isBPTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RGB_BPTC_SIGNED_FLOAT && format <= TextureFormat::SRGB_ALPHA_BPTC_UNORM;
|
||||
}
|
||||
|
||||
static constexpr bool isASTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RGBA_ASTC_4x4 && format <= TextureFormat::SRGB8_ALPHA8_ASTC_12x12;
|
||||
}
|
||||
|
||||
@@ -23,28 +23,22 @@
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
namespace filament::backend {
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
class Driver;
|
||||
|
||||
/**
|
||||
* Platform is an interface that abstracts how the backend (also referred to as Driver) is
|
||||
* created. The backend provides several common Platform concrete implementations, which are
|
||||
* selected automatically. It is possible however to provide a custom Platform when creating
|
||||
* the filament Engine.
|
||||
*/
|
||||
class UTILS_PUBLIC Platform {
|
||||
public:
|
||||
struct SwapChain {};
|
||||
struct Fence {};
|
||||
struct Stream {};
|
||||
struct ExternalTexture {
|
||||
uintptr_t image = 0;
|
||||
};
|
||||
|
||||
struct DriverConfig {
|
||||
/*
|
||||
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
|
||||
* Driver clamps to valid values.
|
||||
*/
|
||||
size_t handleArenaSize = 0;
|
||||
size_t handleArenaSize = 0; // size of handle arena in bytes. Setting to 0 indicates default value is to be used. Driver clamps to valid values.
|
||||
};
|
||||
|
||||
virtual ~Platform() noexcept;
|
||||
@@ -68,8 +62,7 @@ public:
|
||||
*
|
||||
* @return nullptr on failure, or a pointer to the newly created driver.
|
||||
*/
|
||||
virtual backend::Driver* createDriver(void* sharedContext,
|
||||
const DriverConfig& driverConfig) noexcept = 0;
|
||||
virtual backend::Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Processes the platform's event queue when called from its primary event-handling thread.
|
||||
@@ -78,9 +71,39 @@ public:
|
||||
* on platforms that need it, such as macOS + OpenGL. Returns false if this is not the main
|
||||
* thread, or if the platform does not need to perform any special processing.
|
||||
*/
|
||||
virtual bool pumpEvents() noexcept;
|
||||
virtual bool pumpEvents() noexcept { return false; }
|
||||
};
|
||||
|
||||
|
||||
class UTILS_PUBLIC DefaultPlatform : public Platform {
|
||||
public:
|
||||
~DefaultPlatform() noexcept override;
|
||||
|
||||
/**
|
||||
* Creates a Platform configured for the requested backend if available
|
||||
*
|
||||
* @param backendHint Preferred backend, if not available the backend most suitable for the
|
||||
* underlying platform is returned and \p backendHint is updated
|
||||
* accordingly. Can't be nullptr.
|
||||
*
|
||||
* @return A pointer to the Platform object.
|
||||
*
|
||||
* @see destroy
|
||||
*/
|
||||
static DefaultPlatform* create(backend::Backend* backendHint) noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a Platform object returned by create()
|
||||
*
|
||||
* @param platform a reference (as a pointer) to the DefaultPlatform pointer to destroy.
|
||||
* \p platform is cleared upon return.
|
||||
*
|
||||
* @see create
|
||||
*/
|
||||
static void destroy(DefaultPlatform** platform) noexcept;
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# include/backend Headers
|
||||
|
||||
Headers in `include/backend/` are fully public, in particular they can be included in filament's
|
||||
public headers.
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
|
||||
#include <backend/AcquiredImage.h>
|
||||
#include <backend/Platform.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Driver;
|
||||
|
||||
/**
|
||||
* A Platform interface that creates an OpenGL backend.
|
||||
*
|
||||
* WARNING: None of the methods below are allowed to change the GL state and must restore it
|
||||
* upon return.
|
||||
*
|
||||
*/
|
||||
class OpenGLPlatform : public Platform {
|
||||
protected:
|
||||
|
||||
/*
|
||||
* Derived classes can use this to instantiate the default OpenGLDriver backend.
|
||||
* This is typically called from your implementation of createDriver()
|
||||
*/
|
||||
static Driver* createDefaultDriver(OpenGLPlatform* platform,
|
||||
void* sharedContext, const DriverConfig& driverConfig);
|
||||
|
||||
~OpenGLPlatform() noexcept override;
|
||||
|
||||
public:
|
||||
|
||||
struct ExternalTexture {
|
||||
unsigned int target; // GLenum target
|
||||
unsigned int id; // GLuint id
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by the driver to destroy the OpenGL context. This should clean up any windows
|
||||
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
|
||||
* called.
|
||||
*/
|
||||
virtual void terminate() noexcept = 0;
|
||||
|
||||
/**
|
||||
* Called by the driver to create a SwapChain for this driver.
|
||||
*
|
||||
* @param nativeWindow a token representing the native window. See concrete implementation
|
||||
* for details.
|
||||
* @param flags extra flags used by the implementation, see filament::SwapChain
|
||||
* @return The driver's SwapChain object.
|
||||
*
|
||||
*/
|
||||
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
|
||||
* The default implementation returns false.
|
||||
*
|
||||
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
|
||||
*/
|
||||
virtual bool isSRGBSwapChainSupported() const noexcept;
|
||||
|
||||
/**
|
||||
* Called by the driver create a headless SwapChain.
|
||||
*
|
||||
* @param width width of the buffer
|
||||
* @param height height of the buffer
|
||||
* @param flags extra flags used by the implementation, see filament::SwapChain
|
||||
* @return The driver's SwapChain object.
|
||||
*
|
||||
* TODO: we need a more generic way of passing construction parameters
|
||||
* A void* might be enough.
|
||||
*/
|
||||
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Called by the driver to destroys the SwapChain
|
||||
* @param swapChain SwapChain to be destroyed.
|
||||
*/
|
||||
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Called by the driver to establish the default FBO. The default implementation returns 0.
|
||||
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
|
||||
*/
|
||||
virtual uint32_t createDefaultRenderTarget() noexcept;
|
||||
|
||||
/**
|
||||
* Called by the driver to make the OpenGL context active on the calling thread and bind
|
||||
* the drawSwapChain to the default render target (FBO) created with createDefaultRenderTarget.
|
||||
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
|
||||
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
|
||||
*/
|
||||
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Called by the driver once the current frame finishes drawing. Typically, this should present
|
||||
* the drawSwapChain. This is for example where `eglMakeCurrent()` would be called.
|
||||
* @param swapChain the SwapChain to present.
|
||||
*/
|
||||
virtual void commit(SwapChain* swapChain) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Set the time the next committed buffer should be presented to the user at.
|
||||
*
|
||||
* @param presentationTimeInNanosecond time in the future in nanosecond. The clock used depends
|
||||
* on the concrete platform implementation.
|
||||
*/
|
||||
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Fence support
|
||||
|
||||
/**
|
||||
* Can this implementation create a Fence.
|
||||
* @return true if supported, false otherwise. The default implementation returns false.
|
||||
*/
|
||||
virtual bool canCreateFence() noexcept;
|
||||
|
||||
/**
|
||||
* Creates a Fence (e.g. eglCreateSyncKHR). This must be implemented if `canCreateFence`
|
||||
* returns true. Fences are used for frame pacing.
|
||||
*
|
||||
* @return A Fence object. The default implementation returns nullptr.
|
||||
*/
|
||||
virtual Fence* createFence() noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a Fence object. The default implementation does nothing.
|
||||
*
|
||||
* @param fence Fence to destroy.
|
||||
*/
|
||||
virtual void destroyFence(Fence* fence) noexcept;
|
||||
|
||||
/**
|
||||
* Waits on a Fence.
|
||||
*
|
||||
* @param fence Fence to wait on.
|
||||
* @param timeout Timeout.
|
||||
* @return Whether the fence signaled or timed out. See backend::FenceStatus.
|
||||
* The default implementation always return backend::FenceStatus::ERROR.
|
||||
*/
|
||||
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Streaming support
|
||||
|
||||
/**
|
||||
* Creates a Stream from a native Stream.
|
||||
*
|
||||
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
|
||||
*
|
||||
* @param nativeStream The native stream, this parameter depends on the concrete implementation.
|
||||
* @return A new Stream object.
|
||||
*/
|
||||
virtual Stream* createStream(void* nativeStream) noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a Stream.
|
||||
* @param stream Stream to destroy.
|
||||
*/
|
||||
virtual void destroyStream(Stream* stream) noexcept;
|
||||
|
||||
/**
|
||||
* The specified stream takes ownership of the texture (tname) object
|
||||
* Once attached, the texture is automatically updated with the Stream's content, which
|
||||
* could be a video stream for instance.
|
||||
*
|
||||
* @param stream Stream to take ownership of the texture
|
||||
* @param tname GL texture id to "bind" to the Stream.
|
||||
*/
|
||||
virtual void attach(Stream* stream, intptr_t tname) noexcept;
|
||||
|
||||
/**
|
||||
* Destroys the texture associated to the stream
|
||||
* @param stream Stream to detach from its texture
|
||||
*/
|
||||
virtual void detach(Stream* stream) noexcept;
|
||||
|
||||
/**
|
||||
* Updates the content of the texture attached to the stream.
|
||||
* @param stream Stream to update
|
||||
* @param timestamp Output parameter: Timestamp of the image bound to the texture.
|
||||
*/
|
||||
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept;
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// External Image support
|
||||
|
||||
/**
|
||||
* Creates an external texture handle. External textures don't have any parameters because
|
||||
* these are undefined until setExternalImage() is called.
|
||||
* @return a pointer to an ExternalTexture structure filled with valid token. However, the
|
||||
* implementation could just return { 0, GL_TEXTURE_2D } at this point. The actual
|
||||
* values can be delayed until setExternalImage.
|
||||
*/
|
||||
virtual ExternalTexture *createExternalImageTexture() noexcept;
|
||||
|
||||
/**
|
||||
* Destroys an external texture handle and associated data.
|
||||
* @param texture a pointer to the handle to destroy.
|
||||
*/
|
||||
virtual void destroyExternalImage(ExternalTexture* texture) noexcept;
|
||||
|
||||
// called on the application thread to allow Filament to take ownership of the image
|
||||
|
||||
/**
|
||||
* Takes ownership of the externalImage. The externalImage parameter depends on the Platform's
|
||||
* concrete implementation. Ownership is released when destroyExternalImage() is called.
|
||||
*
|
||||
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
|
||||
*
|
||||
* @param externalImage A token representing the platform's external image.
|
||||
* @see destroyExternalImage
|
||||
*/
|
||||
virtual void retainExternalImage(void* externalImage) noexcept;
|
||||
|
||||
/**
|
||||
* Called to bind the platform-specific externalImage to an ExternalTexture.
|
||||
* ExternalTexture::id is guaranteed to be bound when this method is called and ExternalTexture
|
||||
* is updated with new values for id/target if necessary.
|
||||
*
|
||||
* WARNING: this method is not allowed to change the bound texture, or must restore the previous
|
||||
* binding upon return. This is to avoid problem with a backend doing state caching.
|
||||
*
|
||||
* @param externalImage The platform-specific external image.
|
||||
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
|
||||
* @return true on success, false on error.
|
||||
*/
|
||||
virtual bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept;
|
||||
|
||||
/**
|
||||
* The method allows platforms to convert a user-supplied external image object into a new type
|
||||
* (e.g. HardwareBuffer => EGLImage). The default implementation returns source.
|
||||
* @param source Image to transform.
|
||||
* @return Transformed image.
|
||||
*/
|
||||
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
struct PlatformCocoaGLImpl;
|
||||
|
||||
/**
|
||||
* A concrete implementation of OpenGLPlatform that supports macOS's Cocoa.
|
||||
*/
|
||||
class PlatformCocoaGL : public OpenGLPlatform {
|
||||
public:
|
||||
PlatformCocoaGL();
|
||||
~PlatformCocoaGL() noexcept override;
|
||||
|
||||
protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
Driver* createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
// Currently returns 0
|
||||
int getOSVersion() const noexcept override;
|
||||
|
||||
bool pumpEvents() noexcept override;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
private:
|
||||
PlatformCocoaGLImpl* pImpl = nullptr;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
struct PlatformCocoaTouchGLImpl;
|
||||
|
||||
class PlatformCocoaTouchGL : public OpenGLPlatform {
|
||||
public:
|
||||
PlatformCocoaTouchGL();
|
||||
~PlatformCocoaTouchGL() noexcept;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
Driver* createDriver(void* sharedGLContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept final { return 0; }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
uint32_t createDefaultRenderTarget() noexcept override;
|
||||
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
|
||||
void destroyExternalImage(ExternalTexture* texture) noexcept override;
|
||||
void retainExternalImage(void* externalImage) noexcept override;
|
||||
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
|
||||
|
||||
private:
|
||||
PlatformCocoaTouchGLImpl* pImpl = nullptr;
|
||||
};
|
||||
|
||||
using ContextManager = PlatformCocoaTouchGL;
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
|
||||
|
||||
#include <backend/platforms/PlatformEGL.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class ExternalStreamManagerAndroid;
|
||||
|
||||
/**
|
||||
* A concrete implementation of OpenGLPlatform and subclass of PlatformEGL that supports
|
||||
* EGL on Android. It adds Android streaming functionality to PlatformEGL.
|
||||
*/
|
||||
class PlatformEGLAndroid : public PlatformEGL {
|
||||
public:
|
||||
|
||||
PlatformEGLAndroid() noexcept;
|
||||
~PlatformEGLAndroid() noexcept override;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
/**
|
||||
* Returns the Android SDK version.
|
||||
* @return Android SDK version.
|
||||
*/
|
||||
int getOSVersion() const noexcept override;
|
||||
|
||||
Driver* createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
/**
|
||||
* Set the presentation time using `eglPresentationTimeANDROID`
|
||||
* @param presentationTimeInNanosecond
|
||||
*/
|
||||
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
|
||||
|
||||
|
||||
Stream* createStream(void* nativeStream) noexcept override;
|
||||
void destroyStream(Stream* stream) noexcept override;
|
||||
void attach(Stream* stream, intptr_t tname) noexcept override;
|
||||
void detach(Stream* stream) noexcept override;
|
||||
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
|
||||
|
||||
/**
|
||||
* Converts a AHardwareBuffer to EGLImage
|
||||
* @param source source.image is a AHardwareBuffer
|
||||
* @return source.image contains an EGLImage
|
||||
*/
|
||||
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
|
||||
|
||||
private:
|
||||
int mOSVersion;
|
||||
ExternalStreamManagerAndroid& mExternalStreamManager;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
|
||||
@@ -1,55 +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_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
* A concrete implementation of OpenGLPlatform that supports WebGL.
|
||||
*/
|
||||
class PlatformWebGL : public OpenGLPlatform {
|
||||
protected:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
Driver* createDriver(void* sharedGLContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// OpenGLPlatform Interface
|
||||
|
||||
void terminate() noexcept override;
|
||||
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
|
||||
@@ -299,11 +299,11 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, canGenerateMipmaps)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(void, cancelExternalImage, void*, image)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(backend::SyncStatus, getSyncStatus, backend::SyncHandle, sh)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
|
||||
|
||||
+5
-3
@@ -22,9 +22,10 @@
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
namespace filament::backend {
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
class MetalPlatform final : public Platform {
|
||||
class MetalPlatform : public DefaultPlatform {
|
||||
public:
|
||||
~MetalPlatform() override;
|
||||
|
||||
@@ -59,6 +60,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include "private/backend/AcquiredImage.h"
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
class Driver;
|
||||
|
||||
class OpenGLPlatform : public DefaultPlatform {
|
||||
protected:
|
||||
|
||||
/*
|
||||
* Derived classes can use this to instantiate the default OpenGLDriver backend.
|
||||
* This is typically called from your implementation of createDriver()
|
||||
*/
|
||||
static Driver* createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const DriverConfig& driverConfig);
|
||||
|
||||
public:
|
||||
~OpenGLPlatform() noexcept override;
|
||||
|
||||
// Called to destroy the OpenGL context. This should clean up any windows
|
||||
// or buffers from initialization.
|
||||
virtual void terminate() noexcept = 0;
|
||||
|
||||
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t& flags) noexcept = 0;
|
||||
|
||||
// headless swapchain
|
||||
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept = 0;
|
||||
|
||||
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
|
||||
|
||||
virtual void createDefaultRenderTarget(uint32_t& framebuffer, uint32_t& colorbuffer,
|
||||
uint32_t& depthbuffer) noexcept {
|
||||
framebuffer = 0;
|
||||
colorbuffer = 0;
|
||||
depthbuffer = 0;
|
||||
}
|
||||
|
||||
// Called to make the OpenGL context active on the calling thread.
|
||||
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
|
||||
|
||||
// Called once the current frame finishes drawing. Typically this should
|
||||
// swap draw buffers (i.e. for double-buffered rendering).
|
||||
virtual void commit(SwapChain* swapChain) noexcept = 0;
|
||||
|
||||
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept = 0;
|
||||
|
||||
virtual bool canCreateFence() noexcept { return false; }
|
||||
virtual Fence* createFence() noexcept = 0;
|
||||
virtual void destroyFence(Fence* fence) noexcept = 0;
|
||||
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept = 0;
|
||||
|
||||
// this is called synchronously in the application thread (NOT the Driver thread)
|
||||
virtual Stream* createStream(void* nativeStream) noexcept = 0;
|
||||
|
||||
virtual void destroyStream(Stream* stream) noexcept = 0;
|
||||
|
||||
// attach takes ownership of the texture (tname) object
|
||||
virtual void attach(Stream* stream, intptr_t tname) noexcept = 0;
|
||||
|
||||
// detach destroys the texture associated to the stream
|
||||
virtual void detach(Stream* stream) noexcept = 0;
|
||||
virtual void updateTexImage(Stream* stream, int64_t* timestamp) 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; }
|
||||
|
||||
// called to bind the platform-specific externalImage to a texture
|
||||
// texture points to a OpenGLDriver::GLTexture
|
||||
virtual bool setExternalImage(void* externalImage, void* texture) noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
// called on the application thread to allow Filament to take ownership of the image
|
||||
virtual void retainExternalImage(void* externalImage) noexcept {}
|
||||
|
||||
// called to release ownership of the image
|
||||
virtual void releaseExternalImage(void* externalImage) noexcept {}
|
||||
|
||||
// called once when a new SAMPLER_EXTERNAL texture is created.
|
||||
virtual void createExternalImageTexture(void* texture) noexcept {}
|
||||
|
||||
// called once before a SAMPLER_EXTERNAL texture is destroyed.
|
||||
virtual void destroyExternalImage(void* texture) noexcept {}
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
|
||||
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
|
||||
|
||||
#include "backend/DriverEnums.h"
|
||||
|
||||
#include "utils/compiler.h"
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Platform;
|
||||
|
||||
class UTILS_PUBLIC PlatformFactory {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a Platform configured for the requested backend if available
|
||||
*
|
||||
* @param backendHint Preferred backend, if not available the backend most suitable for the
|
||||
* underlying platform is returned and \p backendHint is updated
|
||||
* accordingly. Can't be nullptr.
|
||||
*
|
||||
* @return A pointer to the Platform object.
|
||||
*
|
||||
* @see destroy
|
||||
*/
|
||||
static Platform* create(backend::Backend* backendHint) noexcept;
|
||||
|
||||
/**
|
||||
* Destroys a Platform object returned by create()
|
||||
*
|
||||
* @param platform a reference (as a pointer) to the Platform pointer to destroy.
|
||||
* \p platform is cleared upon return.
|
||||
*
|
||||
* @see create
|
||||
*/
|
||||
static void destroy(Platform** platform) noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
|
||||
@@ -1,3 +0,0 @@
|
||||
# include/private/backend Headers
|
||||
|
||||
Headers in `include/private/backend/` are only public to filament and cannot be used by end-users.
|
||||
@@ -29,7 +29,7 @@ bool requestsGoogleLineDirectivesExtension(std::string_view source) noexcept {
|
||||
}
|
||||
|
||||
void removeGoogleLineDirectives(char* shader, size_t length) noexcept {
|
||||
std::string_view const s{ shader, length };
|
||||
std::string_view s(shader, length);
|
||||
|
||||
size_t pos = 0;
|
||||
while (true) {
|
||||
@@ -173,20 +173,6 @@ size_t getFormatSize(TextureFormat format) noexcept {
|
||||
case TextureFormat::DXT5_SRGBA:
|
||||
return 16;
|
||||
|
||||
case TextureFormat::RED_RGTC1:
|
||||
case TextureFormat::SIGNED_RED_RGTC1:
|
||||
return 8;
|
||||
|
||||
case TextureFormat::RED_GREEN_RGTC2:
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
|
||||
return 16;
|
||||
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
|
||||
case TextureFormat::RGBA_BPTC_UNORM:
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
|
||||
return 16;
|
||||
|
||||
// The block size for ASTC compression is always 16 bytes.
|
||||
case TextureFormat::RGBA_ASTC_4x4:
|
||||
case TextureFormat::RGBA_ASTC_5x4:
|
||||
@@ -290,22 +276,16 @@ size_t getFormatComponentCount(TextureFormat format) noexcept {
|
||||
// Compressed formats ---------------------------------------------------------------------
|
||||
case TextureFormat::EAC_R11:
|
||||
case TextureFormat::EAC_R11_SIGNED:
|
||||
case TextureFormat::RED_RGTC1:
|
||||
case TextureFormat::SIGNED_RED_RGTC1:
|
||||
return 1;
|
||||
|
||||
case TextureFormat::EAC_RG11:
|
||||
case TextureFormat::EAC_RG11_SIGNED:
|
||||
case TextureFormat::RED_GREEN_RGTC2:
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
|
||||
return 2;
|
||||
|
||||
case TextureFormat::ETC2_RGB8:
|
||||
case TextureFormat::ETC2_SRGB8:
|
||||
case TextureFormat::DXT1_RGB:
|
||||
case TextureFormat::DXT1_SRGB:
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
|
||||
return 3;
|
||||
|
||||
case TextureFormat::ETC2_EAC_RGBA8:
|
||||
@@ -318,8 +298,6 @@ size_t getFormatComponentCount(TextureFormat format) noexcept {
|
||||
case TextureFormat::DXT3_SRGBA:
|
||||
case TextureFormat::DXT5_RGBA:
|
||||
case TextureFormat::DXT5_SRGBA:
|
||||
case TextureFormat::RGBA_BPTC_UNORM:
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
|
||||
case TextureFormat::RGBA_ASTC_4x4:
|
||||
case TextureFormat::RGBA_ASTC_5x4:
|
||||
case TextureFormat::RGBA_ASTC_5x5:
|
||||
@@ -378,18 +356,6 @@ size_t getBlockWidth(TextureFormat format) noexcept {
|
||||
case TextureFormat::DXT5_SRGBA:
|
||||
return 4;
|
||||
|
||||
case TextureFormat::RED_RGTC1:
|
||||
case TextureFormat::SIGNED_RED_RGTC1:
|
||||
case TextureFormat::RED_GREEN_RGTC2:
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
|
||||
return 4;
|
||||
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
|
||||
case TextureFormat::RGBA_BPTC_UNORM:
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
|
||||
return 4;
|
||||
|
||||
case TextureFormat::RGBA_ASTC_4x4:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_4x4:
|
||||
return 4;
|
||||
@@ -489,8 +455,7 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto freeFunc = [](void* buffer,
|
||||
UTILS_UNUSED size_t size, UTILS_UNUSED void* user) { free(buffer); };
|
||||
const auto freeFunc = [](void* buffer, size_t size, void* user) { free(buffer); };
|
||||
const size_t reshapedSize = 4 * data.size / 3;
|
||||
const PixelDataFormat reshapedFormat =
|
||||
data.format == PixelDataFormat::RGB ? PixelDataFormat::RGBA : PixelDataFormat::RGBA_INTEGER;
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
namespace filament::backend {
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
PresentCallable::PresentCallable(PresentFn fn, void* user) noexcept
|
||||
: mPresentFn(fn), mUser(user) {
|
||||
@@ -34,4 +35,5 @@ void PresentCallable::operator()(bool presentFrame) noexcept {
|
||||
mPresentFn = nullptr;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -62,7 +62,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
|
||||
void* vaddr = MAP_FAILED;
|
||||
void* vaddr_shadow = MAP_FAILED;
|
||||
void* vaddr_guard = MAP_FAILED;
|
||||
int const fd = ashmem_create_region("filament::CircularBuffer", size + BLOCK_SIZE);
|
||||
int fd = ashmem_create_region("filament::CircularBuffer", size + BLOCK_SIZE);
|
||||
if (fd >= 0) {
|
||||
// reserve/find enough address space
|
||||
void* reserve_vaddr = mmap(nullptr, size * 2 + BLOCK_SIZE,
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
|
||||
using namespace utils;
|
||||
|
||||
namespace filament::backend {
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
CommandBufferQueue::CommandBufferQueue(size_t requiredSize, size_t bufferSize)
|
||||
: mRequiredSize((requiredSize + CircularBuffer::BLOCK_MASK) & ~CircularBuffer::BLOCK_MASK),
|
||||
@@ -40,13 +41,13 @@ CommandBufferQueue::~CommandBufferQueue() {
|
||||
}
|
||||
|
||||
void CommandBufferQueue::requestExit() {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard<utils::Mutex> lock(mLock);
|
||||
mExitRequested = EXIT_REQUESTED;
|
||||
mCondition.notify_one();
|
||||
}
|
||||
|
||||
bool CommandBufferQueue::isExitRequested() const {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard<utils::Mutex> lock(mLock);
|
||||
ASSERT_PRECONDITION( mExitRequested == 0 || mExitRequested == EXIT_REQUESTED,
|
||||
"mExitRequested is corrupted (value = 0x%08x)!", mExitRequested);
|
||||
return (bool)mExitRequested;
|
||||
@@ -72,7 +73,7 @@ void CommandBufferQueue::flush() noexcept {
|
||||
void* const tail = circularBuffer.getTail();
|
||||
|
||||
// size of this slice
|
||||
uint32_t const used = uint32_t(intptr_t(head) - intptr_t(tail));
|
||||
uint32_t used = uint32_t(intptr_t(head) - intptr_t(tail));
|
||||
|
||||
circularBuffer.circularize();
|
||||
|
||||
@@ -124,9 +125,10 @@ std::vector<CommandBufferQueue::Slice> CommandBufferQueue::waitForCommands() con
|
||||
}
|
||||
|
||||
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Slice const& buffer) {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard<utils::Mutex> lock(mLock);
|
||||
mFreeSpace += uintptr_t(buffer.end) - uintptr_t(buffer.begin);
|
||||
mCondition.notify_one();
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#if DEBUG_COMMAND_STREAM
|
||||
#include <utils/CallStack.h>
|
||||
#endif
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Profiler.h>
|
||||
#include <utils/Systrace.h>
|
||||
@@ -37,7 +34,7 @@ namespace filament::backend {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// A few utility functions for debugging...
|
||||
|
||||
inline void printParameterPack(io::ostream&) { }
|
||||
inline void printParameterPack(io::ostream& out) { }
|
||||
|
||||
template<typename LAST>
|
||||
static void printParameterPack(io::ostream& out, const LAST& t) { out << t; }
|
||||
@@ -98,7 +95,7 @@ void CommandStream::execute(void* buffer) {
|
||||
if (UTILS_UNLIKELY(mUsePerformanceCounter)) {
|
||||
// we want to remove all this when tracing is completely disabled
|
||||
profiler.stop();
|
||||
UTILS_UNUSED Profiler::Counters const counters = profiler.readCounters();
|
||||
UTILS_UNUSED Profiler::Counters counters = profiler.readCounters();
|
||||
SYSTRACE_VALUE32("GLThread (I)", counters.getInstructions());
|
||||
SYSTRACE_VALUE32("GLThread (C)", counters.getCpuCycles());
|
||||
SYSTRACE_VALUE32("GLThread (CPI x10)", counters.getCPI() * 10);
|
||||
|
||||
@@ -14,21 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "DriverBase.h"
|
||||
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include "private/backend/AcquiredImage.h"
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#include <backend/AcquiredImage.h>
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include "DriverBase.h"
|
||||
|
||||
#include <math/half.h>
|
||||
#include <math/vec2.h>
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
using namespace utils;
|
||||
using namespace filament::math;
|
||||
|
||||
|
||||
@@ -16,13 +16,172 @@
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/system_properties.h>
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "opengl/platforms/PlatformEGLAndroid.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkAndroid.h"
|
||||
#endif
|
||||
#elif defined(IOS)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "opengl/platforms/PlatformCocoaTouchGL.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkCocoaTouch.h"
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "opengl/platforms/PlatformCocoaGL.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkCocoa.h"
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
#include "vulkan/PlatformVkLinuxGGP.h"
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkLinuxWayland.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_X11)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "opengl/platforms/PlatformGLX.h"
|
||||
#endif
|
||||
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkLinuxX11.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "opengl/platforms/PlatformEGLHeadless.h"
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "opengl/platforms/PlatformWGL.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkWindows.h"
|
||||
#endif
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#include "opengl/platforms/PlatformWebGL.h"
|
||||
#endif
|
||||
|
||||
#if defined (FILAMENT_SUPPORTS_METAL)
|
||||
namespace filament::backend {
|
||||
filament::backend::DefaultPlatform* createDefaultMetalPlatform();
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "noop/PlatformNoop.h"
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
// this generates the vtable in this translation unit
|
||||
Platform::~Platform() noexcept = default;
|
||||
|
||||
bool Platform::pumpEvents() noexcept {
|
||||
return false;
|
||||
// Creates the platform-specific Platform object. The caller takes ownership and is
|
||||
// responsible for destroying it. Initialization of the backend API is deferred until
|
||||
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
|
||||
DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
assert_invariant(backend);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
char scratch[PROP_VALUE_MAX + 1];
|
||||
int length = __system_property_get("debug.filament.backend", scratch);
|
||||
if (length > 0) {
|
||||
*backend = Backend(atoi(scratch));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*backend == Backend::DEFAULT) {
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
*backend = Backend::OPENGL;
|
||||
#elif defined(__ANDROID__)
|
||||
*backend = Backend::OPENGL;
|
||||
#elif defined(IOS) || defined(__APPLE__)
|
||||
*backend = Backend::METAL;
|
||||
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
*backend = Backend::VULKAN;
|
||||
#else
|
||||
* backend = Backend::OPENGL;
|
||||
#endif
|
||||
}
|
||||
if (*backend == Backend::NOOP) {
|
||||
return new PlatformNoop();
|
||||
}
|
||||
if (*backend == Backend::VULKAN) {
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#if defined(__ANDROID__)
|
||||
return new PlatformVkAndroid();
|
||||
#elif defined(IOS)
|
||||
return new PlatformVkCocoaTouch();
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
return new PlatformVkLinuxGGP();
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
return new PlatformVkLinuxWayland();
|
||||
#elif defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformVkLinuxX11();
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
return new PlatformVkCocoa();
|
||||
#elif defined(WIN32)
|
||||
return new PlatformVkWindows();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
if (*backend == Backend::METAL) {
|
||||
#if defined(FILAMENT_SUPPORTS_METAL)
|
||||
return createDefaultMetalPlatform();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
assert_invariant(*backend == Backend::OPENGL);
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL)
|
||||
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
|
||||
// Swiftshader OpenGLES support is deprecated and incomplete
|
||||
return nullptr;
|
||||
#elif defined(__ANDROID__)
|
||||
return new PlatformEGLAndroid();
|
||||
#elif defined(IOS)
|
||||
return new PlatformCocoaTouchGL();
|
||||
#elif defined(__APPLE__)
|
||||
return new PlatformCocoaGL();
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformGLX();
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
return new PlatformEGLHeadless();
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
return new PlatformWGL();
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
return new PlatformWebGL();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// destroys a Platform created by create()
|
||||
void DefaultPlatform::destroy(DefaultPlatform** platform) noexcept {
|
||||
delete *platform;
|
||||
*platform = nullptr;
|
||||
}
|
||||
|
||||
DefaultPlatform::~DefaultPlatform() noexcept = default;
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -1,182 +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 <private/backend/PlatformFactory.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <sys/system_properties.h>
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "backend/platforms/PlatformEGLAndroid.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkAndroid.h"
|
||||
#endif
|
||||
#elif defined(IOS)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
|
||||
#include "backend/platforms/PlatformCocoaTouchGL.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkCocoaTouch.h"
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include <backend/platforms/PlatformCocoaGL.h>
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkCocoa.h"
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
#include "vulkan/PlatformVkLinuxGGP.h"
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkLinuxWayland.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_X11)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "backend/platforms/PlatformGLX.h"
|
||||
#endif
|
||||
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkLinuxX11.h"
|
||||
#endif
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "backend/platforms/PlatformEGLHeadless.h"
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
|
||||
#include "backend/platforms/PlatformWGL.h"
|
||||
#endif
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkWindows.h"
|
||||
#endif
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#include "backend/platforms/PlatformWebGL.h"
|
||||
#endif
|
||||
|
||||
#if defined (FILAMENT_SUPPORTS_METAL)
|
||||
namespace filament::backend {
|
||||
filament::backend::Platform* createDefaultMetalPlatform();
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "noop/PlatformNoop.h"
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
// Creates the platform-specific Platform object. The caller takes ownership and is
|
||||
// responsible for destroying it. Initialization of the backend API is deferred until
|
||||
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
|
||||
Platform* PlatformFactory::create(Backend* backend) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
assert_invariant(backend);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
char scratch[PROP_VALUE_MAX + 1];
|
||||
int length = __system_property_get("debug.filament.backend", scratch);
|
||||
if (length > 0) {
|
||||
*backend = Backend(atoi(scratch));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (*backend == Backend::DEFAULT) {
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
*backend = Backend::OPENGL;
|
||||
#elif defined(__ANDROID__)
|
||||
*backend = Backend::OPENGL;
|
||||
#elif defined(IOS) || defined(__APPLE__)
|
||||
*backend = Backend::METAL;
|
||||
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
*backend = Backend::VULKAN;
|
||||
#else
|
||||
* backend = Backend::OPENGL;
|
||||
#endif
|
||||
}
|
||||
if (*backend == Backend::NOOP) {
|
||||
return new PlatformNoop();
|
||||
}
|
||||
if (*backend == Backend::VULKAN) {
|
||||
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#if defined(__ANDROID__)
|
||||
return new PlatformVkAndroid();
|
||||
#elif defined(IOS)
|
||||
return new PlatformVkCocoaTouch();
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
return new PlatformVkLinuxGGP();
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
return new PlatformVkLinuxWayland();
|
||||
#elif defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformVkLinuxX11();
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
return new PlatformVkCocoa();
|
||||
#elif defined(WIN32)
|
||||
return new PlatformVkWindows();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
if (*backend == Backend::METAL) {
|
||||
#if defined(FILAMENT_SUPPORTS_METAL)
|
||||
return createDefaultMetalPlatform();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
assert_invariant(*backend == Backend::OPENGL);
|
||||
#if defined(FILAMENT_SUPPORTS_OPENGL)
|
||||
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
|
||||
// Swiftshader OpenGLES support is deprecated and incomplete
|
||||
return nullptr;
|
||||
#elif defined(__ANDROID__)
|
||||
return new PlatformEGLAndroid();
|
||||
#elif defined(IOS)
|
||||
return new PlatformCocoaTouchGL();
|
||||
#elif defined(__APPLE__)
|
||||
return new PlatformCocoaGL();
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformGLX();
|
||||
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
|
||||
return new PlatformEGLHeadless();
|
||||
#endif
|
||||
#elif defined(WIN32)
|
||||
return new PlatformWGL();
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
return new PlatformWebGL();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// destroys a Platform created by create()
|
||||
void PlatformFactory::destroy(Platform** platform) noexcept {
|
||||
delete *platform;
|
||||
*platform = nullptr;
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label);
|
||||
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args);
|
||||
|
||||
/**
|
||||
* Free resources. Should be called at least once per process when no further calls to blit will
|
||||
@@ -112,12 +112,11 @@ private:
|
||||
};
|
||||
|
||||
void blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
|
||||
const BlitArgs& args, const char* label);
|
||||
const BlitArgs& args);
|
||||
void blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
|
||||
const BlitArgs& args, const char* label);
|
||||
const BlitArgs& args);
|
||||
void blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
|
||||
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
|
||||
const char* label);
|
||||
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest);
|
||||
id<MTLTexture> createIntermediateTexture(id<MTLTexture> t, MTLSize size);
|
||||
id<MTLFunction> compileFragmentFunction(BlitFunctionKey key);
|
||||
id<MTLFunction> getBlitVertexFunction();
|
||||
|
||||
@@ -143,7 +143,7 @@ MetalBlitter::MetalBlitter(MetalContext& context) noexcept : mContext(context) {
|
||||
|
||||
#define MTLSizeEqual(a, b) (a.width == b.width && a.height == b.height && a.depth == b.depth)
|
||||
|
||||
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label) {
|
||||
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
|
||||
bool blitColor = args.blitColor();
|
||||
bool blitDepth = args.blitDepth();
|
||||
|
||||
@@ -164,7 +164,7 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, co
|
||||
// Determine if the blit for color or depth are eligible to use a MTLBlitCommandEncoder.
|
||||
// blitColor and / or blitDepth are set to false upon success, to indicate that no more work is
|
||||
// necessary for that attachment.
|
||||
blitFastPath(cmdBuffer, blitColor, blitDepth, args, label);
|
||||
blitFastPath(cmdBuffer, blitColor, blitDepth, args);
|
||||
|
||||
if (!blitColor && !blitDepth) {
|
||||
return;
|
||||
@@ -207,22 +207,21 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, co
|
||||
slowBlit.destination.region = finalBlit.source.region = sourceRegionNoOffset;
|
||||
}
|
||||
|
||||
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit, label);
|
||||
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit);
|
||||
|
||||
bool finalBlitColor = intermediateColor != nil;
|
||||
bool finalBlitDepth = intermediateDepth != nil;
|
||||
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit, label);
|
||||
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit);
|
||||
}
|
||||
|
||||
void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
|
||||
const BlitArgs& args, const char* label) {
|
||||
const BlitArgs& args) {
|
||||
if (blitColor) {
|
||||
if (args.source.color.sampleCount == args.destination.color.sampleCount &&
|
||||
args.source.color.pixelFormat == args.destination.color.pixelFormat &&
|
||||
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
|
||||
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
|
||||
blitEncoder.label = @(label);
|
||||
[blitEncoder copyFromTexture:args.source.color
|
||||
sourceSlice:args.source.slice
|
||||
sourceLevel:args.source.level
|
||||
@@ -244,7 +243,6 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
|
||||
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
|
||||
blitEncoder.label = @(label);
|
||||
[blitEncoder copyFromTexture:args.source.depth
|
||||
sourceSlice:args.source.slice
|
||||
sourceLevel:args.source.level
|
||||
@@ -262,7 +260,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
}
|
||||
|
||||
void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
|
||||
const BlitArgs& args, const char* label) {
|
||||
const BlitArgs& args) {
|
||||
|
||||
uint32_t depthPlaneSource = args.source.region.origin.z;
|
||||
uint32_t depthPlaneDest = args.destination.region.origin.z;
|
||||
@@ -270,8 +268,7 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
assert_invariant(args.source.region.size.depth == args.destination.region.size.depth);
|
||||
uint32_t depthPlaneCount = args.source.region.size.depth;
|
||||
for (NSUInteger d = 0; d < depthPlaneCount; d++) {
|
||||
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++,
|
||||
label);
|
||||
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++);
|
||||
}
|
||||
|
||||
blitColor = false;
|
||||
@@ -279,8 +276,7 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
|
||||
}
|
||||
|
||||
void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
|
||||
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
|
||||
const char* label) {
|
||||
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest) {
|
||||
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
|
||||
if (blitColor) {
|
||||
@@ -292,7 +288,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
|
||||
}
|
||||
|
||||
id<MTLRenderCommandEncoder> encoder = [cmdBuffer renderCommandEncoderWithDescriptor:descriptor];
|
||||
encoder.label = @(label);
|
||||
encoder.label = @"Blit";
|
||||
|
||||
BlitFunctionKey key;
|
||||
key.blitColor = blitColor;
|
||||
|
||||
@@ -69,7 +69,6 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
|
||||
// Encode a blit from the staging buffer into the private GPU buffer.
|
||||
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
|
||||
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
|
||||
blitEncoder.label = @"Buffer upload blit";
|
||||
[blitEncoder copyFromBuffer:staging->buffer
|
||||
sourceOffset:0
|
||||
toBuffer:mBuffer
|
||||
|
||||
@@ -96,8 +96,6 @@ struct MetalContext {
|
||||
SamplerStateCache samplerStateCache;
|
||||
ArgumentEncoderCache argumentEncoderCache;
|
||||
|
||||
PolygonOffset currentPolygonOffset = {0.0f, 0.0f};
|
||||
|
||||
MetalSamplerGroup* samplerBindings[Program::SAMPLER_BINDING_COUNT] = {};
|
||||
|
||||
// Keeps track of sampler groups we've finalized for the current render pass.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "MetalState.h"
|
||||
#include "MetalTimerQuery.h"
|
||||
|
||||
#include "MetalPlatform.h"
|
||||
#include "private/backend/MetalPlatform.h"
|
||||
|
||||
#include <CoreVideo/CVMetalTexture.h>
|
||||
#include <CoreVideo/CVPixelBuffer.h>
|
||||
@@ -706,11 +706,6 @@ bool MetalDriver::isAutoDepthResolveSupported() {
|
||||
return mContext->supportsAutoDepthResolve;
|
||||
}
|
||||
|
||||
bool MetalDriver::isSRGBSwapChainSupported() {
|
||||
// the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag is not supported
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
switch (workaround) {
|
||||
case Workaround::SPLIT_EASU:
|
||||
@@ -808,6 +803,11 @@ void MetalDriver::setupExternalImage(void* image) {
|
||||
CVPixelBufferRetain(pixelBuffer);
|
||||
}
|
||||
|
||||
void MetalDriver::cancelExternalImage(void* image) {
|
||||
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) image;
|
||||
CVPixelBufferRelease(pixelBuffer);
|
||||
}
|
||||
|
||||
void MetalDriver::setExternalImage(Handle<HwTexture> th, void* image) {
|
||||
ASSERT_PRECONDITION(!isInRenderPass(mContext),
|
||||
"setExternalImage must be called outside of a render pass.");
|
||||
@@ -1005,7 +1005,6 @@ void MetalDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
mContext->depthStencilState.invalidate();
|
||||
mContext->cullModeState.invalidate();
|
||||
mContext->windingState.invalidate();
|
||||
mContext->currentPolygonOffset = {0.0f, 0.0f};
|
||||
|
||||
mContext->finalizedSamplerGroups.clear();
|
||||
}
|
||||
@@ -1184,12 +1183,8 @@ void MetalDriver::startCapture(int) {
|
||||
if (@available(iOS 13, *)) {
|
||||
MTLCaptureDescriptor* descriptor = [MTLCaptureDescriptor new];
|
||||
descriptor.captureObject = mContext->device;
|
||||
#if defined(IOS)
|
||||
descriptor.destination = MTLCaptureDestinationDeveloperTools;
|
||||
#else
|
||||
descriptor.destination = MTLCaptureDestinationGPUTraceDocument;
|
||||
descriptor.outputURL = [[NSURL alloc] initFileURLWithPath:@"filament.gputrace"];
|
||||
#endif
|
||||
NSError* error = nil;
|
||||
[[MTLCaptureManager sharedCaptureManager] startCaptureWithDescriptor:descriptor
|
||||
error:&error];
|
||||
@@ -1263,7 +1258,7 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
|
||||
args.source.color = srcTexture;
|
||||
args.destination.color = readPixelsTexture;
|
||||
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "readPixels blit");
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
|
||||
#if !defined(IOS)
|
||||
// Managed textures on macOS require explicit synchronization between GPU / CPU.
|
||||
@@ -1347,7 +1342,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
args.destination.level = dstColorAttachment.level;
|
||||
args.source.slice = srcColorAttachment.layer;
|
||||
args.destination.slice = dstColorAttachment.layer;
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Color blit");
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1370,7 +1365,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
|
||||
args.destination.level = dstDepthAttachment.level;
|
||||
args.source.slice = srcDepthAttachment.layer;
|
||||
args.destination.slice = dstDepthAttachment.layer;
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Depth blit");
|
||||
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1591,12 +1586,10 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
|
||||
[mContext->currentRenderPassEncoder setDepthStencilState:state];
|
||||
}
|
||||
|
||||
if (ps.polygonOffset.constant != mContext->currentPolygonOffset.constant ||
|
||||
ps.polygonOffset.slope != mContext->currentPolygonOffset.slope) {
|
||||
if (ps.polygonOffset.constant != 0.0 || ps.polygonOffset.slope != 0.0) {
|
||||
[mContext->currentRenderPassEncoder setDepthBias:ps.polygonOffset.constant
|
||||
slopeScale:ps.polygonOffset.slope
|
||||
clamp:0.0];
|
||||
mContext->currentPolygonOffset = ps.polygonOffset;
|
||||
}
|
||||
|
||||
// Set scissor-rectangle.
|
||||
|
||||
@@ -198,16 +198,6 @@ MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexc
|
||||
|
||||
case TextureFormat::DXT1_RGB: return MTLPixelFormatInvalid;
|
||||
case TextureFormat::DXT1_SRGB: return MTLPixelFormatInvalid;
|
||||
|
||||
case TextureFormat::RED_RGTC1: return MTLPixelFormatBC4_RUnorm;
|
||||
case TextureFormat::SIGNED_RED_RGTC1: return MTLPixelFormatBC4_RSnorm;
|
||||
case TextureFormat::RED_GREEN_RGTC2: return MTLPixelFormatBC5_RGUnorm;
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2: return MTLPixelFormatBC5_RGSnorm;
|
||||
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT: return MTLPixelFormatBC6H_RGBFloat;
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT: return MTLPixelFormatBC6H_RGBUfloat;
|
||||
case TextureFormat::RGBA_BPTC_UNORM: return MTLPixelFormatBC7_RGBAUnorm;
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM: return MTLPixelFormatBC7_RGBAUnorm_sRGB;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +391,6 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
|
||||
id<MTLFunction> function = [library newFunctionWithName:@"main0"
|
||||
constantValues:constants
|
||||
error:&error];
|
||||
function.label = @(program.getName().c_str());
|
||||
assert_invariant(function);
|
||||
*shaderFunctions[i] = function;
|
||||
}
|
||||
@@ -721,7 +720,6 @@ void MetalTexture::loadWithCopyBuffer(uint32_t level, uint32_t slice, MTLRegion
|
||||
stagingBufferSize);
|
||||
id<MTLCommandBuffer> blitCommandBuffer = getPendingCommandBuffer(&context);
|
||||
id<MTLBlitCommandEncoder> blitCommandEncoder = [blitCommandBuffer blitCommandEncoder];
|
||||
blitCommandEncoder.label = @"Texture upload buffer blit";
|
||||
[blitCommandEncoder copyFromBuffer:entry->buffer
|
||||
sourceOffset:0
|
||||
sourceBytesPerRow:shape.bytesPerRow
|
||||
@@ -794,7 +792,7 @@ void MetalTexture::loadWithBlit(uint32_t level, uint32_t slice, MTLRegion region
|
||||
args.destination.region = region;
|
||||
args.source.color = stagingTexture;
|
||||
args.destination.color = destinationTexture;
|
||||
context.blitter->blit(getPendingCommandBuffer(&context), args, "Texture upload blit");
|
||||
context.blitter->blit(getPendingCommandBuffer(&context), args);
|
||||
}
|
||||
|
||||
void MetalTexture::updateLodRange(uint32_t level) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "MetalPlatform.h"
|
||||
#include "private/backend/MetalPlatform.h"
|
||||
|
||||
#include "MetalDriverFactory.h"
|
||||
|
||||
@@ -22,15 +22,16 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
namespace filament::backend {
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
Platform* createDefaultMetalPlatform() {
|
||||
DefaultPlatform* createDefaultMetalPlatform() {
|
||||
return new MetalPlatform();
|
||||
}
|
||||
|
||||
MetalPlatform::~MetalPlatform() = default;
|
||||
|
||||
Driver* MetalPlatform::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
Driver* MetalPlatform::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
return MetalDriverFactory::create(this, driverConfig);
|
||||
}
|
||||
|
||||
@@ -74,4 +75,5 @@ id<MTLCommandBuffer> MetalPlatform::createAndEnqueueCommandBuffer() noexcept {
|
||||
return commandBuffer;
|
||||
}
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
|
||||
@@ -173,11 +173,7 @@ bool NoopDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isSRGBSwapChainSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NoopDriver::isWorkaroundNeeded(Workaround) {
|
||||
bool NoopDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -228,6 +224,9 @@ void NoopDriver::update3DImage(Handle<HwTexture> th,
|
||||
void NoopDriver::setupExternalImage(void* image) {
|
||||
}
|
||||
|
||||
void NoopDriver::cancelExternalImage(void* image) {
|
||||
}
|
||||
|
||||
bool NoopDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class PlatformNoop final : public Platform {
|
||||
class PlatformNoop final : public DefaultPlatform {
|
||||
public:
|
||||
|
||||
int getOSVersion() const noexcept final { return 0; }
|
||||
|
||||
@@ -57,7 +57,7 @@ const char* getGLError(GLenum error) noexcept {
|
||||
|
||||
UTILS_NOINLINE
|
||||
GLenum checkGLError(io::ostream& out, const char* function, size_t line) noexcept {
|
||||
GLenum const error = glGetError();
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
const char* string = getGLError(error);
|
||||
out << "OpenGL error " << io::hex << error << " (" << string << ") in \""
|
||||
@@ -68,7 +68,7 @@ GLenum checkGLError(io::ostream& out, const char* function, size_t line) noexcep
|
||||
|
||||
UTILS_NOINLINE
|
||||
void assertGLError(io::ostream& out, const char* function, size_t line) noexcept {
|
||||
GLenum const err = checkGLError(out, function, line);
|
||||
GLenum err = checkGLError(out, function, line);
|
||||
if (err != GL_NO_ERROR) {
|
||||
debug_trap();
|
||||
}
|
||||
@@ -104,7 +104,7 @@ const char* getFramebufferStatus(GLenum status) noexcept {
|
||||
|
||||
UTILS_NOINLINE
|
||||
GLenum checkFramebufferStatus(io::ostream& out, GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum const status = glCheckFramebufferStatus(target);
|
||||
GLenum status = glCheckFramebufferStatus(target);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
const char* string = getFramebufferStatus(status);
|
||||
out << "OpenGL framebuffer error " << io::hex << status << " (" << string << ") in \""
|
||||
@@ -115,7 +115,7 @@ GLenum checkFramebufferStatus(io::ostream& out, GLenum target, const char* funct
|
||||
|
||||
UTILS_NOINLINE
|
||||
void assertFramebufferStatus(io::ostream& out, GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum const status = checkFramebufferStatus(out, target, function, line);
|
||||
GLenum status = checkFramebufferStatus(out, target, function, line);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
debug_trap();
|
||||
}
|
||||
|
||||
@@ -472,34 +472,6 @@ constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(GL_EXT_texture_compression_rgtc)
|
||||
case TextureFormat::RED_RGTC1: return GL_COMPRESSED_RED_RGTC1_EXT;
|
||||
case TextureFormat::SIGNED_RED_RGTC1: return GL_COMPRESSED_SIGNED_RED_RGTC1_EXT;
|
||||
case TextureFormat::RED_GREEN_RGTC2: return GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2: return GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
|
||||
#else
|
||||
case TextureFormat::RED_RGTC1:
|
||||
case TextureFormat::SIGNED_RED_RGTC1:
|
||||
case TextureFormat::RED_GREEN_RGTC2:
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
|
||||
// this should not happen
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(GL_EXT_texture_compression_bptc)
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT: return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT: return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
|
||||
case TextureFormat::RGBA_BPTC_UNORM: return GL_COMPRESSED_RGBA_BPTC_UNORM_EXT;
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM: return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT;
|
||||
#else
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
|
||||
case TextureFormat::RGBA_BPTC_UNORM:
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
|
||||
// this should not happen
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(GL_KHR_texture_compression_astc_hdr)
|
||||
case TextureFormat::RGBA_ASTC_4x4: return GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
|
||||
case TextureFormat::RGBA_ASTC_5x4: return GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
|
||||
|
||||
@@ -27,7 +27,7 @@ bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept {
|
||||
if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GLES) {
|
||||
char const* version = (char const*)glGetString(GL_VERSION);
|
||||
// This works on all versions of GLES
|
||||
int const n = version ? sscanf(version, "OpenGL ES %d.%d", major, minor) : 0;
|
||||
int n = version ? sscanf(version, "OpenGL ES %d.%d", major, minor) : 0;
|
||||
return n == 2;
|
||||
} else if constexpr (BACKEND_OPENGL_VERSION == BACKEND_OPENGL_VERSION_GL) {
|
||||
// OpenGL version
|
||||
@@ -142,7 +142,7 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
bugs.enable_initialize_non_used_uniform_array = true;
|
||||
|
||||
int maj, min, driverMajor, driverMinor;
|
||||
int const c = sscanf(state.version, "OpenGL ES %d.%d V@%d.%d", // NOLINT(cert-err34-c)
|
||||
int c = sscanf(state.version, "OpenGL ES %d.%d V@%d.%d", // NOLINT(cert-err34-c)
|
||||
&maj, &min, &driverMajor, &driverMinor);
|
||||
if (c == 4) {
|
||||
// Workarounds based on version here.
|
||||
@@ -176,7 +176,7 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
bugs.dont_use_timer_query = true;
|
||||
|
||||
int maj, min, driverVersion, driverRevision, driverPatch;
|
||||
int const c = sscanf(state.version, "OpenGL ES %d.%d v%d.r%dp%d", // NOLINT(cert-err34-c)
|
||||
int c = sscanf(state.version, "OpenGL ES %d.%d v%d.r%dp%d", // NOLINT(cert-err34-c)
|
||||
&maj, &min, &driverVersion, &driverRevision, &driverPatch);
|
||||
if (c == 5) {
|
||||
// Workarounds based on version here.
|
||||
@@ -218,7 +218,7 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
if (strstr(state.renderer, "Adreno")) {
|
||||
// Qualcomm GPU
|
||||
// early exit condition is flattened in EASU code
|
||||
// (that should be regardless of ANGLE, but we should double-check)
|
||||
// (that should be regardless of ANGLE, but we should double check)
|
||||
bugs.split_easu = true;
|
||||
}
|
||||
// TODO: see if we could use `bugs.allow_read_only_ancillary_feedback_loop = true`
|
||||
@@ -268,12 +268,10 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
}
|
||||
#endif
|
||||
|
||||
// in practice KHR_Debug has never been useful, and actually is confusing. We keep this
|
||||
// only for our own debugging, in case we need it some day.
|
||||
#if false && !defined(NDEBUG) && defined(GL_KHR_debug)
|
||||
#if !defined(NDEBUG) && defined(GL_KHR_debug)
|
||||
if (ext.KHR_debug) {
|
||||
auto cb = +[](GLenum, GLenum type, GLuint, GLenum severity, GLsizei length,
|
||||
const GLchar* message, const void *) {
|
||||
auto cb = [](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
|
||||
const GLchar* message, const void *userParam) {
|
||||
io::ostream* stream = &slog.i;
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_HIGH: stream = &slog.e; break;
|
||||
@@ -294,7 +292,7 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
case GL_DEBUG_TYPE_MARKER: level = "MARKER: "; break;
|
||||
default: break;
|
||||
}
|
||||
out << "KHR_debug " << level << std::string_view{ message, size_t(length) } << io::endl;
|
||||
out << "KHR_debug " << level << message << io::endl;
|
||||
};
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
@@ -306,7 +304,7 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
void OpenGLContext::setDefaultState() noexcept {
|
||||
// We need to make sure our internal state matches the GL state when we start.
|
||||
// (some of these calls may be unneeded as they might be the gl defaults)
|
||||
GLenum const caps[] = {
|
||||
GLenum caps[] = {
|
||||
GL_BLEND,
|
||||
GL_CULL_FACE,
|
||||
GL_SCISSOR_TEST,
|
||||
@@ -317,14 +315,16 @@ void OpenGLContext::setDefaultState() noexcept {
|
||||
GL_SAMPLE_COVERAGE,
|
||||
GL_POLYGON_OFFSET_FILL,
|
||||
};
|
||||
size_t capsCount = sizeof(caps) / sizeof(caps[0]);
|
||||
|
||||
UTILS_NOUNROLL
|
||||
for (auto const capi : caps) {
|
||||
size_t const capIndex = getIndexForCap(capi);
|
||||
for (GLenum capi = 0; capi < capsCount; ++capi) {
|
||||
size_t capIndex = getIndexForCap(caps[capi]);
|
||||
GLenum cap = caps[capi];
|
||||
if (state.enables.caps[capIndex]) {
|
||||
glEnable(capi);
|
||||
glEnable(cap);
|
||||
} else {
|
||||
glDisable(capi);
|
||||
glDisable(cap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ void OpenGLContext::setDefaultState() noexcept {
|
||||
|
||||
void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
const char * const extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
GLUtils::unordered_string_set const exts = GLUtils::split(extensions);
|
||||
GLUtils::unordered_string_set exts = GLUtils::split(extensions);
|
||||
if constexpr (DEBUG_PRINT_EXTENSIONS) {
|
||||
for (auto extension: exts) {
|
||||
slog.d << "\"" << std::string_view(extension) << "\"\n";
|
||||
@@ -377,8 +377,6 @@ void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
#endif
|
||||
ext.EXT_texture_compression_s3tc = exts.has("GL_EXT_texture_compression_s3tc"sv);
|
||||
ext.EXT_texture_compression_s3tc_srgb = exts.has("GL_EXT_texture_compression_s3tc_srgb"sv);
|
||||
ext.EXT_texture_compression_rgtc = exts.has("GL_EXT_texture_compression_rgtc"sv);
|
||||
ext.EXT_texture_compression_bptc = exts.has("GL_EXT_texture_compression_bptc"sv);
|
||||
ext.EXT_texture_cube_map_array = exts.has("GL_EXT_texture_cube_map_array"sv) || exts.has("GL_OES_texture_cube_map_array"sv);
|
||||
ext.GOOGLE_cpp_style_line_directive = exts.has("GL_GOOGLE_cpp_style_line_directive"sv);
|
||||
ext.KHR_debug = exts.has("GL_KHR_debug"sv);
|
||||
@@ -422,8 +420,6 @@ void OpenGLContext::initExtensionsGL() noexcept {
|
||||
ext.EXT_texture_compression_etc2 = exts.has("GL_ARB_ES3_compatibility"sv);
|
||||
ext.EXT_texture_compression_s3tc = exts.has("GL_EXT_texture_compression_s3tc"sv);
|
||||
ext.EXT_texture_compression_s3tc_srgb = exts.has("GL_EXT_texture_compression_s3tc_srgb"sv);
|
||||
ext.EXT_texture_compression_rgtc = exts.has("GL_EXT_texture_compression_rgtc"sv);
|
||||
ext.EXT_texture_compression_bptc = exts.has("GL_EXT_texture_compression_bptc"sv);
|
||||
ext.EXT_texture_filter_anisotropic = exts.has("GL_EXT_texture_filter_anisotropic"sv);
|
||||
ext.EXT_texture_sRGB = exts.has("GL_EXT_texture_sRGB"sv);
|
||||
ext.GOOGLE_cpp_style_line_directive = exts.has("GL_GOOGLE_cpp_style_line_directive"sv);
|
||||
@@ -448,7 +444,7 @@ void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept {
|
||||
glBindBuffer(target, buffer);
|
||||
}
|
||||
} else {
|
||||
size_t const targetIndex = getIndexForBufferTarget(target);
|
||||
size_t targetIndex = getIndexForBufferTarget(target);
|
||||
update_state(state.buffers.genericBinding[targetIndex], buffer, [&]() {
|
||||
glBindBuffer(target, buffer);
|
||||
});
|
||||
@@ -615,7 +611,7 @@ void OpenGLContext::resetState() noexcept {
|
||||
// Reset state.buffers to its default state to avoid the complexity and error-prone
|
||||
// nature of resetting the GL state to its existing state
|
||||
state.buffers = {};
|
||||
GLenum const bufferTargets[] = {
|
||||
GLenum bufferTargets[] = {
|
||||
GL_UNIFORM_BUFFER,
|
||||
GL_TRANSFORM_FEEDBACK_BUFFER,
|
||||
#if !defined(__EMSCRIPTEN__)
|
||||
@@ -628,7 +624,9 @@ void OpenGLContext::resetState() noexcept {
|
||||
GL_PIXEL_PACK_BUFFER,
|
||||
GL_PIXEL_UNPACK_BUFFER,
|
||||
};
|
||||
for (auto const target : bufferTargets) {
|
||||
size_t bufferTargetCount = sizeof(bufferTargets) / sizeof(bufferTargets[0]);
|
||||
for (size_t targetArrayIndex = 0; targetArrayIndex < bufferTargetCount; ++targetArrayIndex) {
|
||||
GLenum target = bufferTargets[targetArrayIndex];
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
|
||||
@@ -657,11 +655,13 @@ void OpenGLContext::resetState() noexcept {
|
||||
GL_TEXTURE_CUBE_MAP_ARRAY,
|
||||
#endif
|
||||
};
|
||||
const size_t textureTargetCount = sizeof(textureTargets) / sizeof(textureTargets[0]);
|
||||
for (GLint unit = 0; unit < gets.max_combined_texture_image_units; ++unit) {
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
glBindSampler(unit, 0);
|
||||
|
||||
for (auto const target : textureTargets) {
|
||||
for (size_t textureTargetArrayIndex = 0; textureTargetArrayIndex < textureTargetCount; ++textureTargetArrayIndex) {
|
||||
GLuint target = textureTargets[textureTargetArrayIndex];
|
||||
glBindTexture(target, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,93 +137,91 @@ public:
|
||||
|
||||
// features supported by this version of GL or GLES
|
||||
struct {
|
||||
bool multisample_texture;
|
||||
} features = {};
|
||||
bool multisample_texture = false;
|
||||
} features;
|
||||
|
||||
// supported extensions detected at runtime
|
||||
struct {
|
||||
bool APPLE_color_buffer_packed_float;
|
||||
bool ARB_shading_language_packing;
|
||||
bool EXT_clip_control;
|
||||
bool EXT_color_buffer_float;
|
||||
bool EXT_color_buffer_half_float;
|
||||
bool EXT_debug_marker;
|
||||
bool EXT_disjoint_timer_query;
|
||||
bool EXT_multisampled_render_to_texture;
|
||||
bool EXT_multisampled_render_to_texture2;
|
||||
bool EXT_shader_framebuffer_fetch;
|
||||
bool KHR_texture_compression_astc_hdr;
|
||||
bool KHR_texture_compression_astc_ldr;
|
||||
bool EXT_texture_compression_etc2;
|
||||
bool EXT_texture_compression_s3tc;
|
||||
bool EXT_texture_compression_s3tc_srgb;
|
||||
bool EXT_texture_compression_rgtc;
|
||||
bool EXT_texture_compression_bptc;
|
||||
bool EXT_texture_cube_map_array;
|
||||
bool EXT_texture_filter_anisotropic;
|
||||
bool EXT_texture_sRGB;
|
||||
bool GOOGLE_cpp_style_line_directive;
|
||||
bool KHR_debug;
|
||||
bool OES_EGL_image_external_essl3;
|
||||
bool QCOM_tiled_rendering;
|
||||
bool WEBGL_compressed_texture_etc;
|
||||
bool WEBGL_compressed_texture_s3tc;
|
||||
bool WEBGL_compressed_texture_s3tc_srgb;
|
||||
} ext = {};
|
||||
bool APPLE_color_buffer_packed_float = false;
|
||||
bool ARB_shading_language_packing = false;
|
||||
bool EXT_clip_control = false;
|
||||
bool EXT_color_buffer_float = false;
|
||||
bool EXT_color_buffer_half_float = false;
|
||||
bool EXT_debug_marker = false;
|
||||
bool EXT_disjoint_timer_query = false;
|
||||
bool EXT_multisampled_render_to_texture = false;
|
||||
bool EXT_multisampled_render_to_texture2 = false;
|
||||
bool EXT_shader_framebuffer_fetch = false;
|
||||
bool KHR_texture_compression_astc_hdr = false;
|
||||
bool KHR_texture_compression_astc_ldr = false;
|
||||
bool EXT_texture_compression_etc2 = false;
|
||||
bool EXT_texture_compression_s3tc = false;
|
||||
bool EXT_texture_compression_s3tc_srgb = false;
|
||||
bool EXT_texture_cube_map_array = false;
|
||||
bool EXT_texture_filter_anisotropic = false;
|
||||
bool EXT_texture_sRGB = false;
|
||||
bool GOOGLE_cpp_style_line_directive = false;
|
||||
bool KHR_debug = false;
|
||||
bool OES_EGL_image_external_essl3 = false;
|
||||
bool QCOM_tiled_rendering = false;
|
||||
bool WEBGL_compressed_texture_etc = false;
|
||||
bool WEBGL_compressed_texture_s3tc = false;
|
||||
bool WEBGL_compressed_texture_s3tc_srgb = false;
|
||||
} ext;
|
||||
|
||||
struct {
|
||||
// Some drivers have issues with UBOs in the fragment shader when
|
||||
// glFlush() is called between draw calls.
|
||||
bool disable_glFlush;
|
||||
bool disable_glFlush = false;
|
||||
|
||||
// Some drivers seem to not store the GL_ELEMENT_ARRAY_BUFFER binding
|
||||
// in the VAO state.
|
||||
bool vao_doesnt_store_element_array_buffer_binding;
|
||||
bool vao_doesnt_store_element_array_buffer_binding = false;
|
||||
|
||||
// Some drivers have gl state issues when drawing from shared contexts
|
||||
bool disable_shared_context_draws;
|
||||
bool disable_shared_context_draws = false;
|
||||
|
||||
// Some drivers require the GL_TEXTURE_EXTERNAL_OES target to be bound when
|
||||
// the texture image changes, even if it's already bound to that texture
|
||||
bool texture_external_needs_rebind;
|
||||
bool texture_external_needs_rebind = false;
|
||||
|
||||
// Some web browsers seem to immediately clear the default framebuffer when calling
|
||||
// glInvalidateFramebuffer with WebGL 2.0
|
||||
bool disable_invalidate_framebuffer;
|
||||
bool disable_invalidate_framebuffer = false;
|
||||
|
||||
// Some drivers declare GL_EXT_texture_filter_anisotropic but don't support
|
||||
// calling glSamplerParameter() with GL_TEXTURE_MAX_ANISOTROPY_EXT
|
||||
bool texture_filter_anisotropic_broken_on_sampler;
|
||||
bool texture_filter_anisotropic_broken_on_sampler = false;
|
||||
|
||||
// Some drivers have issues when reading from a mip while writing to a different mip.
|
||||
// In the OpenGL ES 3.0 specification this is covered in section 4.4.3,
|
||||
// "Feedback Loops Between Textures and the Framebuffer".
|
||||
bool disable_feedback_loops;
|
||||
bool disable_feedback_loops = false;
|
||||
|
||||
// Some drivers don't implement timer queries correctly
|
||||
bool dont_use_timer_query;
|
||||
bool dont_use_timer_query = false;
|
||||
|
||||
// Some drivers can't blit from a sidecar renderbuffer into a layer of a texture array.
|
||||
// This technique is used for VSM with MSAA turned on.
|
||||
bool disable_sidecar_blit_into_texture_array;
|
||||
bool disable_sidecar_blit_into_texture_array = false;
|
||||
|
||||
// Some drivers incorrectly flatten the early exit condition in the EASU code, in which
|
||||
// case we need an alternative algorithm
|
||||
bool split_easu;
|
||||
bool split_easu = false;
|
||||
|
||||
// As of Android R some qualcomm drivers invalidate buffers for the whole render pass
|
||||
// even if glInvalidateFramebuffer() is called at the end of it.
|
||||
bool invalidate_end_only_if_invalidate_start;
|
||||
bool invalidate_end_only_if_invalidate_start = false;
|
||||
|
||||
// GLES doesn't allow feedback loops even if writes are disabled. So take we the point of
|
||||
// view that this is generally forbidden. However, this restriction is lifted on desktop
|
||||
// GL and Vulkan and probably Metal.
|
||||
bool allow_read_only_ancillary_feedback_loop;
|
||||
bool allow_read_only_ancillary_feedback_loop = false;
|
||||
|
||||
// Some Adreno drivers crash in glDrawXXX() when there's an uninitialized uniform block,
|
||||
// even when the shader doesn't access it.
|
||||
bool enable_initialize_non_used_uniform_array;
|
||||
} bugs = {};
|
||||
bool enable_initialize_non_used_uniform_array = false;
|
||||
} bugs;
|
||||
|
||||
// state getters -- as needed.
|
||||
vec4gli const& getViewport() const { return state.window.viewport; }
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
#include "OpenGLDriver.h"
|
||||
|
||||
#include "private/backend/DriverApi.h"
|
||||
#include "private/backend/OpenGLPlatform.h"
|
||||
|
||||
#include "CommandStreamDispatcher.h"
|
||||
#include "OpenGLContext.h"
|
||||
#include "OpenGLDriverFactory.h"
|
||||
#include "OpenGLProgram.h"
|
||||
#include "OpenGLTimerQuery.h"
|
||||
#include "OpenGLContext.h"
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
#include <backend/SamplerDescriptor.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
@@ -78,8 +78,8 @@ using namespace GLUtils;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
UTILS_NOINLINE
|
||||
Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
|
||||
void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
Driver* OpenGLDriver::create(
|
||||
OpenGLPlatform* const platform, void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
assert_invariant(platform);
|
||||
OpenGLPlatform* const ec = platform;
|
||||
|
||||
@@ -120,7 +120,7 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
|
||||
|
||||
// here we check we're on a supported version of GL before initializing the driver
|
||||
GLint major = 0, minor = 0;
|
||||
bool const success = OpenGLContext::queryOpenGLVersion(&major, &minor);
|
||||
bool success = OpenGLContext::queryOpenGLVersion(&major, &minor);
|
||||
|
||||
if (UTILS_UNLIKELY(!success)) {
|
||||
PANIC_LOG("Can't get OpenGL version");
|
||||
@@ -142,9 +142,8 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
|
||||
}
|
||||
}
|
||||
|
||||
size_t const defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
|
||||
Platform::DriverConfig const validConfig {
|
||||
.handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize) };
|
||||
size_t defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
|
||||
Platform::DriverConfig validConfig { .handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize) };
|
||||
OpenGLDriver* const driver = new OpenGLDriver(ec, validConfig);
|
||||
return driver;
|
||||
}
|
||||
@@ -170,8 +169,7 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
|
||||
std::fill(mSamplerBindings.begin(), mSamplerBindings.end(), nullptr);
|
||||
|
||||
// set a reasonable default value for our stream array
|
||||
mTexturesWithStreamsAttached.reserve(8);
|
||||
mStreamsWithPendingAcquiredImage.reserve(8);
|
||||
mExternalStreams.reserve(8);
|
||||
|
||||
#ifndef NDEBUG
|
||||
slog.i << "OS version: " << mPlatform.getOSVersion() << io::endl;
|
||||
@@ -437,10 +435,10 @@ void OpenGLDriver::createIndexBufferR(
|
||||
DEBUG_MARKER()
|
||||
|
||||
auto& gl = mContext;
|
||||
uint8_t const elementSize = static_cast<uint8_t>(getElementTypeSize(elementType));
|
||||
uint8_t elementSize = static_cast<uint8_t>(getElementTypeSize(elementType));
|
||||
GLIndexBuffer* ib = construct<GLIndexBuffer>(ibh, elementSize, indexCount);
|
||||
glGenBuffers(1, &ib->gl.buffer);
|
||||
GLsizeiptr const size = elementSize * indexCount;
|
||||
GLsizeiptr size = elementSize * indexCount;
|
||||
gl.bindVertexArray(nullptr);
|
||||
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->gl.buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, getBufferUsage(usage));
|
||||
@@ -574,17 +572,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
GLTexture* t = construct<GLTexture>(th, target, levels, samples, w, h, depth, format, usage);
|
||||
if (UTILS_LIKELY(usage & TextureUsage::SAMPLEABLE)) {
|
||||
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
|
||||
t->externalTexture = mPlatform.createExternalImageTexture();
|
||||
if (t->externalTexture) {
|
||||
t->gl.target = t->externalTexture->target;
|
||||
t->gl.id = t->externalTexture->id;
|
||||
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
|
||||
// internalFormat actually depends on the external image, but it doesn't matter
|
||||
// because it's not used anywhere for anything important.
|
||||
t->gl.internalFormat = getInternalFormat(format);
|
||||
t->gl.baseLevel = 0;
|
||||
t->gl.maxLevel = 0;
|
||||
}
|
||||
mPlatform.createExternalImageTexture(t);
|
||||
} else {
|
||||
glGenTextures(1, &t->gl.id);
|
||||
|
||||
@@ -595,7 +583,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
// getIndexForTextureTarget() is constexpr -- so all of this disappears at compile time.
|
||||
switch (target) {
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
// we can't be here -- doesn't matter what we do
|
||||
// we can't be here -- doesn't mater what we do
|
||||
case SamplerType::SAMPLER_2D:
|
||||
t->gl.target = GL_TEXTURE_2D;
|
||||
t->gl.targetIndex = (uint8_t)gl.getIndexForTextureTarget(GL_TEXTURE_2D);
|
||||
@@ -1050,8 +1038,7 @@ void OpenGLDriver::renderBufferStorage(GLuint rbo, GLenum internalformat, uint32
|
||||
auto& gl = mContext;
|
||||
if (gl.ext.EXT_multisampled_render_to_texture ||
|
||||
gl.ext.EXT_multisampled_render_to_texture2) {
|
||||
glext::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
|
||||
samples, internalformat, width, height);
|
||||
glext::glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, internalformat, width, height);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -1073,7 +1060,10 @@ void OpenGLDriver::createDefaultRenderTargetR(
|
||||
|
||||
construct<GLRenderTarget>(rth, 0, 0); // FIXME: we don't know the width/height
|
||||
|
||||
uint32_t framebuffer = mPlatform.createDefaultRenderTarget();
|
||||
uint32_t framebuffer = 0;
|
||||
uint32_t colorbuffer = 0;
|
||||
uint32_t depthbuffer = 0;
|
||||
mPlatform.createDefaultRenderTarget(framebuffer, colorbuffer, depthbuffer);
|
||||
|
||||
GLRenderTarget* rt = handle_cast<GLRenderTarget*>(rth);
|
||||
rt->gl.fbo = framebuffer;
|
||||
@@ -1124,7 +1114,7 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
* About the size of the attachments:
|
||||
*
|
||||
* If the attachment sizes are not all identical, the results of rendering are defined only
|
||||
* within the largest area that can fit in all the attachments. This area is defined as
|
||||
* within the largest area that can fit in all of the attachments. This area is defined as
|
||||
* the intersection of rectangles having a lower left of (0, 0) and an upper right of
|
||||
* (width, height) for each attachment. Contents of attachments outside this area are
|
||||
* undefined after execution of a rendering command.
|
||||
@@ -1215,11 +1205,11 @@ void OpenGLDriver::createSyncR(Handle<HwSync> fh, int) {
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// check the status of the sync once a frame, since we must do this from our thread
|
||||
std::weak_ptr<GLSync::State> const weak = f->result;
|
||||
std::weak_ptr<GLSync::State> weak = f->result;
|
||||
runEveryNowAndThen([sync = f->gl.sync, weak]() -> bool {
|
||||
auto result = weak.lock();
|
||||
if (result) {
|
||||
GLenum const status = glClientWaitSync(sync, 0, 0u);
|
||||
GLenum status = glClientWaitSync(sync, 0, 0u);
|
||||
result->status.store(status, std::memory_order_relaxed);
|
||||
return (status != GL_TIMEOUT_EXPIRED);
|
||||
}
|
||||
@@ -1324,7 +1314,7 @@ void OpenGLDriver::destroyTexture(Handle<HwTexture> th) {
|
||||
detachStream(t);
|
||||
}
|
||||
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
|
||||
mPlatform.destroyExternalImage(t->externalTexture);
|
||||
mPlatform.destroyExternalImage(t);
|
||||
} else {
|
||||
glDeleteTextures(1, &t->gl.id);
|
||||
}
|
||||
@@ -1380,23 +1370,15 @@ void OpenGLDriver::destroyStream(Handle<HwStream> sh) {
|
||||
GLStream* s = handle_cast<GLStream*>(sh);
|
||||
|
||||
// if this stream is still attached to a texture, detach it first
|
||||
auto& texturesWithStreamsAttached = mTexturesWithStreamsAttached;
|
||||
auto pos = std::find_if(
|
||||
texturesWithStreamsAttached.begin(), texturesWithStreamsAttached.end(),
|
||||
[s](GLTexture const* t) {
|
||||
return t->hwStream == s;
|
||||
});
|
||||
|
||||
if (pos != texturesWithStreamsAttached.end()) {
|
||||
auto& externalStreams = mExternalStreams;
|
||||
auto pos = std::find_if(externalStreams.begin(), externalStreams.end(),
|
||||
[s](GLTexture const* t) { return t->hwStream == s; });
|
||||
if (pos != externalStreams.end()) {
|
||||
detachStream(*pos);
|
||||
}
|
||||
|
||||
// and then destroy the stream. Only NATIVE streams have Platform::Stream associated.
|
||||
if (s->streamType == StreamType::NATIVE) {
|
||||
mPlatform.destroyStream(s->stream);
|
||||
}
|
||||
|
||||
// finally destroy the HwStream handle
|
||||
destruct(sh, s);
|
||||
}
|
||||
}
|
||||
@@ -1444,64 +1426,30 @@ Handle<HwStream> OpenGLDriver::createStreamAcquired() {
|
||||
void OpenGLDriver::setAcquiredImage(Handle<HwStream> sh, void* hwbuffer,
|
||||
CallbackHandler* handler, StreamCallback cb, void* userData) {
|
||||
GLStream* glstream = handle_cast<GLStream*>(sh);
|
||||
assert_invariant(glstream->streamType == StreamType::ACQUIRED);
|
||||
|
||||
if (UTILS_UNLIKELY(glstream->user_thread.pending.image)) {
|
||||
if (glstream->user_thread.pending.image) {
|
||||
scheduleRelease(glstream->user_thread.pending);
|
||||
slog.w << "Acquired image is set more than once per frame." << io::endl;
|
||||
}
|
||||
|
||||
glstream->user_thread.pending = mPlatform.transformAcquiredImage({
|
||||
hwbuffer, cb, userData, handler });
|
||||
|
||||
if (glstream->user_thread.pending.image != nullptr) {
|
||||
// If there's no pending image, do nothing. Note that GL_OES_EGL_image does not let you pass
|
||||
// NULL to glEGLImageTargetTexture2DOES, and there is no concept of "detaching" an
|
||||
// EGLimage from a texture.
|
||||
mStreamsWithPendingAcquiredImage.push_back(glstream);
|
||||
}
|
||||
}
|
||||
|
||||
// updateStreams() and setAcquiredImage() are both called from on the application's thread
|
||||
// and therefore do not require synchronization. The former is always called immediately before
|
||||
// beginFrame, the latter is called by the user from anywhere outside beginFrame / endFrame.
|
||||
void OpenGLDriver::updateStreams(DriverApi* driver) {
|
||||
if (UTILS_UNLIKELY(!mStreamsWithPendingAcquiredImage.empty())) {
|
||||
for (GLStream* s : mStreamsWithPendingAcquiredImage) {
|
||||
assert_invariant(s);
|
||||
assert_invariant(s->streamType == StreamType::ACQUIRED);
|
||||
if (UTILS_UNLIKELY(!mExternalStreams.empty())) {
|
||||
for (GLTexture* t : mExternalStreams) {
|
||||
assert_invariant(t);
|
||||
|
||||
AcquiredImage const previousImage = s->user_thread.acquired;
|
||||
s->user_thread.acquired = s->user_thread.pending;
|
||||
s->user_thread.pending = { nullptr };
|
||||
GLStream* s = static_cast<GLStream*>(t->hwStream); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||
if (UTILS_UNLIKELY(s == nullptr)) {
|
||||
// this can happen because we're called synchronously and the setExternalStream()
|
||||
// call may not have been processed yet.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Bind the stashed EGLImage to its corresponding GL texture as soon as we start
|
||||
// making the GL calls for the upcoming frame.
|
||||
driver->queueCommand([this, s, image = s->user_thread.acquired.image, previousImage]() {
|
||||
|
||||
auto& streams = mTexturesWithStreamsAttached;
|
||||
auto pos = std::find_if(streams.begin(), streams.end(),
|
||||
[s](GLTexture const* t) {
|
||||
return t->hwStream == s;
|
||||
});
|
||||
if (pos != streams.end()) {
|
||||
GLTexture* t = *pos;
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
if (mPlatform.setExternalImage(image, t->externalTexture)) {
|
||||
// the target and id can be reset each time
|
||||
t->gl.target = t->externalTexture->target;
|
||||
t->gl.id = t->externalTexture->id;
|
||||
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
}
|
||||
}
|
||||
|
||||
if (previousImage.image) {
|
||||
scheduleRelease(AcquiredImage(previousImage));
|
||||
}
|
||||
});
|
||||
if (s->streamType == StreamType::ACQUIRED) {
|
||||
updateStreamAcquired(t, driver);
|
||||
}
|
||||
}
|
||||
mStreamsWithPendingAcquiredImage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1561,12 +1509,6 @@ bool OpenGLDriver::isTextureFormatSupported(TextureFormat format) {
|
||||
return ext.EXT_texture_compression_s3tc || // this is ES specific
|
||||
ext.WEBGL_compressed_texture_s3tc; // this is WEBGL specific
|
||||
}
|
||||
if (isRGTCCompression(format)) {
|
||||
return ext.EXT_texture_compression_rgtc;
|
||||
}
|
||||
if (isBPTCCompression(format)) {
|
||||
return ext.EXT_texture_compression_bptc;
|
||||
}
|
||||
if (isASTCCompression(format)) {
|
||||
return ext.KHR_texture_compression_astc_hdr;
|
||||
}
|
||||
@@ -1691,10 +1633,6 @@ bool OpenGLDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isSRGBSwapChainSupported() {
|
||||
return mPlatform.isSRGBSwapChainSupported();
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
switch (workaround) {
|
||||
case Workaround::SPLIT_EASU:
|
||||
@@ -1871,7 +1809,7 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
|
||||
DEBUG_MARKER()
|
||||
|
||||
#if defined(GL_EXT_texture_filter_anisotropic)
|
||||
OpenGLContext const& context = getContext();
|
||||
OpenGLContext& context = getContext();
|
||||
const bool anisotropyWorkaround =
|
||||
context.ext.EXT_texture_filter_anisotropic &&
|
||||
context.bugs.texture_filter_anisotropic_broken_on_sampler;
|
||||
@@ -1891,7 +1829,7 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
|
||||
SamplerParams params = pSamplers[i].s;
|
||||
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
|
||||
// From OES_EGL_image_external spec:
|
||||
// "The default s and t wrap modes are CLAMP_TO_EDGE, and it is an INVALID_ENUM
|
||||
// "The default s and t wrap modes are CLAMP_TO_EDGE and it is an INVALID_ENUM
|
||||
// error to set the wrap mode to any other value."
|
||||
params.wrapS = SamplerWrapMode::CLAMP_TO_EDGE;
|
||||
params.wrapT = SamplerWrapMode::CLAMP_TO_EDGE;
|
||||
@@ -1915,7 +1853,7 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
|
||||
// Driver claims to support anisotropic filtering, but it fails when set on
|
||||
// the sampler, we have to set it on the texture instead.
|
||||
// The texture is already bound here.
|
||||
GLfloat const anisotropy = float(1u << params.anisotropyLog2);
|
||||
GLfloat anisotropy = float(1u << params.anisotropyLog2);
|
||||
glTexParameterf(t->gl.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
std::min(context.gets.max_anisotropy, anisotropy));
|
||||
}
|
||||
@@ -2006,8 +1944,8 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
return;
|
||||
}
|
||||
|
||||
GLenum const glFormat = getFormat(p.format);
|
||||
GLenum const glType = getType(p.type);
|
||||
GLenum glFormat = getFormat(p.format);
|
||||
GLenum glType = getType(p.type);
|
||||
|
||||
gl.pixelStore(GL_UNPACK_ROW_LENGTH, GLint(p.stride));
|
||||
gl.pixelStore(GL_UNPACK_ALIGNMENT, GLint(p.alignment));
|
||||
@@ -2016,7 +1954,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
|
||||
switch (t->target) {
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
// if we get there, it's because the user is trying to use an external texture,
|
||||
// if we get there, it's because the user is trying to use an external texture
|
||||
// but it's not supported, so instead, we behave like a texture2d.
|
||||
// fallthrough...
|
||||
case SamplerType::SAMPLER_2D:
|
||||
@@ -2060,7 +1998,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
assert_invariant(zoffset + depth <= 6);
|
||||
UTILS_NOUNROLL
|
||||
for (size_t face = 0; face < depth; face++) {
|
||||
GLenum const target = getCubemapTarget(zoffset + face);
|
||||
GLenum target = getCubemapTarget(zoffset + face);
|
||||
glTexSubImage2D(target, GLint(level), GLint(xoffset), GLint(yoffset),
|
||||
GLsizei(width), GLsizei(height), glFormat, glType,
|
||||
static_cast<uint8_t const*>(p.buffer) + faceSize * face);
|
||||
@@ -2069,7 +2007,7 @@ void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
|
||||
}
|
||||
}
|
||||
|
||||
// update the base/max LOD, so we don't access undefined LOD. this allows the app to
|
||||
// update the base/max LOD so we don't access undefined LOD. this allows the app to
|
||||
// specify levels as they become available.
|
||||
|
||||
if (int8_t(level) < t->gl.baseLevel) {
|
||||
@@ -2104,13 +2042,13 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level,
|
||||
|
||||
// TODO: maybe assert that the CompressedPixelDataType is the same as the internalFormat
|
||||
|
||||
GLsizei const imageSize = GLsizei(p.imageSize);
|
||||
GLsizei imageSize = GLsizei(p.imageSize);
|
||||
|
||||
// TODO: maybe assert the size is right (b/c we can compute it ourselves)
|
||||
|
||||
switch (t->target) {
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
// if we get there, it's because the user is trying to use an external texture,
|
||||
// if we get there, it's because the user is trying to use an external texture
|
||||
// but it's not supported, so instead, we behave like a texture2d.
|
||||
// fallthrough...
|
||||
case SamplerType::SAMPLER_2D:
|
||||
@@ -2152,7 +2090,7 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level,
|
||||
|
||||
UTILS_NOUNROLL
|
||||
for (size_t face = 0; face < depth; face++) {
|
||||
GLenum const target = getCubemapTarget(zoffset + face);
|
||||
GLenum target = getCubemapTarget(zoffset + face);
|
||||
glCompressedTexSubImage2D(target, GLint(level), GLint(xoffset), GLint(yoffset),
|
||||
GLsizei(width), GLsizei(height), t->gl.internalFormat,
|
||||
imageSize, static_cast<uint8_t const*>(p.buffer) + faceSize * face);
|
||||
@@ -2161,7 +2099,7 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level,
|
||||
}
|
||||
}
|
||||
|
||||
// update the base/max LOD, so we don't access undefined LOD. this allows the app to
|
||||
// update the base/max LOD so we don't access undefined LOD. this allows the app to
|
||||
// specify levels as they become available.
|
||||
|
||||
if (uint8_t(level) < t->gl.baseLevel) {
|
||||
@@ -2182,26 +2120,37 @@ void OpenGLDriver::setupExternalImage(void* image) {
|
||||
mPlatform.retainExternalImage(image);
|
||||
}
|
||||
|
||||
void OpenGLDriver::cancelExternalImage(void* image) {
|
||||
mPlatform.releaseExternalImage(image);
|
||||
}
|
||||
|
||||
void OpenGLDriver::setExternalImage(Handle<HwTexture> th, void* image) {
|
||||
DEBUG_MARKER()
|
||||
GLTexture* t = handle_cast<GLTexture*>(th);
|
||||
assert_invariant(t);
|
||||
assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL);
|
||||
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
if (mPlatform.setExternalImage(image, t->externalTexture)) {
|
||||
// the target and id can be reset each time
|
||||
t->gl.target = t->externalTexture->target;
|
||||
t->gl.id = t->externalTexture->id;
|
||||
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
}
|
||||
mPlatform.setExternalImage(image, handle_cast<GLTexture*>(th));
|
||||
setExternalTexture(handle_cast<GLTexture*>(th), image);
|
||||
}
|
||||
|
||||
void OpenGLDriver::setExternalImagePlane(Handle<HwTexture> th, void* image, uint32_t plane) {
|
||||
DEBUG_MARKER()
|
||||
}
|
||||
|
||||
void OpenGLDriver::setExternalTexture(GLTexture* t, void* image) {
|
||||
auto& gl = mContext;
|
||||
|
||||
// TODO: move this logic to PlatformEGL.
|
||||
if (gl.ext.OES_EGL_image_external_essl3) {
|
||||
assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL);
|
||||
assert_invariant(t->gl.target == GL_TEXTURE_EXTERNAL_OES);
|
||||
|
||||
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
|
||||
gl.activeTexture(OpenGLContext::DUMMY_TEXTURE_BINDING);
|
||||
|
||||
#ifdef GL_OES_EGL_image
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, static_cast<GLeglImageOES>(image));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLDriver::setExternalStream(Handle<HwTexture> th, Handle<HwStream> sh) {
|
||||
auto& gl = mContext;
|
||||
if (gl.ext.OES_EGL_image_external_essl3) {
|
||||
@@ -2228,7 +2177,7 @@ void OpenGLDriver::setExternalStream(Handle<HwTexture> th, Handle<HwStream> sh)
|
||||
|
||||
UTILS_NOINLINE
|
||||
void OpenGLDriver::attachStream(GLTexture* t, GLStream* hwStream) noexcept {
|
||||
mTexturesWithStreamsAttached.push_back(t);
|
||||
mExternalStreams.push_back(t);
|
||||
|
||||
switch (hwStream->streamType) {
|
||||
case StreamType::NATIVE:
|
||||
@@ -2243,10 +2192,10 @@ void OpenGLDriver::attachStream(GLTexture* t, GLStream* hwStream) noexcept {
|
||||
UTILS_NOINLINE
|
||||
void OpenGLDriver::detachStream(GLTexture* t) noexcept {
|
||||
auto& gl = mContext;
|
||||
auto& texturesWithStreamsAttached = mTexturesWithStreamsAttached;
|
||||
auto pos = std::find(texturesWithStreamsAttached.begin(), texturesWithStreamsAttached.end(), t);
|
||||
if (pos != texturesWithStreamsAttached.end()) {
|
||||
texturesWithStreamsAttached.erase(pos);
|
||||
auto& streams = mExternalStreams;
|
||||
auto pos = std::find(streams.begin(), streams.end(), t);
|
||||
if (pos != streams.end()) {
|
||||
streams.erase(pos);
|
||||
}
|
||||
|
||||
GLStream* s = static_cast<GLStream*>(t->hwStream); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||
@@ -2321,7 +2270,7 @@ void OpenGLDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
|
||||
|
||||
bool OpenGLDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
|
||||
GLTimerQuery* tq = handle_cast<GLTimerQuery*>(tqh);
|
||||
uint64_t const d = tq->elapsed.load(std::memory_order_relaxed);
|
||||
uint64_t d = tq->elapsed.load(std::memory_order_relaxed);
|
||||
if (!d) {
|
||||
return false;
|
||||
}
|
||||
@@ -2374,7 +2323,7 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
BACKEND_OPENGL_LEVEL >= BACKEND_OPENGL_LEVEL_GLES30) {
|
||||
if (!gl.bugs.disable_invalidate_framebuffer) {
|
||||
AttachmentArray attachments; // NOLINT
|
||||
GLsizei const attachmentCount = getAttachments(attachments, rt, discardFlags);
|
||||
GLsizei attachmentCount = getAttachments(attachments, rt, discardFlags);
|
||||
if (attachmentCount) {
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
|
||||
}
|
||||
@@ -2411,10 +2360,8 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
mRenderPassDepthWrite = any(clearFlags & TargetBufferFlags::DEPTH);
|
||||
mRenderPassStencilWrite = any(clearFlags & TargetBufferFlags::STENCIL);
|
||||
|
||||
static_assert(sizeof(GLsizei) >= sizeof(uint32_t));
|
||||
gl.viewport(params.viewport.left, params.viewport.bottom,
|
||||
(GLsizei)std::min(uint32_t(std::numeric_limits<int32_t>::max()), params.viewport.width),
|
||||
(GLsizei)std::min(uint32_t(std::numeric_limits<int32_t>::max()), params.viewport.height));
|
||||
(GLsizei)params.viewport.width, (GLsizei)params.viewport.height);
|
||||
|
||||
gl.depthRange(params.depthRange.near, params.depthRange.far);
|
||||
|
||||
@@ -2464,7 +2411,7 @@ void OpenGLDriver::endRenderPass(int) {
|
||||
// we wouldn't have to bind the framebuffer if we had glInvalidateNamedFramebuffer()
|
||||
gl.bindFramebuffer(GL_FRAMEBUFFER, rt->gl.fbo);
|
||||
AttachmentArray attachments; // NOLINT
|
||||
GLsizei const attachmentCount = getAttachments(attachments, rt, effectiveDiscardFlags);
|
||||
GLsizei attachmentCount = getAttachments(attachments, rt, effectiveDiscardFlags);
|
||||
if (attachmentCount) {
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
|
||||
}
|
||||
@@ -2492,7 +2439,7 @@ void OpenGLDriver::resolvePass(ResolveAction action, GLRenderTarget const* rt,
|
||||
assert_invariant(rt->gl.fbo_read);
|
||||
auto& gl = mContext;
|
||||
const TargetBufferFlags resolve = rt->gl.resolve & ~discardFlags;
|
||||
GLbitfield const mask = getAttachmentBitfield(resolve);
|
||||
GLbitfield mask = getAttachmentBitfield(resolve);
|
||||
if (UTILS_UNLIKELY(mask)) {
|
||||
|
||||
// we can only resolve COLOR0 at the moment
|
||||
@@ -2583,6 +2530,40 @@ void OpenGLDriver::setScissor(Viewport const& scissor) noexcept {
|
||||
gl.enable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
// Binds the external image stashed in the associated stream.
|
||||
//
|
||||
// updateStreamAcquired() and setAcquiredImage() are both called from on the application's thread
|
||||
// and therefore do not require synchronization. The former is always called immediately before
|
||||
// beginFrame, the latter is called by the user from anywhere outside beginFrame / endFrame.
|
||||
void OpenGLDriver::updateStreamAcquired(GLTexture* gltexture, DriverApi* driver) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
|
||||
GLStream* glstream = static_cast<GLStream*>(gltexture->hwStream); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
|
||||
assert_invariant(glstream);
|
||||
assert_invariant(glstream->streamType == StreamType::ACQUIRED);
|
||||
|
||||
// If there's no pending image, do nothing. Note that GL_OES_EGL_image does not let you pass
|
||||
// NULL to glEGLImageTargetTexture2DOES, and there is no concept of "detaching" an EGLimage from
|
||||
// a texture.
|
||||
if (glstream->user_thread.pending.image == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
AcquiredImage previousImage = glstream->user_thread.acquired;
|
||||
glstream->user_thread.acquired = glstream->user_thread.pending;
|
||||
glstream->user_thread.pending = { nullptr };
|
||||
|
||||
// Bind the stashed EGLImage to its corresponding GL texture as soon as we start making the GL
|
||||
// calls for the upcoming frame.
|
||||
void* image = glstream->user_thread.acquired.image;
|
||||
driver->queueCommand([this, gltexture, image, previousImage]() {
|
||||
setExternalTexture(gltexture, image);
|
||||
if (previousImage.image) {
|
||||
scheduleRelease(AcquiredImage(previousImage));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setting rendering state
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -2606,7 +2587,7 @@ void OpenGLDriver::bindBufferRange(BufferObjectBinding bindingType, uint32_t ind
|
||||
|
||||
GLBufferObject* ub = handle_cast<GLBufferObject *>(ubh);
|
||||
|
||||
GLenum const target = GLUtils::getBufferBindingType(bindingType);
|
||||
GLenum target = GLUtils::getBufferBindingType(bindingType);
|
||||
|
||||
assert_invariant(bindingType == BufferObjectBinding::SHADER_STORAGE ||
|
||||
ub->gl.binding == target);
|
||||
@@ -2619,7 +2600,7 @@ void OpenGLDriver::bindBufferRange(BufferObjectBinding bindingType, uint32_t ind
|
||||
void OpenGLDriver::unbindBuffer(BufferObjectBinding bindingType, uint32_t index) {
|
||||
DEBUG_MARKER()
|
||||
auto& gl = mContext;
|
||||
GLenum const target = GLUtils::getBufferBindingType(bindingType);
|
||||
GLenum target = GLUtils::getBufferBindingType(bindingType);
|
||||
gl.bindBufferRange(target, GLuint(index), 0, 0, 0);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
@@ -2650,7 +2631,7 @@ GLuint OpenGLDriver::getSamplerSlow(SamplerParams params) const noexcept {
|
||||
auto& gl = mContext;
|
||||
if (gl.ext.EXT_texture_filter_anisotropic &&
|
||||
!gl.bugs.texture_filter_anisotropic_broken_on_sampler) {
|
||||
GLfloat const anisotropy = float(1u << params.anisotropyLog2);
|
||||
GLfloat anisotropy = float(1u << params.anisotropyLog2);
|
||||
glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT,
|
||||
std::min(gl.gets.max_anisotropy, anisotropy));
|
||||
}
|
||||
@@ -2711,8 +2692,8 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
DEBUG_MARKER()
|
||||
auto& gl = mContext;
|
||||
|
||||
GLenum const glFormat = getFormat(p.format);
|
||||
GLenum const glType = getType(p.type);
|
||||
GLenum glFormat = getFormat(p.format);
|
||||
GLenum glType = getType(p.type);
|
||||
|
||||
gl.pixelStore(GL_PACK_ROW_LENGTH, (GLint)p.stride);
|
||||
gl.pixelStore(GL_PACK_ALIGNMENT, (GLint)p.alignment);
|
||||
@@ -2727,7 +2708,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
* +--------------------+
|
||||
* | | stride alignment
|
||||
* | | ----------------------->-->
|
||||
* | | +----------------------+--+ low addresses
|
||||
* | | +----------------------+--+ low adresses
|
||||
* | | | | | |
|
||||
* | w | | | bottom | |
|
||||
* | <---------> | | V | |
|
||||
@@ -2737,7 +2718,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +---------+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* | y | | +----------------------+--+ high adresses
|
||||
* +------------+-------+
|
||||
* Image is "flipped" vertically
|
||||
* "bottom" is from the "top" (low addresses)
|
||||
@@ -2763,8 +2744,9 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
auto& gl = mContext;
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
|
||||
void* vaddr = nullptr;
|
||||
std::unique_ptr<uint8_t> clientBuffer;
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
std::unique_ptr<uint8_t> clientBuffer = std::make_unique<uint8_t>(p.size);
|
||||
clientBuffer.reset(new uint8_t(p.size));
|
||||
glGetBufferSubData(GL_PIXEL_PACK_BUFFER, 0, p.size, clientBuffer.get());
|
||||
vaddr = clientBuffer.get();
|
||||
#else
|
||||
@@ -2772,10 +2754,10 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
#endif
|
||||
if (vaddr) {
|
||||
// now we need to flip the buffer vertically to match our API
|
||||
size_t const stride = p.stride ? p.stride : width;
|
||||
size_t const bpp = PixelBufferDescriptor::computeDataSize(
|
||||
size_t stride = p.stride ? p.stride : width;
|
||||
size_t bpp = PixelBufferDescriptor::computeDataSize(
|
||||
p.format, p.type, 1, 1, 1);
|
||||
size_t const bpr = PixelBufferDescriptor::computeDataSize(
|
||||
size_t bpr = PixelBufferDescriptor::computeDataSize(
|
||||
p.format, p.type, stride, 1, p.alignment);
|
||||
char const* head = (char const*)vaddr + p.left * bpp + bpr * p.top;
|
||||
char* tail = (char*)p.buffer + p.left * bpp + bpr * (p.top + height - 1);
|
||||
@@ -2862,14 +2844,14 @@ void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
|
||||
auto& v = mGpuCommandCompleteOps;
|
||||
auto it = v.begin();
|
||||
while (it != v.end()) {
|
||||
GLenum const status = glClientWaitSync(it->first, 0, 0);
|
||||
GLenum status = glClientWaitSync(it->first, 0, 0);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED) {
|
||||
it->second();
|
||||
glDeleteSync(it->first);
|
||||
it = v.erase(it);
|
||||
} else if (UTILS_UNLIKELY(status == GL_WAIT_FAILED)) {
|
||||
// This should never happen, but is very problematic if it does, as we might leak
|
||||
// some data depending on what the callback does. However, we clean up our own state.
|
||||
// some data depending on what the callback does. However, we clean-up our own state.
|
||||
glDeleteSync(it->first);
|
||||
it = v.erase(it);
|
||||
} else {
|
||||
@@ -2919,15 +2901,13 @@ void OpenGLDriver::tick(int) {
|
||||
executeEveryNowAndThenOps();
|
||||
}
|
||||
|
||||
void OpenGLDriver::beginFrame(
|
||||
UTILS_UNUSED int64_t monotonic_clock_ns,
|
||||
UTILS_UNUSED uint32_t frameId) {
|
||||
void OpenGLDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
|
||||
DEBUG_MARKER()
|
||||
auto& gl = mContext;
|
||||
insertEventMarker("beginFrame");
|
||||
if (UTILS_UNLIKELY(!mTexturesWithStreamsAttached.empty())) {
|
||||
if (UTILS_UNLIKELY(!mExternalStreams.empty())) {
|
||||
OpenGLPlatform& platform = mPlatform;
|
||||
for (GLTexture const* t : mTexturesWithStreamsAttached) {
|
||||
for (GLTexture const* t : mExternalStreams) {
|
||||
assert_invariant(t && t->hwStream);
|
||||
if (t->hwStream->streamType == StreamType::NATIVE) {
|
||||
assert_invariant(t->hwStream->stream);
|
||||
@@ -2955,7 +2935,7 @@ void OpenGLDriver::setPresentationTime(int64_t monotonic_clock_ns) {
|
||||
mPlatform.setPresentationTime(monotonic_clock_ns);
|
||||
}
|
||||
|
||||
void OpenGLDriver::endFrame(UTILS_UNUSED uint32_t frameId) {
|
||||
void OpenGLDriver::endFrame(uint32_t frameId) {
|
||||
DEBUG_MARKER()
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// WebGL builds are single-threaded so users might manipulate various GL state after we're
|
||||
@@ -3058,7 +3038,7 @@ void OpenGLDriver::blit(TargetBufferFlags buffers,
|
||||
DEBUG_MARKER()
|
||||
auto& gl = mContext;
|
||||
|
||||
GLbitfield const mask = getAttachmentBitfield(buffers);
|
||||
GLbitfield mask = getAttachmentBitfield(buffers);
|
||||
if (mask) {
|
||||
GLenum glFilterMode = (filter == SamplerMagFilter::NEAREST) ? GL_NEAREST : GL_LINEAR;
|
||||
if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
|
||||
@@ -3071,7 +3051,7 @@ void OpenGLDriver::blit(TargetBufferFlags buffers,
|
||||
// buffer -- this should produce the same output that if we copied from the resolved
|
||||
// texture. EXT_multisampled_render_to_texture seems to allow both behaviours, and this
|
||||
// is an emulation of that. We cannot use the resolved texture easily because it's not
|
||||
// actually attached to the RenderTarget. Another implementation would be to do a
|
||||
// actually attached to the this RenderTarget. Another implementation would be to do a
|
||||
// reverse-resolve, but that wouldn't buy us anything.
|
||||
GLRenderTarget const* s = handle_cast<GLRenderTarget const*>(src);
|
||||
GLRenderTarget const* d = handle_cast<GLRenderTarget const*>(dst);
|
||||
@@ -3208,14 +3188,8 @@ void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGr
|
||||
useProgram(p);
|
||||
|
||||
#if defined(GL_ES_VERSION_3_1) || defined(GL_VERSION_4_3)
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// on Android, GLES3.1 and above entry-points are defined in glext
|
||||
// (this is temporary, until we phase-out API < 21)
|
||||
using glext::glDispatchCompute;
|
||||
#endif
|
||||
|
||||
glDispatchCompute(workGroupCount.x, workGroupCount.y, workGroupCount.z);
|
||||
// FIXME: this line is commented-out for now due to issues switching G3 clients to API 21.
|
||||
// glDispatchCompute(workGroupCount.x, workGroupCount.y, workGroupCount.z);
|
||||
#endif
|
||||
|
||||
#ifdef FILAMENT_ENABLE_MATDBG
|
||||
|
||||
@@ -21,14 +21,12 @@
|
||||
#include "GLUtils.h"
|
||||
#include "OpenGLContext.h"
|
||||
|
||||
#include "private/backend/AcquiredImage.h"
|
||||
#include "private/backend/Driver.h"
|
||||
#include "private/backend/HandleAllocator.h"
|
||||
#include "backend/Program.h"
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
|
||||
#include <backend/AcquiredImage.h>
|
||||
#include <backend/Program.h>
|
||||
#include <backend/TargetBufferInfo.h>
|
||||
#include "backend/TargetBufferInfo.h"
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Allocator.h>
|
||||
@@ -50,6 +48,7 @@ class PixelBufferDescriptor;
|
||||
struct TargetBufferInfo;
|
||||
|
||||
class OpenGLProgram;
|
||||
class OpenGLBlitter;
|
||||
class OpenGLTimerQueryInterface;
|
||||
|
||||
class OpenGLDriver final : public DriverBase {
|
||||
@@ -134,7 +133,7 @@ public:
|
||||
uint8_t reserved : 3;
|
||||
} gl;
|
||||
|
||||
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
|
||||
void* platformPImpl = nullptr;
|
||||
};
|
||||
|
||||
struct GLTimerQuery : public HwTimerQuery {
|
||||
@@ -153,6 +152,8 @@ public:
|
||||
struct GLStream : public HwStream {
|
||||
using HwStream::HwStream;
|
||||
struct Info {
|
||||
// storage for the read/write textures below
|
||||
Platform::ExternalTexture* ets = nullptr;
|
||||
GLuint width = 0;
|
||||
GLuint height = 0;
|
||||
};
|
||||
@@ -346,12 +347,7 @@ private:
|
||||
std::array<GLSamplerGroup*, Program::SAMPLER_BINDING_COUNT> mSamplerBindings = {}; // 4 pointers
|
||||
|
||||
mutable tsl::robin_map<uint32_t, GLuint> mSamplerMap;
|
||||
|
||||
// this must be accessed from the driver thread only
|
||||
std::vector<GLTexture*> mTexturesWithStreamsAttached;
|
||||
|
||||
// the must be accessed from the user thread only
|
||||
std::vector<GLStream*> mStreamsWithPendingAcquiredImage;
|
||||
mutable std::vector<GLTexture*> mExternalStreams;
|
||||
|
||||
void attachStream(GLTexture* t, GLStream* stream) noexcept;
|
||||
void detachStream(GLTexture* t) noexcept;
|
||||
@@ -359,8 +355,11 @@ private:
|
||||
|
||||
OpenGLPlatform& mPlatform;
|
||||
|
||||
void updateStreamAcquired(GLTexture* t, DriverApi* driver) noexcept;
|
||||
void updateTextureLodRange(GLTexture* texture, int8_t targetLevel) noexcept;
|
||||
|
||||
void setExternalTexture(GLTexture* t, void* image);
|
||||
|
||||
// tasks executed on the main thread after the fence signaled
|
||||
void whenGpuCommandsComplete(std::function<void()> fn) noexcept;
|
||||
void executeGpuCommandsCompleteOps() noexcept;
|
||||
|
||||
@@ -14,96 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
#include "private/backend/OpenGLPlatform.h"
|
||||
|
||||
#include "OpenGLDriverFactory.h"
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform,
|
||||
void* sharedContext, const Platform::DriverConfig& driverConfig) {
|
||||
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
|
||||
|
||||
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const Platform::DriverConfig& driverConfig) {
|
||||
return OpenGLDriverFactory::create(platform, sharedContext, driverConfig);
|
||||
}
|
||||
|
||||
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
|
||||
|
||||
bool OpenGLPlatform::isSRGBSwapChainSupported() const noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t OpenGLPlatform::createDefaultRenderTarget() noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OpenGLPlatform::setPresentationTime(
|
||||
UTILS_UNUSED int64_t presentationTimeInNanosecond) noexcept {
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLPlatform::canCreateFence() noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
Platform::Fence* OpenGLPlatform::createFence() noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenGLPlatform::destroyFence(
|
||||
UTILS_UNUSED Fence* fence) noexcept {
|
||||
}
|
||||
|
||||
FenceStatus OpenGLPlatform::waitFence(
|
||||
UTILS_UNUSED Fence* fence,
|
||||
UTILS_UNUSED uint64_t timeout) noexcept {
|
||||
return FenceStatus::ERROR;
|
||||
}
|
||||
|
||||
|
||||
Platform::Stream* OpenGLPlatform::createStream(
|
||||
UTILS_UNUSED void* nativeStream) noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenGLPlatform::destroyStream(
|
||||
UTILS_UNUSED Stream* stream) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLPlatform::attach(
|
||||
UTILS_UNUSED Stream* stream,
|
||||
UTILS_UNUSED intptr_t tname) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLPlatform::detach(
|
||||
UTILS_UNUSED Stream* stream) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLPlatform::updateTexImage(
|
||||
UTILS_UNUSED Stream* stream,
|
||||
UTILS_UNUSED int64_t* timestamp) noexcept {
|
||||
}
|
||||
|
||||
|
||||
OpenGLPlatform::ExternalTexture* OpenGLPlatform::createExternalImageTexture() noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenGLPlatform::destroyExternalImage(
|
||||
UTILS_UNUSED ExternalTexture* texture) noexcept {
|
||||
}
|
||||
|
||||
void OpenGLPlatform::retainExternalImage(
|
||||
UTILS_UNUSED void* externalImage) noexcept {
|
||||
}
|
||||
|
||||
bool OpenGLPlatform::setExternalImage(
|
||||
UTILS_UNUSED void* externalImage,
|
||||
UTILS_UNUSED ExternalTexture* texture) noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
AcquiredImage OpenGLPlatform::transformAcquiredImage(AcquiredImage source) noexcept {
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -81,7 +81,7 @@ OpenGLProgram::~OpenGLProgram() noexcept {
|
||||
}
|
||||
const GLuint program = gl.program;
|
||||
UTILS_NOUNROLL
|
||||
for (GLuint const shader: gl.shaders) {
|
||||
for (GLuint shader: gl.shaders) {
|
||||
if (shader) {
|
||||
if (program) {
|
||||
glDetachShader(program, shader);
|
||||
@@ -103,18 +103,18 @@ void OpenGLProgram::compileShaders(OpenGLContext& context,
|
||||
Program::ShaderSource shadersSource,
|
||||
utils::FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
|
||||
GLuint shaderIds[Program::SHADER_TYPE_COUNT],
|
||||
UTILS_UNUSED_IN_RELEASE std::array<CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept {
|
||||
std::array<CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept {
|
||||
|
||||
std::string specializationConstantString;
|
||||
std::string specificationConstantString;
|
||||
for (auto const& sc : specializationConstants) {
|
||||
specializationConstantString += "#define SPIRV_CROSS_CONSTANT_ID_" + std::to_string(sc.id) + ' ';
|
||||
specializationConstantString += std::visit([](auto&& arg) {
|
||||
specificationConstantString += "#define SPIRV_CROSS_CONSTANT_ID_" + std::to_string(sc.id) + ' ';
|
||||
specificationConstantString += std::visit([](auto&& arg) {
|
||||
return std::to_string(arg);
|
||||
}, sc.value);
|
||||
specializationConstantString += '\n';
|
||||
specificationConstantString += '\n';
|
||||
}
|
||||
if (!specializationConstantString.empty()) {
|
||||
specializationConstantString += '\n';
|
||||
if (!specificationConstantString.empty()) {
|
||||
specificationConstantString += '\n';
|
||||
}
|
||||
|
||||
// build all shaders
|
||||
@@ -132,7 +132,7 @@ void OpenGLProgram::compileShaders(OpenGLContext& context,
|
||||
Program::ShaderBlob& shader = shadersSource[i];
|
||||
|
||||
// remove GOOGLE_cpp_style_line_directive
|
||||
std::string_view const source = process_GOOGLE_cpp_style_line_directive(context,
|
||||
std::string_view source = process_GOOGLE_cpp_style_line_directive(context,
|
||||
reinterpret_cast<char*>(shader.data()), shader.size());
|
||||
|
||||
// add support for ARB_shading_language_packing if needed
|
||||
@@ -143,19 +143,19 @@ void OpenGLProgram::compileShaders(OpenGLContext& context,
|
||||
|
||||
const std::array<const char*, 4> sources = {
|
||||
prolog.data(),
|
||||
specializationConstantString.c_str(),
|
||||
specificationConstantString.c_str(),
|
||||
packingFunctions.data(),
|
||||
body.data()
|
||||
};
|
||||
|
||||
const std::array<GLint, 4> lengths = {
|
||||
(GLint)prolog.length(),
|
||||
(GLint)specializationConstantString.length(),
|
||||
(GLint)specificationConstantString.length(),
|
||||
(GLint)packingFunctions.length(),
|
||||
(GLint)body.length() - 1 // null terminated
|
||||
};
|
||||
|
||||
GLuint const shaderId = glCreateShader(glShaderType);
|
||||
GLuint shaderId = glCreateShader(glShaderType);
|
||||
glShaderSource(shaderId, sources.size(), sources.data(), lengths.data());
|
||||
glCompileShader(shaderId);
|
||||
|
||||
@@ -246,8 +246,8 @@ std::array<std::string_view, 2> OpenGLProgram::splitShaderSource(std::string_vie
|
||||
auto eol = source.find('\n', pos) + 1;
|
||||
assert_invariant(eol != std::string_view::npos);
|
||||
|
||||
std::string_view const version = source.substr(start, eol - start);
|
||||
std::string_view const body = source.substr(version.length(), source.length() - version.length());
|
||||
std::string_view version = source.substr(start, eol - start);
|
||||
std::string_view body = source.substr(version.length(), source.length() - version.length());
|
||||
return { version, body };
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ std::array<std::string_view, 2> OpenGLProgram::splitShaderSource(std::string_vie
|
||||
* program itself is valid).
|
||||
*/
|
||||
GLuint OpenGLProgram::linkProgram(const GLuint shaderIds[Program::SHADER_TYPE_COUNT]) noexcept {
|
||||
GLuint const program = glCreateProgram();
|
||||
GLuint program = glCreateProgram();
|
||||
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
||||
if (shaderIds[i]) {
|
||||
glAttachShader(program, shaderIds[i]);
|
||||
@@ -286,15 +286,13 @@ bool OpenGLProgram::checkProgramStatus(const char* name,
|
||||
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
||||
const ShaderStage type = static_cast<ShaderStage>(i);
|
||||
const GLuint shader = shaderIds[i];
|
||||
if (shader) {
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE) {
|
||||
logCompilationError(slog.e, type, name, shader, shaderSourceCode[i]);
|
||||
}
|
||||
glDetachShader(program, shader);
|
||||
glDeleteShader(shader);
|
||||
shaderIds[i] = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status != GL_TRUE) {
|
||||
logCompilationError(slog.e, type, name, shader, shaderSourceCode[i]);
|
||||
}
|
||||
glDetachShader(program, shader);
|
||||
glDeleteShader(shader);
|
||||
shaderIds[i] = 0;
|
||||
}
|
||||
// log the link error as well
|
||||
logProgramLinkError(slog.e, name, program);
|
||||
@@ -342,9 +340,9 @@ void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint progra
|
||||
for (GLuint binding = 0, n = lazyInitializationData.uniformBlockInfo.size(); binding < n; binding++) {
|
||||
auto const& name = lazyInitializationData.uniformBlockInfo[binding];
|
||||
if (!name.empty()) {
|
||||
GLuint const index = glGetUniformBlockIndex(program, name.c_str());
|
||||
if (index != GL_INVALID_INDEX) {
|
||||
glUniformBlockBinding(program, index, binding);
|
||||
GLint index = glGetUniformBlockIndex(program, name.c_str());
|
||||
if (index >= 0) {
|
||||
glUniformBlockBinding(program, GLuint(index), binding);
|
||||
}
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
@@ -369,7 +367,7 @@ void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint progra
|
||||
UTILS_NOUNROLL
|
||||
for (const Program::Sampler& sampler: samplers) {
|
||||
// find its location and associate a TMU to it
|
||||
GLint const loc = glGetUniformLocation(program, sampler.name.c_str());
|
||||
GLint loc = glGetUniformLocation(program, sampler.name.c_str());
|
||||
if (loc >= 0) {
|
||||
// this can fail if the program doesn't use this sampler
|
||||
glUniform1i(loc, tmu);
|
||||
@@ -404,7 +402,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) const noexcept {
|
||||
assert_invariant(sb);
|
||||
for (uint8_t j = 0, m = sb->textureUnitEntries.size(); j < m; ++j, ++tmu) { // "<=" on purpose here
|
||||
const GLTexture* const t = sb->textureUnitEntries[j].texture;
|
||||
GLuint const s = sb->textureUnitEntries[j].sampler;
|
||||
GLuint s = sb->textureUnitEntries[j].sampler;
|
||||
if (t) { // program may not use all samplers of sampler group
|
||||
if (UTILS_UNLIKELY(t->gl.fence)) {
|
||||
glWaitSync(t->gl.fence, 0, GL_TIMEOUT_IGNORED);
|
||||
@@ -421,8 +419,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) const noexcept {
|
||||
|
||||
UTILS_NOINLINE
|
||||
void logCompilationError(io::ostream& out, ShaderStage shaderType,
|
||||
const char* name, GLuint shaderId,
|
||||
UTILS_UNUSED_IN_RELEASE CString const& sourceCode) noexcept {
|
||||
const char* name, GLuint shaderId, CString const& sourceCode) noexcept {
|
||||
|
||||
auto to_string = [](ShaderStage type) -> const char* {
|
||||
switch (type) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user