Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2fa38590d |
@@ -10,14 +10,10 @@ on:
|
||||
jobs:
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest-xl, ubuntu-22.04-16core]
|
||||
os: [macos-latest, ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
@@ -40,21 +40,17 @@ jobs:
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh presubmit
|
||||
|
||||
build-ios:
|
||||
name: build-iOS
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
@@ -67,7 +63,7 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest-xl, ubuntu-22.04-16core]
|
||||
os: [macos-latest, ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
|
||||
|
||||
steps:
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
|
||||
|
||||
steps:
|
||||
@@ -112,10 +112,6 @@ jobs:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
@@ -153,7 +149,7 @@ jobs:
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
|
||||
|
||||
steps:
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest-xl
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
+1
-2
@@ -13,10 +13,9 @@ section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio Flamingo or more recent
|
||||
- Android Studio Arctic Fox or more recent
|
||||
- Android SDK
|
||||
- Android NDK 25.1 or higher
|
||||
- Java 17
|
||||
|
||||
### Environment variables
|
||||
|
||||
|
||||
+1
-6
@@ -124,16 +124,11 @@ if (LINUX)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
endif()
|
||||
|
||||
# Default Swiftshader build does not enable the xlib extension
|
||||
if (FILAMENT_SUPPORTS_XLIB AND FILAMENT_USE_SWIFTSHADER)
|
||||
set(FILAMENT_SUPPORTS_XLIB OFF)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPPORTS_XLIB)
|
||||
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_X11)
|
||||
set(FILAMENT_SUPPORTS_X11 TRUE)
|
||||
endif()
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2023 The Android Open Source Project
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.36.0'
|
||||
implementation 'com.google.android.filament:filament-android:1.32.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -41,6 +41,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
| ------------- | ------------- |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||
@@ -50,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.36.0'
|
||||
pod 'Filament', '~> 1.32.0'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
+58
-13
@@ -13,7 +13,22 @@ Before starting, ensure that each of these branches is up-to-date with origin:
|
||||
|
||||
It should have the version corresponding to its name, $RELEASE.
|
||||
|
||||
## 1. Bump versions on main to $RELEASE.
|
||||
## 1. Update RELEASE_NOTES.md on the rc branch.
|
||||
|
||||
Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE
|
||||
and write release notes. To see which commits make up the release, run:
|
||||
|
||||
```
|
||||
build/common/release.sh -c rc/$RELEASE
|
||||
```
|
||||
|
||||
Commit the changes to rc/$RELEASE with the title:
|
||||
|
||||
```
|
||||
Update RELEASE_NOTES for $RELEASE
|
||||
```
|
||||
|
||||
## 2. Bump versions on main to $RELEASE.
|
||||
|
||||
Checkout main and run the following command to bump Filament's version to $RELEASE:
|
||||
|
||||
@@ -29,19 +44,49 @@ Release Filament $RELEASE
|
||||
|
||||
Do not push to origin yet.
|
||||
|
||||
## 2. Update RELEASE_NOTES.md on main.
|
||||
## 3. Cherry-pick RELEASE_NOTES change from rc branch to main.
|
||||
|
||||
Create a new header in RELEASE_NOTES.md for $NEXT_RELEASE. Copy the release notes in
|
||||
NEW_RELEASE_NOTES.md to RELEASE_NOTES.md under the new header. Clear NEW_RELEASE_NOTES.md.
|
||||
```
|
||||
git cherry-pick rc/$RELEASE
|
||||
```
|
||||
|
||||
Amend these changes to the "Release Filament $RELEASE" commit.
|
||||
Update the headers. The "main branch" header becomes a header for $NEXT_RELEASE, and a new "main
|
||||
branch" header is added.
|
||||
|
||||
For example, this:
|
||||
|
||||
```
|
||||
## main branch
|
||||
- foo
|
||||
- bar
|
||||
|
||||
## v1.9.3
|
||||
- baz
|
||||
- bat
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
## main branch
|
||||
|
||||
## v1.9.4
|
||||
- foo
|
||||
- bar
|
||||
|
||||
## v1.9.3
|
||||
- baz
|
||||
- bat
|
||||
```
|
||||
|
||||
Ammend these changes to the cherry-picked change.
|
||||
|
||||
```
|
||||
git add -u
|
||||
git commit --amend --no-edit
|
||||
```
|
||||
|
||||
## 3. Run release script.
|
||||
## 4. Run release script.
|
||||
|
||||
```
|
||||
build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
|
||||
@@ -50,18 +95,18 @@ build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
|
||||
This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc
|
||||
branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally.
|
||||
|
||||
## 4. Push the release branch.
|
||||
## 5. Push the release branch.
|
||||
|
||||
```
|
||||
git push origin release
|
||||
```
|
||||
|
||||
## 5. Create the GitHub release.
|
||||
## 6. Create the GitHub release.
|
||||
|
||||
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
|
||||
Make sure the target is set to the release branch.
|
||||
|
||||
## 6. Delete the old rc branch (optional).
|
||||
## 7. Delete the old rc branch (optional).
|
||||
|
||||
This step is optional. The old rc branch may be left alive for a few weeks for posterity.
|
||||
|
||||
@@ -69,7 +114,7 @@ This step is optional. The old rc branch may be left alive for a few weeks for p
|
||||
git push origin --delete rc/$RELEASE
|
||||
```
|
||||
|
||||
## 7. Bump the version on the new rc branch to $NEXT_RELEASE.
|
||||
## 8. Bump the version on the new rc branch to $NEXT_RELEASE.
|
||||
|
||||
```
|
||||
git checkout rc/$NEXT_RELEASE
|
||||
@@ -82,19 +127,19 @@ Commit the changes to rc/$NEXT_RELEASE with the title:
|
||||
Bump version to $NEXT_RELEASE
|
||||
```
|
||||
|
||||
## 8. Push main.
|
||||
## 9. Push main.
|
||||
|
||||
```
|
||||
git push origin main
|
||||
```
|
||||
|
||||
## 9. Push the new rc branch.
|
||||
## 10. Push the new rc branch.
|
||||
|
||||
```
|
||||
git push origin -u rc/$NEXT_RELEASE
|
||||
```
|
||||
|
||||
## 10. Rebuild the GitHub release (if failed).
|
||||
## 11. Rebuild the GitHub release (if failed).
|
||||
|
||||
Sometimes the GitHub release job will fail. In this case, you can manually re-run the release job.
|
||||
|
||||
|
||||
@@ -7,50 +7,6 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.36.0
|
||||
|
||||
- engine: a local transform can now be supplied for each GPU instance [⚠️ **Recompile materials**]
|
||||
- everything: Add limited support for OpenGL ES 2.0 devices. [⚠️ **Recompile Materials**]
|
||||
- platform: New virtual on `OpenGLPlatform` to preserve ancillary buffers
|
||||
|
||||
## v1.35.0
|
||||
|
||||
- materials: Materials can now access up to 4 global `vec4` visible by all materials [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.34.0
|
||||
|
||||
- materials: picking is done in float (prepare for ES2) [⚠️ **New Material Version**]
|
||||
- materials: postLightingBlending is now applied before the fog [⚠️ **Recompile materials**]
|
||||
- vulkan: fix adreno optimized material artifacts [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.33.0
|
||||
|
||||
- materials: prepare ES2 support [⚠️ **New Material Version**]
|
||||
|
||||
## v1.32.4
|
||||
|
||||
- engine: Add support for _constant parameters_, which are constants that can be specialized after material compilation.
|
||||
- materials: improved size reduction of OpenGL/Metal shaders by ~65% when compiling materials with
|
||||
size optimizations (`matc -S`) [⚠️ **Recompile Materials**]
|
||||
- engine: fix potential crash on Metal devices with A8X GPU (iPad Air 2) [⚠️ **Recompile Materials**]
|
||||
- opengl: support the external image on macOS
|
||||
|
||||
## v1.32.3
|
||||
|
||||
- fog: added an option to disable the fog after a certain distance [⚠️ **Recompile Materials**].
|
||||
- fog: fog color now takes exposure and IBL intensity into account [⚠️ **Recompile Materials**].
|
||||
- materials: implement cascades debugging as a post-process [⚠️ **Recompile Materials**].
|
||||
- materials: use 9 digits or less for floats [⚠️ **Recompile Materials**].
|
||||
- gltfio: fix skinning when objects are far from the origin
|
||||
- materials: remove 4 unneeded variants from `unlit` materials [⚠️ **Recompile Materials**].
|
||||
|
||||
## v1.32.2
|
||||
|
||||
- lighting: the sun disc was computed in low/medium quality instead of high quality. This will
|
||||
provide performance improvements to mobile devices [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.32.1
|
||||
|
||||
## v1.32.0
|
||||
|
||||
- fog: fixed fog height falloff and computation precision on mobile [⚠️ **Recompile Materials**]
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
// - Build and upload artifacts with ./gradlew publish
|
||||
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseStagingRepository
|
||||
//
|
||||
// These commands must both be run in the same Gradle invocation:
|
||||
// ./gradlew publish closeAndReleaseStagingRepository
|
||||
//
|
||||
// The following is needed in ~/gradle/gradle.properties:
|
||||
//
|
||||
// sonatypeUsername=nexus_user
|
||||
@@ -79,15 +82,14 @@ buildscript {
|
||||
}
|
||||
|
||||
ext.versions = [
|
||||
'jdk': 17,
|
||||
'minSdk': 19,
|
||||
'targetSdk': 33,
|
||||
'compileSdk': 33,
|
||||
'kotlin': '1.8.20',
|
||||
'kotlin': '1.8.0',
|
||||
'kotlin_coroutines': '1.6.4',
|
||||
'buildTools': '33.0.2',
|
||||
'buildTools': '33.0.1',
|
||||
'ndk': '25.1.8937393',
|
||||
'androidx_core': '1.10.0',
|
||||
'androidx_core': '1.9.0',
|
||||
'androidx_annotations': '1.3.0'
|
||||
]
|
||||
|
||||
@@ -104,7 +106,7 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.0.0'
|
||||
classpath 'com.android.tools.build:gradle:7.4.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -127,7 +129,6 @@ buildscript {
|
||||
"-fno-asynchronous-unwind-tables",
|
||||
"-fno-rtti",
|
||||
"-ffast-math",
|
||||
"-fno-finite-math-only",
|
||||
"-ffp-contract=fast",
|
||||
"-fvisibility-inlines-hidden",
|
||||
"-fvisibility=hidden",
|
||||
@@ -195,7 +196,6 @@ subprojects {
|
||||
}
|
||||
|
||||
ndk {
|
||||
//noinspection ChromeOsAbiSupport
|
||||
abiFilters(*rootProject.ext.abis)
|
||||
}
|
||||
|
||||
@@ -216,8 +216,8 @@ subprojects {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,14 +142,6 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
if (!exclude_vulkan) {
|
||||
matcArgs += ['-a', 'vulkan']
|
||||
}
|
||||
|
||||
def mat_no_opt = providers
|
||||
.gradleProperty("com.google.android.filament.matnopt")
|
||||
.forUseAtConfigurationTime().present
|
||||
if (mat_no_opt) {
|
||||
matcArgs += ['-g']
|
||||
}
|
||||
|
||||
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
|
||||
|
||||
exec.exec {
|
||||
|
||||
@@ -17,17 +17,6 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
singleVariant("fullRelease") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
singleVariant("liteRelease") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament'
|
||||
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -315,13 +315,12 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong nativeView,
|
||||
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat cutOffDistance,
|
||||
jfloat r, jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
|
||||
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat r,
|
||||
jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
|
||||
jfloat inScatteringSize, jboolean fogColorFromIbl, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
View::FogOptions options = {
|
||||
.distance = distance,
|
||||
.cutOffDistance = cutOffDistance,
|
||||
.maximumOpacity = maximumOpacity,
|
||||
.height = height,
|
||||
.heightFalloff = heightFalloff,
|
||||
@@ -486,22 +485,3 @@ Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
|
||||
View* view = (View*) nativeView;
|
||||
view->setGuardBandOptions({ .enabled = (bool)enabled });
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetMaterialGlobal(JNIEnv * , jclass, jlong nativeView,
|
||||
jint index, jfloat x, jfloat y, jfloat z, jfloat w) {
|
||||
View *view = (View *) nativeView;
|
||||
view->setMaterialGlobal((uint32_t)index, { x, y, z, w });
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nGetMaterialGlobal(JNIEnv *env, jclass clazz,
|
||||
jlong nativeView, jint index, jfloatArray out_) {
|
||||
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
|
||||
View *view = (View *) nativeView;
|
||||
auto result = view->getMaterialGlobal(index);
|
||||
std::copy_n(result.v, 4, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,6 @@ public class ColorGrading {
|
||||
*
|
||||
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
public enum ToneMapping {
|
||||
/** Linear tone mapping (i.e. no tone mapping). */
|
||||
LINEAR,
|
||||
@@ -232,7 +231,6 @@ public class ColorGrading {
|
||||
*
|
||||
* @deprecated Use {@link #toneMapper(ToneMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder toneMapping(ToneMapping toneMapping) {
|
||||
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
|
||||
return this;
|
||||
|
||||
+3
-3
@@ -356,16 +356,16 @@ public class RenderableManager {
|
||||
|
||||
/**
|
||||
* Specifies the number of draw instance of this renderable. The default is 1 instance and
|
||||
* the maximum number of instances allowed is 32767. 0 is invalid.
|
||||
* the maximum number of instances allowed is 65535. 0 is invalid.
|
||||
* All instances are culled using the same bounding box, so care must be taken to make
|
||||
* sure all instances render inside the specified bounding box.
|
||||
* The material can use getInstanceIndex() in the vertex shader to get the instance index and
|
||||
* possibly adjust the position or transform.
|
||||
*
|
||||
* @param instanceCount the number of instances silently clamped between 1 and 32767.
|
||||
* @param instanceCount the number of instances silently clamped between 1 and 65535.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder instances(@IntRange(from = 1, to = 32767) int instanceCount) {
|
||||
public Builder instances(@IntRange(from = 1, to = 65535) int instanceCount) {
|
||||
nBuilderInstances(mNativeBuilder, instanceCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -962,8 +962,7 @@ public class View {
|
||||
assertFloat3In(options.color);
|
||||
mFogOptions = options;
|
||||
nSetFogOptions(getNativeObject(), options.distance, options.maximumOpacity, options.height,
|
||||
options.heightFalloff, options.cutOffDistance,
|
||||
options.color[0], options.color[1], options.color[2],
|
||||
options.heightFalloff, options.color[0], options.color[1], options.color[2],
|
||||
options.density, options.inScatteringStart, options.inScatteringSize,
|
||||
options.fogColorFromIbl,
|
||||
options.enabled);
|
||||
@@ -1117,37 +1116,6 @@ public class View {
|
||||
float mFragCoordsZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of material global variables. There are up-to four such variable each of
|
||||
* type float4. These variables can be read in a user Material with
|
||||
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
|
||||
*
|
||||
* @param index index of the variable to set between 0 and 3.
|
||||
* @param value new value for the variable.
|
||||
* @see #getMaterialGlobal
|
||||
*/
|
||||
public void setMaterialGlobal(int index, @NonNull @Size(min = 4) float[] value) {
|
||||
Asserts.assertFloat4In(value);
|
||||
nSetMaterialGlobal(getNativeObject(), index, value[0], value[1], value[2], value[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the material global variables.
|
||||
* All variable start with a default value of { 0, 0, 0, 1 }
|
||||
*
|
||||
* @param index index of the variable to set between 0 and 3.
|
||||
* @param out A 4-float array where the value will be stored, or null in which case the array is
|
||||
* allocated.
|
||||
* @return A 4-float array containing the current value of the variable.
|
||||
* @see #setMaterialGlobal
|
||||
*/
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getMaterialGlobal(int index, @Nullable @Size(min = 4) float[] out) {
|
||||
out = Asserts.assertFloat4(out);
|
||||
nGetMaterialGlobal(getNativeObject(), index, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed View");
|
||||
@@ -1189,7 +1157,7 @@ public class View {
|
||||
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
|
||||
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float cutOffDistance, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
private static native void nSetBlendMode(long nativeView, int blendMode);
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
|
||||
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
|
||||
@@ -1204,9 +1172,6 @@ public class View {
|
||||
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
|
||||
private static native void nSetStencilBufferEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsStencilBufferEnabled(long nativeView);
|
||||
private static native void nSetMaterialGlobal(long nativeView, int index, float x, float y, float z, float w);
|
||||
private static native void nGetMaterialGlobal(long nativeView, int index, float[] out);
|
||||
|
||||
|
||||
/**
|
||||
* List of available ambient occlusion techniques.
|
||||
@@ -1427,87 +1392,48 @@ public class View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to control large-scale fog in the scene
|
||||
* Options to control fog in the scene
|
||||
*/
|
||||
public static class FogOptions {
|
||||
/**
|
||||
* Distance in world units [m] from the camera to where the fog starts ( >= 0.0 )
|
||||
* distance in world units from the camera where the fog starts ( >= 0.0 )
|
||||
*/
|
||||
public float distance = 0.0f;
|
||||
/**
|
||||
* Distance in world units [m] after which the fog calculation is disabled.
|
||||
* This can be used to exclude the skybox, which is desirable if it already contains clouds or
|
||||
* fog. The default value is +infinity which applies the fog to everything.
|
||||
*
|
||||
* Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
|
||||
* plane distance and projection used though).
|
||||
*/
|
||||
public float cutOffDistance = Float.POSITIVE_INFINITY;
|
||||
/**
|
||||
* fog's maximum opacity between 0 and 1
|
||||
*/
|
||||
public float maximumOpacity = 1.0f;
|
||||
/**
|
||||
* Fog's floor in world units [m]. This sets the "sea level".
|
||||
* fog's floor in world units
|
||||
*/
|
||||
public float height = 0.0f;
|
||||
/**
|
||||
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
|
||||
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
|
||||
* factor 2.78 (e) change in fog density.
|
||||
*
|
||||
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
|
||||
* faster computations.
|
||||
* how fast fog dissipates with altitude
|
||||
*/
|
||||
public float heightFalloff = 1.0f;
|
||||
/**
|
||||
* Fog's color is used for ambient light in-scattering, a good value is
|
||||
* to use the average of the ambient light, possibly tinted towards blue
|
||||
* for outdoors environments. Color component's values should be between 0 and 1, values
|
||||
* above one are allowed but could create a non energy-conservative fog (this is dependant
|
||||
* on the IBL's intensity as well).
|
||||
*
|
||||
* We assume that our fog has no absorption and therefore all the light it scatters out
|
||||
* becomes ambient light in-scattering and has lost all directionality, i.e.: scattering is
|
||||
* isotropic. This somewhat simulates Rayleigh scattering.
|
||||
*
|
||||
* This value is used as a tint instead, when fogColorFromIbl is enabled.
|
||||
*
|
||||
* @see fogColorFromIbl
|
||||
* fog's color (linear), see fogColorFromIbl
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] color = {1.0f, 1.0f, 1.0f};
|
||||
public float[] color = {0.5f, 0.5f, 0.5f};
|
||||
/**
|
||||
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
|
||||
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
|
||||
* the incoming light to 37% of its original value.
|
||||
*
|
||||
* Note: The extinction factor is related to the fog density, it's usually some constant K times
|
||||
* the density at sea level (more specifically at fog height). The constant K depends on
|
||||
* the composition of the fog/atmosphere.
|
||||
*
|
||||
* For historical reason this parameter is called `density`.
|
||||
* fog's density at altitude given by 'height'
|
||||
*/
|
||||
public float density = 0.1f;
|
||||
/**
|
||||
* Distance in world units [m] from the camera where the Sun in-scattering starts.
|
||||
* distance in world units from the camera where in-scattering starts
|
||||
*/
|
||||
public float inScatteringStart = 0.0f;
|
||||
/**
|
||||
* Very inaccurately simulates the Sun's in-scattering. That is, the light from the sun that
|
||||
* is scattered (by the fog) towards the camera.
|
||||
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
* Smaller values result is a larger scattering size.
|
||||
* size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
*/
|
||||
public float inScatteringSize = -1.0f;
|
||||
/**
|
||||
* The fog color will be sampled from the IBL in the view direction and tinted by `color`.
|
||||
* Depending on the scene this can produce very convincing results.
|
||||
* This simulate a more anisotropic phase-function.
|
||||
* Fog color will be modulated by the IBL color in the view direction.
|
||||
*/
|
||||
public boolean fogColorFromIbl = false;
|
||||
/**
|
||||
* Enable or disable large-scale fog
|
||||
* enable or disable fog
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
}
|
||||
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.android;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Fence;
|
||||
|
||||
public class FilamentHelper {
|
||||
|
||||
/**
|
||||
* Wait for all pending frames to be processed before returning. This is to
|
||||
* avoid a race between the surface being resized before pending frames are
|
||||
* rendered into it. This is typically called from {@link UiHelper.RendererCallback#onResized},
|
||||
* {@link android.view.SurfaceHolder.Callback#surfaceChanged} or
|
||||
* {@link android.view.TextureView.SurfaceTextureListener#onSurfaceTextureSizeChanged}.
|
||||
*
|
||||
* @param engine Filament engine to synchronize
|
||||
*
|
||||
* @see UiHelper.RendererCallback#onResized
|
||||
* @see android.view.SurfaceHolder.Callback#surfaceChanged
|
||||
* @see android.view.TextureView.SurfaceTextureListener#onSurfaceTextureSizeChanged
|
||||
*/
|
||||
static public void synchronizePendingFrames(Engine engine) {
|
||||
Fence fence = engine.createFence();
|
||||
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
|
||||
engine.destroyFence(fence);
|
||||
}
|
||||
}
|
||||
+3
-11
@@ -84,14 +84,6 @@ import com.google.android.filament.SwapChain;
|
||||
* // The native surface has changed size. This is always called at least once
|
||||
* // after the surface is created (after onNativeWindowChanged() is invoked).
|
||||
* public void onResized(int width, int height) {
|
||||
*
|
||||
* // Wait for all pending frames to be processed before returning. This is to
|
||||
* // avoid a race between the surface being resized before pending frames are
|
||||
* // rendered into it.
|
||||
* Fence fence = mEngine.createFence();
|
||||
* fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
|
||||
* mEngine.destroyFence(fence);
|
||||
*
|
||||
* // Compute camera projection and set the viewport on the view
|
||||
* }
|
||||
* });
|
||||
@@ -183,7 +175,7 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
private static class SurfaceViewHandler implements RenderSurface {
|
||||
private final SurfaceView mSurfaceView;
|
||||
private SurfaceView mSurfaceView;
|
||||
|
||||
SurfaceViewHandler(SurfaceView surface) {
|
||||
mSurfaceView = surface;
|
||||
@@ -200,7 +192,7 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
private static class SurfaceHolderHandler implements RenderSurface {
|
||||
private final SurfaceHolder mSurfaceHolder;
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
|
||||
SurfaceHolderHandler(SurfaceHolder surface) {
|
||||
mSurfaceHolder = surface;
|
||||
@@ -217,7 +209,7 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
private class TextureViewHandler implements RenderSurface {
|
||||
private final TextureView mTextureView;
|
||||
private TextureView mTextureView;
|
||||
private Surface mSurface;
|
||||
|
||||
TextureViewHandler(TextureView surface) { mTextureView = surface; }
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.utils'
|
||||
@@ -24,11 +21,16 @@ android {
|
||||
excludes += ['lib/*/libfilament-jni.so', 'lib/*/libgltfio-jni.so']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
configurations.all { config ->
|
||||
// Hack to preserve the version of the dependencies
|
||||
if (!config.name.endsWith('Publication')) {
|
||||
resolutionStrategy {
|
||||
dependencySubstitution {
|
||||
substitute(module("com.google.android.filament:gltfio-android:${VERSION_NAME}")).with(project(":gltfio-android"))
|
||||
substitute(module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")).with(project(":gltfio-android"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +43,7 @@ dependencies {
|
||||
implementation deps.coroutines.android
|
||||
|
||||
api project(':filament-android')
|
||||
api project(':gltfio-android')
|
||||
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
-1169
File diff suppressed because it is too large
Load Diff
+19
-245
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
@@ -24,16 +24,8 @@ enum class MatrixColumn {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
enum class RotationsOrder(
|
||||
val yaw: VectorComponent,
|
||||
val pitch: VectorComponent,
|
||||
val roll: VectorComponent) {
|
||||
XYZ(VectorComponent.X, VectorComponent.Y, VectorComponent.Z),
|
||||
XZY(VectorComponent.X, VectorComponent.Z, VectorComponent.Y),
|
||||
YXZ(VectorComponent.Y, VectorComponent.X, VectorComponent.Z),
|
||||
YZX(VectorComponent.Y, VectorComponent.Z, VectorComponent.X),
|
||||
ZXY(VectorComponent.Z, VectorComponent.X, VectorComponent.Y),
|
||||
ZYX(VectorComponent.Z, VectorComponent.Y, VectorComponent.X);
|
||||
enum class RotationsOrder {
|
||||
XYZ, XZY, YXZ, YZX, ZXY, ZYX
|
||||
}
|
||||
|
||||
data class Mat2(
|
||||
@@ -85,12 +77,6 @@ data class Mat2(
|
||||
operator fun minus(v: Float) = Mat2(x - v, y - v)
|
||||
operator fun times(v: Float) = Mat2(x * v, y * v)
|
||||
operator fun div(v: Float) = Mat2(x / v, y / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat2(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat2) = Mat2(
|
||||
Float2(
|
||||
@@ -103,18 +89,12 @@ data class Mat2(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat2, delta: Float = 0.0f) = Mat2(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat2, delta: Float = 0.0f) = x.equals(m.x, delta) && y.equals(m.y, delta)
|
||||
|
||||
operator fun times(v: Float2) = Float2(
|
||||
x.x * v.x + y.x * v.y,
|
||||
x.y * v.x + y.y * v.y,
|
||||
)
|
||||
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x,
|
||||
x.y, y.y
|
||||
@@ -126,6 +106,7 @@ data class Mat2(
|
||||
|${x.y} ${y.y}|
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class Mat3(
|
||||
@@ -181,14 +162,6 @@ data class Mat3(
|
||||
operator fun minus(v: Float) = Mat3(x - v, y - v, z - v)
|
||||
operator fun times(v: Float) = Mat3(x * v, y * v, z * v)
|
||||
operator fun div(v: Float) = Mat3(x / v, y / v, z / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat3(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat3) = Mat3(
|
||||
Float3(
|
||||
@@ -208,15 +181,6 @@ data class Mat3(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat3, delta: Float = 0.0f) = Mat3(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta),
|
||||
z.compareTo(m.z, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat3, delta: Float = 0.0f) =
|
||||
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta)
|
||||
|
||||
operator fun times(v: Float3) = Float3(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z,
|
||||
@@ -248,7 +212,6 @@ data class Mat4(
|
||||
constructor(m: Mat4) : this(m.x.copy(), m.y.copy(), m.z.copy(), m.w.copy())
|
||||
|
||||
companion object {
|
||||
|
||||
fun of(vararg a: Float): Mat4 {
|
||||
require(a.size >= 16)
|
||||
return Mat4(
|
||||
@@ -339,15 +302,6 @@ data class Mat4(
|
||||
operator fun minus(v: Float) = Mat4(x - v, y - v, z - v, w - v)
|
||||
operator fun times(v: Float) = Mat4(x * v, y * v, z * v, w * v)
|
||||
operator fun div(v: Float) = Mat4(x / v, y / v, z / v, w / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat4) = Mat4(
|
||||
Float4(
|
||||
@@ -376,16 +330,6 @@ data class Mat4(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat4, delta: Float = 0.0f) = Mat4(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta),
|
||||
z.compareTo(m.z, delta),
|
||||
w.compareTo(m.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat4, delta: Float = 0.0f) =
|
||||
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta) && w.equals(m.w, delta)
|
||||
|
||||
operator fun times(v: Float4) = Float4(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z+ w.x * v.w,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z+ w.y * v.w,
|
||||
@@ -393,26 +337,6 @@ data class Mat4(
|
||||
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
|
||||
)
|
||||
|
||||
/**
|
||||
* Get the Euler angles in degrees from this rotation Matrix
|
||||
*
|
||||
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
|
||||
*
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*
|
||||
* @see eulerAngles
|
||||
*/
|
||||
fun toEulerAngles(order: RotationsOrder = RotationsOrder.ZYX) = eulerAngles(this, order)
|
||||
|
||||
/**
|
||||
* Get the [Quaternion] from this rotation Matrix
|
||||
*
|
||||
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
|
||||
*
|
||||
* @see quaternion
|
||||
*/
|
||||
fun toQuaternion() = quaternion(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
@@ -432,78 +356,6 @@ data class Mat4(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun equal(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
fun transpose(m: Mat2) = Mat2(
|
||||
Float2(m.x.x, m.y.x),
|
||||
Float2(m.x.y, m.y.y)
|
||||
@@ -642,7 +494,14 @@ fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.fo
|
||||
*/
|
||||
fun rotation(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
return rotation(r[order.yaw], r[order.pitch], r[order.roll], order)
|
||||
return when(order) {
|
||||
RotationsOrder.XZY -> rotation(r.x, r.z, r.y)
|
||||
RotationsOrder.XYZ -> rotation(r.x, r.y, r.z)
|
||||
RotationsOrder.YXZ -> rotation(r.y, r.x, r.z)
|
||||
RotationsOrder.YZX -> rotation(r.y, r.z, r.x)
|
||||
RotationsOrder.ZYX -> rotation(r.z, r.y, r.x)
|
||||
RotationsOrder.ZXY -> rotation(r.z, r.x, r.y)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -740,93 +599,13 @@ fun rotation(quaternion: Quaternion): Mat4 {
|
||||
Float4(
|
||||
2.0f * (n.x * n.z + n.y * n.w),
|
||||
2.0f * (n.y * n.z - n.x * n.w),
|
||||
1.0f - 2.0f * (n.x * n.x + n.y * n.y)
|
||||
1.0f - 2.0f * (n.x * n.x + n.y * n.y),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Euler angles in degrees from a rotation Matrix
|
||||
*
|
||||
* @param m The rotation matrix.
|
||||
* Don't forget to extract the rotation with [rotation] if it's transposed
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*/
|
||||
fun eulerAngles(m: Mat4, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
|
||||
// We need to more simplify this with RotationsOrder VectorComponents mapped to MatrixColumn
|
||||
return transform(Float3().apply {
|
||||
when (order) {
|
||||
RotationsOrder.XYZ -> {
|
||||
this[order.pitch] = asin(clamp(m.z.x, -1.0f, 1.0f))
|
||||
if (abs(m.z.x) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(-m.z.y, m.z.z)
|
||||
this[order.roll] = atan2(-m.y.x, m.x.x)
|
||||
} else {
|
||||
this[order.yaw] = atan2(m.y.z, m.y.y)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.XZY -> {
|
||||
this[order.pitch] = asin(-clamp(m.y.x, -1.0f, 1.0f))
|
||||
if (abs(m.y.x) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(m.y.z, m.y.y)
|
||||
this[order.roll] = atan2(m.z.x, m.x.x)
|
||||
} else {
|
||||
this[order.yaw] = atan2(-m.z.y, m.z.z)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.YXZ -> {
|
||||
this[order.pitch] = asin(-clamp(m.z.y, -1.0f, 1.0f))
|
||||
if (abs(m.z.y) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(m.z.x, m.z.z)
|
||||
this[order.roll] = atan2(m.x.y, m.y.y)
|
||||
} else {
|
||||
this[order.yaw] = atan2(-m.x.z, m.x.x)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.YZX -> {
|
||||
this[order.pitch] = asin(clamp(m.x.y, -1.0f, 1.0f))
|
||||
if (abs(m.x.y) < 0.9999999f) {
|
||||
this[order.roll] = atan2(-m.z.y, m.y.y)
|
||||
this[order.yaw] = atan2(-m.x.z, m.x.x)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(m.z.x, m.z.z)
|
||||
}
|
||||
}
|
||||
RotationsOrder.ZXY -> {
|
||||
this[order.pitch] = asin(clamp(m.y.z, -1.0f, 1.0f))
|
||||
if (abs(m.y.z) < 0.9999999f) {
|
||||
this[order.roll] = atan2(-m.x.z, m.z.z)
|
||||
this[order.yaw] = atan2(-m.y.x, m.y.y)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(m.x.y, m.x.x)
|
||||
}
|
||||
}
|
||||
RotationsOrder.ZYX -> {
|
||||
this[order.pitch] = asin(-clamp(m.x.z, -1.0f, 1.0f))
|
||||
if (abs(m.x.z) < 0.9999999f) {
|
||||
this[order.roll] = atan2(m.y.z, m.z.z)
|
||||
this[order.yaw] = atan2(m.x.y, m.x.x)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(-m.y.x, m.y.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ::degrees)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [Quaternion] from a rotation Matrix
|
||||
*
|
||||
* @param m The rotation matrix.
|
||||
* Don't forget to extract the rotation with [rotation] if it's transposed
|
||||
* Extract Quaternion rotation from a Matrix
|
||||
*/
|
||||
fun quaternion(m: Mat4): Quaternion {
|
||||
val trace = m.x.x + m.y.y + m.z.z
|
||||
@@ -894,14 +673,9 @@ fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
|
||||
}
|
||||
|
||||
fun ortho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Mat4(
|
||||
Float4(x = 2.0f / (r - l)),
|
||||
Float4(y = 2.0f / (t - b)),
|
||||
Float4(z = -2.0f / (f - n)),
|
||||
Float4(
|
||||
-(r + l) / (r - l),
|
||||
-(t + b) / (t - b),
|
||||
-(f + n) / (f - n),
|
||||
1.0f
|
||||
)
|
||||
Float4(x = 2.0f / (r - 1.0f)),
|
||||
Float4(y = 2.0f / (t - b)),
|
||||
Float4(z = -2.0f / (f - n)),
|
||||
Float4(-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1.0f)
|
||||
)
|
||||
|
||||
|
||||
-10
@@ -405,19 +405,9 @@ class ModelViewer(
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
cameraManipulator.setViewport(width, height)
|
||||
updateCameraProjection()
|
||||
synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
private fun synchronizePendingFrames(engine: Engine) {
|
||||
// Wait for all pending frames to be processed before returning. This is to
|
||||
// avoid a race between the surface being resized before pending frames are
|
||||
// rendered into it.
|
||||
val fence = engine.createFence()
|
||||
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER)
|
||||
engine.destroyFence(fence)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
|
||||
}
|
||||
|
||||
+66
-232
@@ -33,9 +33,9 @@ data class Quaternion(
|
||||
var x: Float = 0.0f,
|
||||
var y: Float = 0.0f,
|
||||
var z: Float = 0.0f,
|
||||
var w: Float = 1.0f) {
|
||||
var w: Float = 0.0f) {
|
||||
|
||||
constructor(v: Float3, w: Float = 1.0f) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Float3, w: Float = 0.0f) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Float4) : this(v.x, v.y, v.z, v.w)
|
||||
constructor(q: Quaternion) : this(q.x, q.y, q.z, q.w)
|
||||
|
||||
@@ -52,84 +52,42 @@ data class Quaternion(
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around a specified order
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* Uses intrinsic Tait-Bryan angles. This means that rotations are performed with respect to
|
||||
* the local coordinate system.
|
||||
* That is, for order 'XYZ', the rotation is first around the X axis (which is the same as
|
||||
* the world-X axis), then around local-Y (which may now be different from the world
|
||||
* Y-axis), then local-Z (which may be different from the world Z-axis)
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param d Per axis Euler angles in degrees
|
||||
* Yaw, pitch, roll (YPR) are taken accordingly to the rotations order input.
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around
|
||||
* its Z axis, then its Y axis and finally its X axis.
|
||||
*/
|
||||
fun fromEuler(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Quaternion {
|
||||
fun fromEuler(d: Float3): Quaternion {
|
||||
val r = transform(d, ::radians)
|
||||
return fromEuler(r[order.yaw], r[order.pitch], r[order.roll], order)
|
||||
return fromEulerZYX(r.z, r.y, r.x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler yaw, pitch, roll around a specified order.
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* @param roll about 1st rotation axis in radians. Z in case of ZYX order
|
||||
* @param pitch about 2nd rotation axis in radians. Y in case of ZYX order
|
||||
* @param yaw about 3rd rotation axis in radians. X in case of ZYX order
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param roll about X axis in radians
|
||||
* @param pitch about Y axis in radians
|
||||
* @param yaw about Z axis in radians
|
||||
*/
|
||||
fun fromEuler(
|
||||
yaw: Float = 0.0f,
|
||||
pitch: Float = 0.0f,
|
||||
roll: Float = 0.0f,
|
||||
order: RotationsOrder = RotationsOrder.ZYX
|
||||
): Quaternion {
|
||||
val c1 = cos(yaw * 0.5f)
|
||||
val s1 = sin(yaw * 0.5f)
|
||||
val c2 = cos(pitch * 0.5f)
|
||||
val s2 = sin(pitch * 0.5f)
|
||||
val c3 = cos(roll * 0.5f)
|
||||
val s3 = sin(roll * 0.5f)
|
||||
return when (order) {
|
||||
RotationsOrder.XZY -> Quaternion(
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3)
|
||||
RotationsOrder.XYZ -> Quaternion(
|
||||
s1 * c2 * c3 + s2 * s3 * c1,
|
||||
s2 * c1 * c3 - s1 * s3 * c2,
|
||||
s1 * s2 * c3 + s3 * c1 * c2,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
RotationsOrder.YXZ -> Quaternion(
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3
|
||||
)
|
||||
RotationsOrder.YZX -> Quaternion(
|
||||
s1 * s2 * c3 + c1 * c2 * s3,
|
||||
s1 * c2 * c3 + c1 * s2 * s3,
|
||||
c1 * s2 * c3 - s1 * c2 * s3,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
RotationsOrder.ZYX -> Quaternion(
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3
|
||||
)
|
||||
RotationsOrder.ZXY -> Quaternion(
|
||||
c1 * s2 * c3 - s1 * c2 * s3,
|
||||
s1 * s2 * c3 + c1 * c2 * s3,
|
||||
s1 * c2 * c3 + c1 * s2 * s3,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
}
|
||||
fun fromEulerZYX(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f): Quaternion {
|
||||
val cy = cos(yaw * 0.5f)
|
||||
val sy = sin(yaw * 0.5f)
|
||||
val cp = cos(pitch * 0.5f)
|
||||
val sp = sin(pitch * 0.5f)
|
||||
val cr = cos(roll * 0.5f)
|
||||
val sr = sin(roll * 0.5f)
|
||||
|
||||
return Quaternion(
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
cr * cp * cy + sr * sp * sy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,44 +222,16 @@ data class Quaternion(
|
||||
inline operator fun minus(v: Float) = Quaternion(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Float) = Quaternion(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Float) = Quaternion(x / v, y / v, z / v, w / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = Bool4(
|
||||
x.equals(v, delta),
|
||||
y.equals(v, delta),
|
||||
z.equals(v, delta),
|
||||
w.equals(v, delta)
|
||||
)
|
||||
|
||||
inline operator fun times(v: Float3) = (this * Quaternion(v, 0.0f) * inverse(this)).xyz
|
||||
|
||||
inline operator fun plus(q: Quaternion) = Quaternion(x + q.x, y + q.y, z + q.z, w + q.w)
|
||||
inline operator fun minus(q: Quaternion) = Quaternion(x - q.x, y - q.y, z - q.z, w - q.w)
|
||||
inline operator fun times(q: Quaternion) = Quaternion(
|
||||
w * q.x + x * q.w + y * q.z - z * q.y,
|
||||
w * q.y - x * q.z + y * q.w + z * q.x,
|
||||
w * q.z + x * q.y - y * q.x + z * q.w,
|
||||
w * q.w - x * q.x - y * q.y - z * q.z
|
||||
)
|
||||
|
||||
inline fun compareTo(v: Float4, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta),
|
||||
w.compareTo(v.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float4, delta: Float = 0.0f) = Bool4(
|
||||
x.equals(v.x, delta),
|
||||
y.equals(v.y, delta),
|
||||
z.equals(v.z, delta),
|
||||
w.equals(v.w, delta)
|
||||
)
|
||||
w * q.x + x * q.w + y * q.z - z * q.y,
|
||||
w * q.y - x * q.z + y * q.w + z * q.x,
|
||||
w * q.z + x * q.y - y * q.x + z * q.w,
|
||||
w * q.w - x * q.x - y * q.y - z * q.z)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Quaternion {
|
||||
x = block(x)
|
||||
@@ -323,103 +253,6 @@ inline operator fun Float.minus(q: Quaternion) = Quaternion(this - q.x, this - q
|
||||
inline operator fun Float.times(q: Quaternion) = Quaternion(this * q.x, this * q.y, this * q.z, this * q.w)
|
||||
inline operator fun Float.div(q: Quaternion) = Quaternion(this / q.x, this / q.y, this / q.z, this / q.w)
|
||||
|
||||
inline fun lessThan(a: Quaternion, b: Float) = Bool4(
|
||||
a.x < b,
|
||||
a.y < b,
|
||||
a.z < b,
|
||||
a.w < b
|
||||
)
|
||||
|
||||
inline fun lessThan(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x < b.x,
|
||||
a.y < b.y,
|
||||
a.z < b.z,
|
||||
a.w < b.w
|
||||
)
|
||||
|
||||
inline fun lessThanEqual(a: Quaternion, b: Float) = Bool4(
|
||||
a.x <= b,
|
||||
a.y <= b,
|
||||
a.z <= b,
|
||||
a.w <= b
|
||||
)
|
||||
|
||||
inline fun lessThanEqual(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x <= b.x,
|
||||
a.y <= b.y,
|
||||
a.z <= b.z,
|
||||
a.w <= b.w
|
||||
)
|
||||
|
||||
inline fun greaterThan(a: Quaternion, b: Float) = Bool4(
|
||||
a.x > b,
|
||||
a.y > b,
|
||||
a.z > b,
|
||||
a.w > b
|
||||
)
|
||||
|
||||
inline fun greaterThan(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x > b.y,
|
||||
a.y > b.y,
|
||||
a.z > b.z,
|
||||
a.w > b.w
|
||||
)
|
||||
|
||||
inline fun greaterThanEqual(a: Quaternion, b: Float) = Bool4(
|
||||
a.x >= b,
|
||||
a.y >= b,
|
||||
a.z >= b,
|
||||
a.w >= b
|
||||
)
|
||||
|
||||
inline fun greaterThanEqual(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x >= b.x,
|
||||
a.y >= b.y,
|
||||
a.z >= b.z,
|
||||
a.w >= b.w
|
||||
)
|
||||
|
||||
inline fun equal(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline infix fun Quaternion.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
|
||||
inline infix fun Quaternion.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Quaternion.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Quaternion.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
inline infix fun Quaternion.gt(b: Float) = Bool4(x > b, y > b, z > b, w > b)
|
||||
inline infix fun Quaternion.gt(b: Float4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
|
||||
inline infix fun Quaternion.gte(b: Float) = Bool4(x >= b, y >= b, z >= b, w >= b)
|
||||
inline infix fun Quaternion.gte(b: Float4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
|
||||
inline infix fun Quaternion.eq(b: Float) = Bool4(x == b, y == b, z == b, w == b)
|
||||
inline infix fun Quaternion.eq(b: Float4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
|
||||
inline infix fun Quaternion.neq(b: Float) = Bool4(x != b, y != b, z != b, w != b)
|
||||
inline infix fun Quaternion.neq(b: Float4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.w)
|
||||
|
||||
inline fun abs(q: Quaternion) = Quaternion(abs(q.x), abs(q.y), abs(q.z), abs(q.w))
|
||||
inline fun length(q: Quaternion) = sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w)
|
||||
inline fun length2(q: Quaternion) = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w
|
||||
@@ -445,10 +278,6 @@ fun cross(a: Quaternion, b: Quaternion): Quaternion {
|
||||
return Quaternion(m.x, m.y, m.z, 0.0f)
|
||||
}
|
||||
|
||||
fun angle(a: Quaternion, b: Quaternion): Float {
|
||||
return 2.0f * acos(abs(clamp(dot(a, b), -1.0f, 1.0f)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Spherical linear interpolation between two given orientations
|
||||
*
|
||||
@@ -458,38 +287,36 @@ fun angle(a: Quaternion, b: Quaternion): Float {
|
||||
* @param a The beginning value
|
||||
* @param b The ending value
|
||||
* @param t The ratio between the two floats
|
||||
* @param dotThreshold If the quaternion dot product is greater than this value
|
||||
* (i.e. the quaternions are very close to each other), then the quaternions are
|
||||
* linearly interpolated instead of spherically interpolated.
|
||||
* @param valueEps Prevent blowing up when slerping between two quaternions that are very near each
|
||||
* other. Linear interpolation (lerp) is returned in this case.
|
||||
*
|
||||
* @return Interpolated value between the two floats
|
||||
*/
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, dotThreshold: Float = 0.9995f): Quaternion {
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, valueEps: Float = 0.0000000001f): Quaternion {
|
||||
// could also be computed as: pow(q * inverse(p), t) * p;
|
||||
var dot = dot(a, b)
|
||||
var b1 = b
|
||||
|
||||
// If the dot product is negative, then the interpolation won't follow the shortest angular path
|
||||
// between the two quaterions. In this case, invert the end quaternion to produce an equivalent
|
||||
// rotation that will give us the path we want.
|
||||
if (dot < 0.0f) {
|
||||
dot = -dot
|
||||
b1 = -b
|
||||
}
|
||||
|
||||
val d = dot(a, b)
|
||||
val absd = abs(d)
|
||||
// Prevent blowing up when slerping between two quaternions that are very near each other.
|
||||
return if (dot < dotThreshold) {
|
||||
val angle = acos(dot)
|
||||
val s = sin(angle)
|
||||
a * sin((1.0f - t) * angle) / s + b1 * sin(t * angle) / s
|
||||
} else {
|
||||
// If the angle is too small, use linear interpolation
|
||||
nlerp(a, b1, t)
|
||||
if ((1.0f - absd) < valueEps) {
|
||||
return normalize(lerp(if (d < 0.0f) -a else a, b, t))
|
||||
}
|
||||
val npq = sqrt(dot(a, a) * dot(b, b)) // ||p|| * ||q||
|
||||
val acos = acos(clamp(absd / npq, -1.0f, 1.0f))
|
||||
val acos0 = acos * (1.0f - t)
|
||||
val acos1 = acos * t
|
||||
val sina = sin(acos)
|
||||
if (sina < valueEps) {
|
||||
return normalize(lerp(a, b, t))
|
||||
}
|
||||
val isina = 1.0f / sina
|
||||
val s0 = sin(acos0) * isina
|
||||
val s1 = sin(acos1) * isina
|
||||
// ensure we're taking the "short" side
|
||||
return normalize(s0 * a + (if (d < 0.0f) -s1 else (s1)) * b)
|
||||
}
|
||||
|
||||
fun lerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
return ((1.0f - t) * a) + (t * b)
|
||||
return ((1 - t) * a) + (t * b)
|
||||
}
|
||||
|
||||
fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
@@ -497,12 +324,19 @@ fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Quaternion to Euler angles
|
||||
* Convert a Quaternion to Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
* The Euler angles are applied in ZYX order
|
||||
*/
|
||||
fun eulerAngles(q: Quaternion, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
|
||||
return eulerAngles(rotation(q), order)
|
||||
fun eulerAngles(q: Quaternion): Float3 {
|
||||
val nq = normalize(q)
|
||||
return Float3(
|
||||
// roll (x-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.y * nq.z + nq.w * nq.x),
|
||||
nq.w * nq.w - nq.x * nq.x - nq.y * nq.y + nq.z * nq.z)),
|
||||
// pitch (y-axis rotation)
|
||||
degrees(asin(-2.0f * (nq.x * nq.z - nq.w * nq.y))),
|
||||
// yaw (z-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.x * nq.y + nq.w * nq.z),
|
||||
nq.w * nq.w + nq.x * nq.x - nq.y * nq.y - nq.z * nq.z)))
|
||||
}
|
||||
|
||||
+1
-12
@@ -28,21 +28,12 @@ const val INV_PI = 1.0f / FPI
|
||||
const val INV_TWO_PI = INV_PI * 0.5f
|
||||
const val INV_FOUR_PI = INV_PI * 0.25f
|
||||
|
||||
val HALF_ONE = Half(0x3c00.toUShort())
|
||||
val HALF_TWO = Half(0x4000.toUShort())
|
||||
|
||||
inline fun clamp(x: Float, min: Float, max: Float) = if (x < min) min else (if (x > max) max else x)
|
||||
|
||||
inline fun clamp(x: Half, min: Half, max: Half) = if (x < min) min else (if (x > max) max else x)
|
||||
inline fun clamp(x: Float, min: Float, max: Float)= if (x < min) min else (if (x > max) max else x)
|
||||
|
||||
inline fun saturate(x: Float) = clamp(x, 0.0f, 1.0f)
|
||||
|
||||
inline fun saturate(x: Half) = clamp(x, Half.POSITIVE_ZERO, HALF_ONE)
|
||||
|
||||
inline fun mix(a: Float, b: Float, x: Float) = a * (1.0f - x) + b * x
|
||||
|
||||
inline fun mix(a: Half, b: Half, x: Half) = a * (HALF_ONE - x) + b * x
|
||||
|
||||
inline fun degrees(v: Float) = v * (180.0f * INV_PI)
|
||||
|
||||
inline fun radians(v: Float) = v * (FPI / 180.0f)
|
||||
@@ -51,6 +42,4 @@ inline fun fract(v: Float) = v % 1
|
||||
|
||||
inline fun sqr(v: Float) = v * v
|
||||
|
||||
inline fun sqr(v: Half) = v * v
|
||||
|
||||
inline fun pow(x: Float, y: Float) = (x.toDouble().pow(y.toDouble())).toFloat()
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils
|
||||
package com.google.android.filament.textured
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
|
||||
+15
-890
@@ -22,8 +22,6 @@ import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.math.acos
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
enum class VectorComponent {
|
||||
X, Y, Z, W,
|
||||
@@ -126,23 +124,11 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
inline operator fun minus(v: Float) = Float2(x - v, y - v)
|
||||
inline operator fun times(v: Float) = Float2(x * v, y * v)
|
||||
inline operator fun div(v: Float) = Float2(x / v, y / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float2(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float2(x + v.x, y + v.y)
|
||||
inline operator fun minus(v: Float2) = Float2(x - v.x, y - v.y)
|
||||
inline operator fun times(v: Float2) = Float2(x * v.x, y * v.y)
|
||||
inline operator fun div(v: Float2) = Float2(x / v.x, y / v.y)
|
||||
inline fun compareTo(v: Float2, delta: Float = 0.0f) = Float2(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float2, delta: Float = 0.0f) = x.equals(v.x, delta) && y.equals(v.y, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float2 {
|
||||
x = block(x)
|
||||
@@ -305,14 +291,6 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
inline operator fun minus(v: Float) = Float3(x - v, y - v, z - v)
|
||||
inline operator fun times(v: Float) = Float3(x * v, y * v, z * v)
|
||||
inline operator fun div(v: Float) = Float3(x / v, y / v, z / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float3(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float3(x + v.x, y + v.y, z)
|
||||
inline operator fun minus(v: Float2) = Float3(x - v.x, y - v.y, z)
|
||||
@@ -323,14 +301,6 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
inline operator fun minus(v: Float3) = Float3(x - v.x, y - v.y, z - v.z)
|
||||
inline operator fun times(v: Float3) = Float3(x * v.x, y * v.y, z * v.z)
|
||||
inline operator fun div(v: Float3) = Float3(x / v.x, y / v.y, z / v.z)
|
||||
inline fun compareTo(v: Float3, delta: Float = 0.0f) = Float3(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float3, delta: Float = 0.0f) =
|
||||
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float3 {
|
||||
x = block(x)
|
||||
@@ -564,15 +534,6 @@ data class Float4(
|
||||
inline operator fun minus(v: Float) = Float4(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Float) = Float4(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Float) = Float4(x / v, y / v, z / v, w / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float4(x + v.x, y + v.y, z, w)
|
||||
inline operator fun minus(v: Float2) = Float4(x - v.x, y - v.y, z, w)
|
||||
@@ -588,15 +549,6 @@ data class Float4(
|
||||
inline operator fun minus(v: Float4) = Float4(x - v.x, y - v.y, z - v.z, w - v.w)
|
||||
inline operator fun times(v: Float4) = Float4(x * v.x, y * v.y, z * v.z, w * v.w)
|
||||
inline operator fun div(v: Float4) = Float4(x / v.x, y / v.y, z / v.z, w / v.w)
|
||||
inline fun compareTo(v: Float4, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta),
|
||||
w.compareTo(v.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float4, delta: Float = 0.0f) =
|
||||
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta) && w.equals(v.w, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float4 {
|
||||
x = block(x)
|
||||
@@ -614,12 +566,6 @@ inline operator fun Float.minus(v: Float2) = Float2(this - v.x, this - v.y)
|
||||
inline operator fun Float.times(v: Float2) = Float2(this * v.x, this * v.y)
|
||||
inline operator fun Float.div(v: Float2) = Float2(this / v.x, this / v.y)
|
||||
|
||||
inline fun Float.compareTo(v: Float, delta: Float): Float = when {
|
||||
equals(v, delta) -> 0.0f
|
||||
else -> compareTo(v).toFloat()
|
||||
}
|
||||
|
||||
inline fun Float.equals(v: Float, delta: Float) = (this - v).absoluteValue < delta
|
||||
inline fun abs(v: Float2) = Float2(abs(v.x), abs(v.y))
|
||||
inline fun length(v: Float2) = sqrt(v.x * v.x + v.y * v.y)
|
||||
inline fun length2(v: Float2) = v.x * v.x + v.y * v.y
|
||||
@@ -637,11 +583,6 @@ fun refract(i: Float2, n: Float2, eta: Float): Float2 {
|
||||
return if (k < 0.0f) Float2(0.0f) else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun angle(a: Float2, b: Float2): Float {
|
||||
val l = length(a) * length(b)
|
||||
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float2, min: Float, max: Float): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min, max),
|
||||
@@ -685,25 +626,10 @@ inline fun greaterThan(a: Float2, b: Float) = Bool2(a.x > b, a.y > b)
|
||||
inline fun greaterThan(a: Float2, b: Float2) = Bool2(a.x > b.y, a.y > b.y)
|
||||
inline fun greaterThanEqual(a: Float2, b: Float) = Bool2(a.x >= b, a.y >= b)
|
||||
inline fun greaterThanEqual(a: Float2, b: Float2) = Bool2(a.x >= b.x, a.y >= b.y)
|
||||
inline fun equal(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta)
|
||||
)
|
||||
inline fun equal(a: Float2, b: Float) = Bool2(a.x == b, a.y == b)
|
||||
inline fun equal(a: Float2, b: Float2) = Bool2(a.x == b.x, a.y == b.y)
|
||||
inline fun notEqual(a: Float2, b: Float) = Bool2(a.x != b, a.y != b)
|
||||
inline fun notEqual(a: Float2, b: Float2) = Bool2(a.x != b.x, a.y != b.y)
|
||||
|
||||
inline infix fun Float2.lt(b: Float) = Bool2(x < b, y < b)
|
||||
inline infix fun Float2.lt(b: Float2) = Bool2(x < b.x, y < b.y)
|
||||
@@ -749,11 +675,6 @@ fun refract(i: Float3, n: Float3, eta: Float): Float3 {
|
||||
return if (k < 0.0f) Float3(0.0f) else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun angle(a: Float3, b: Float3): Float {
|
||||
val l = length(a) * length(b)
|
||||
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float3, min: Float, max: Float): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min, max),
|
||||
@@ -801,29 +722,10 @@ inline fun greaterThan(a: Float3, b: Float) = Bool3(a.x > b, a.y > b, a.z > b)
|
||||
inline fun greaterThan(a: Float3, b: Float3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
|
||||
inline fun greaterThanEqual(a: Float3, b: Float) = Bool3(a.x >= b, a.y >= b, a.z >= b)
|
||||
inline fun greaterThanEqual(a: Float3, b: Float3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
|
||||
inline fun equal(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta)
|
||||
)
|
||||
inline fun equal(a: Float3, b: Float) = Bool3(a.x == b, a.y == b, a.z == b)
|
||||
inline fun equal(a: Float3, b: Float3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
|
||||
inline fun notEqual(a: Float3, b: Float) = Bool3(a.x != b, a.y != b, a.z != b)
|
||||
inline fun notEqual(a: Float3, b: Float3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
|
||||
|
||||
inline infix fun Float3.lt(b: Float) = Bool3(x < b, y < b, z < b)
|
||||
inline infix fun Float3.lt(b: Float3) = Bool3(x < b.x, y < b.y, z < b.z)
|
||||
@@ -905,44 +807,17 @@ inline fun transform(v: Float4, block: (Float) -> Float) = v.copy().transform(bl
|
||||
inline fun lessThan(a: Float4, b: Float) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
|
||||
inline fun lessThan(a: Float4, b: Float4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
|
||||
inline fun lessThanEqual(a: Float4, b: Float) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
|
||||
inline fun lessThanEqual(a: Float4, b: Float4) =
|
||||
Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
|
||||
inline fun lessThanEqual(a: Float4, b: Float4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
inline fun greaterThan(a: Float4, b: Float) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
|
||||
inline fun greaterThan(a: Float4, b: Float4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float4) =
|
||||
Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
inline fun equal(a: Float4, b: Float) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
|
||||
inline fun equal(a: Float4, b: Float4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
|
||||
inline fun notEqual(a: Float4, b: Float) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
|
||||
inline fun notEqual(a: Float4, b: Float4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
|
||||
|
||||
inline fun equal(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
|
||||
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, a < b)
|
||||
inline infix fun Float4.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Float4.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Float4.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
@@ -1402,753 +1277,3 @@ data class Bool4(
|
||||
set(index4, v)
|
||||
}
|
||||
}
|
||||
|
||||
data class Half2(var x: Half = Half.POSITIVE_ZERO, var y: Half = Half.POSITIVE_ZERO) {
|
||||
constructor(v: Half) : this(v, v)
|
||||
constructor(v: Half2) : this(v.x, v.y)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
else -> throw IllegalArgumentException("index must be in 0..1")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..1")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half2(-x, -y)
|
||||
operator fun inc() = Half2(x++, y++)
|
||||
operator fun dec() = Half2(x--, y--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half2(x + v, y + v)
|
||||
inline operator fun minus(v: Half) = Half2(x - v, y - v)
|
||||
inline operator fun times(v: Half) = Half2(x * v, y * v)
|
||||
inline operator fun div(v: Half) = Half2(x / v, y / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half2(x + v.x, y + v.y)
|
||||
inline operator fun minus(v: Half2) = Half2(x - v.x, y - v.y)
|
||||
inline operator fun times(v: Half2) = Half2(x * v.x, y * v.y)
|
||||
inline operator fun div(v: Half2) = Half2(x / v.x, y / v.y)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half2 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat())
|
||||
}
|
||||
|
||||
data class Half3(
|
||||
var x: Half = Half.POSITIVE_ZERO,
|
||||
var y: Half = Half.POSITIVE_ZERO,
|
||||
var z: Half = Half.POSITIVE_ZERO
|
||||
) {
|
||||
constructor(v: Half) : this(v, v, v)
|
||||
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z)
|
||||
constructor(v: Half3) : this(v.x, v.y, v.z)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var b: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var p: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
inline var rgb: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var xyz: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var stp: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
|
||||
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
else -> throw IllegalArgumentException("index must be in 0..2")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
2 -> z = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..2")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
|
||||
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half3(-x, -y, -z)
|
||||
operator fun inc() = Half3(x++, y++, z++)
|
||||
operator fun dec() = Half3(x--, y--, z--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half3(x + v, y + v, z + v)
|
||||
inline operator fun minus(v: Half) = Half3(x - v, y - v, z - v)
|
||||
inline operator fun times(v: Half) = Half3(x * v, y * v, z * v)
|
||||
inline operator fun div(v: Half) = Half3(x / v, y / v, z / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half3(x + v.x, y + v.y, z)
|
||||
inline operator fun minus(v: Half2) = Half3(x - v.x, y - v.y, z)
|
||||
inline operator fun times(v: Half2) = Half3(x * v.x, y * v.y, z)
|
||||
inline operator fun div(v: Half2) = Half3(x / v.x, y / v.y, z)
|
||||
|
||||
inline operator fun plus(v: Half3) = Half3(x + v.x, y + v.y, z + v.z)
|
||||
inline operator fun minus(v: Half3) = Half3(x - v.x, y - v.y, z - v.z)
|
||||
inline operator fun times(v: Half3) = Half3(x * v.x, y * v.y, z * v.z)
|
||||
inline operator fun div(v: Half3) = Half3(x / v.x, y / v.y, z / v.z)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half3 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat())
|
||||
}
|
||||
|
||||
data class Half4(
|
||||
var x: Half = Half.POSITIVE_ZERO,
|
||||
var y: Half = Half.POSITIVE_ZERO,
|
||||
var z: Half = Half.POSITIVE_ZERO,
|
||||
var w: Half = Half.POSITIVE_ZERO
|
||||
) {
|
||||
constructor(v: Half) : this(v, v, v, v)
|
||||
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z, w)
|
||||
constructor(v: Half3, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Half4) : this(v.x, v.y, v.z, v.w)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var b: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
inline var a: Half
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var p: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
inline var q: Half
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
inline var rgb: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var xyz: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var stp: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var rgba: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
inline var xyzw: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
inline var stpq: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
|
||||
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
index4: VectorComponent): Half4 {
|
||||
return Half4(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
3 -> w
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
operator fun get(index1: Int, index2: Int, index3: Int, index4: Int): Half4 {
|
||||
return Half4(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
2 -> z = v
|
||||
3 -> w = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, index4: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
|
||||
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w = v
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half4(-x, -y, -z, -w)
|
||||
operator fun inc() = Half4(x++, y++, z++, w++)
|
||||
operator fun dec() = Half4(x--, y--, z--, w--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half4(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Half) = Half4(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Half) = Half4(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Half) = Half4(x / v, y / v, z / v, w / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half4(x + v.x, y + v.y, z, w)
|
||||
inline operator fun minus(v: Half2) = Half4(x - v.x, y - v.y, z, w)
|
||||
inline operator fun times(v: Half2) = Half4(x * v.x, y * v.y, z, w)
|
||||
inline operator fun div(v: Half2) = Half4(x / v.x, y / v.y, z, w)
|
||||
|
||||
inline operator fun plus(v: Half3) = Half4(x + v.x, y + v.y, z + v.z, w)
|
||||
inline operator fun minus(v: Half3) = Half4(x - v.x, y - v.y, z - v.z, w)
|
||||
inline operator fun times(v: Half3) = Half4(x * v.x, y * v.y, z * v.z, w)
|
||||
inline operator fun div(v: Half3) = Half4(x / v.x, y / v.y, z / v.z, w)
|
||||
|
||||
inline operator fun plus(v: Half4) = Half4(x + v.x, y + v.y, z + v.z, w + v.w)
|
||||
inline operator fun minus(v: Half4) = Half4(x - v.x, y - v.y, z - v.z, w - v.w)
|
||||
inline operator fun times(v: Half4) = Half4(x * v.x, y * v.y, z * v.z, w * v.w)
|
||||
inline operator fun div(v: Half4) = Half4(x / v.x, y / v.y, z / v.z, w / v.w)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half4 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat())
|
||||
}
|
||||
|
||||
inline fun min(v: Half2) = min(v.x, v.y)
|
||||
inline fun min(a: Half2, b: Half2) = Half2(min(a.x, b.x), min(a.y, b.y))
|
||||
inline fun max(v: Half2) = max(v.x, v.y)
|
||||
inline fun max(a: Half2, b: Half2) = Half2(max(a.x, b.x), max(a.y, b.y))
|
||||
|
||||
inline fun transform(v: Half2, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half2, b: Half) = Bool2(a.x < b, a.y < b)
|
||||
inline fun lessThan(a: Half2, b: Half2) = Bool2(a.x < b.x, a.y < b.y)
|
||||
inline fun lessThanEqual(a: Half2, b: Half) = Bool2(a.x <= b, a.y <= b)
|
||||
inline fun lessThanEqual(a: Half2, b: Half2) = Bool2(a.x <= b.x, a.y <= b.y)
|
||||
inline fun greaterThan(a: Half2, b: Half) = Bool2(a.x > b, a.y > b)
|
||||
inline fun greaterThan(a: Half2, b: Half2) = Bool2(a.x > b.y, a.y > b.y)
|
||||
inline fun greaterThanEqual(a: Half2, b: Half) = Bool2(a.x >= b, a.y >= b)
|
||||
inline fun greaterThanEqual(a: Half2, b: Half2) = Bool2(a.x >= b.x, a.y >= b.y)
|
||||
inline fun equal(a: Half2, b: Half) = Bool2(a.x == b, a.y == b)
|
||||
inline fun equal(a: Half2, b: Half2) = Bool2(a.x == b.x, a.y == b.y)
|
||||
inline fun notEqual(a: Half2, b: Half) = Bool2(a.x != b, a.y != b)
|
||||
inline fun notEqual(a: Half2, b: Half2) = Bool2(a.x != b.x, a.y != b.y)
|
||||
|
||||
inline infix fun Half2.lt(b: Half) = Bool2(x < b, y < b)
|
||||
inline infix fun Half2.lt(b: Half2) = Bool2(x < b.x, y < b.y)
|
||||
inline infix fun Half2.lte(b: Half) = Bool2(x <= b, y <= b)
|
||||
inline infix fun Half2.lte(b: Half2) = Bool2(x <= b.x, y <= b.y)
|
||||
inline infix fun Half2.gt(b: Half) = Bool2(x > b, y > b)
|
||||
inline infix fun Half2.gt(b: Half2) = Bool2(x > b.x, y > b.y)
|
||||
inline infix fun Half2.gte(b: Half) = Bool2(x >= b, y >= b)
|
||||
inline infix fun Half2.gte(b: Half2) = Bool2(x >= b.x, y >= b.y)
|
||||
inline infix fun Half2.eq(b: Half) = Bool2(x == b, y == b)
|
||||
inline infix fun Half2.eq(b: Half2) = Bool2(x == b.x, y == b.y)
|
||||
inline infix fun Half2.neq(b: Half) = Bool2(x != b, y != b)
|
||||
inline infix fun Half2.neq(b: Half2) = Bool2(x != b.x, y != b.y)
|
||||
|
||||
inline operator fun Half.plus(v: Half3) = Half3(this + v.x, this + v.y, this + v.z)
|
||||
inline operator fun Half.minus(v: Half3) = Half3(this - v.x, this - v.y, this - v.z)
|
||||
inline operator fun Half.times(v: Half3) = Half3(this * v.x, this * v.y, this * v.z)
|
||||
inline operator fun Half.div(v: Half3) = Half3(this / v.x, this / v.y, this / v.z)
|
||||
|
||||
inline fun abs(v: Half3) = Half3(abs(v.x), abs(v.y), abs(v.z))
|
||||
inline fun length(v: Half3) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
|
||||
inline fun length2(v: Half3) = v.x * v.x + v.y * v.y + v.z * v.z
|
||||
inline fun distance(a: Half3, b: Half3) = length(a - b)
|
||||
inline fun dot(a: Half3, b: Half3) = a.x * b.x + a.y * b.y + a.z * b.z
|
||||
inline fun cross(a: Half3, b: Half3): Half3 {
|
||||
return Half3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x)
|
||||
}
|
||||
inline infix fun Half3.x(v: Half3): Half3 {
|
||||
return Half3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x)
|
||||
}
|
||||
fun normalize(v: Half3): Half3 {
|
||||
val l = HALF_ONE / length(v)
|
||||
return Half3(v.x * l, v.y * l, v.z * l)
|
||||
}
|
||||
|
||||
inline fun reflect(i: Half3, n: Half3) = i - HALF_TWO * dot(n, i) * n
|
||||
fun refract(i: Half3, n: Half3, eta: Half): Half3 {
|
||||
val d = dot(n, i)
|
||||
val k = HALF_ONE - eta * eta * (HALF_ONE - sqr(d))
|
||||
return if (k < Half.POSITIVE_ZERO) Half3() else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half3, min: Half, max: Half): Half3 {
|
||||
return Half3(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half3, min: Half3, max: Half3): Half3 {
|
||||
return Half3(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half3, b: Half3, x: Half): Half3 {
|
||||
return Half3(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half3, b: Half3, x: Half3): Half3 {
|
||||
return Half3(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Half3) = min(v.x, min(v.y, v.z))
|
||||
inline fun min(a: Half3, b: Half3) = Half3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z))
|
||||
inline fun max(v: Half3) = max(v.x, max(v.y, v.z))
|
||||
inline fun max(a: Half3, b: Half3) = Half3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z))
|
||||
|
||||
inline fun transform(v: Half3, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half3, b: Half) = Bool3(a.x < b, a.y < b, a.z < b)
|
||||
inline fun lessThan(a: Half3, b: Half3) = Bool3(a.x < b.x, a.y < b.y, a.z < b.z)
|
||||
inline fun lessThanEqual(a: Half3, b: Half) = Bool3(a.x <= b, a.y <= b, a.z <= b)
|
||||
inline fun lessThanEqual(a: Half3, b: Half3) = Bool3(a.x <= b.x, a.y <= b.y, a.z <= b.z)
|
||||
inline fun greaterThan(a: Half3, b: Half) = Bool3(a.x > b, a.y > b, a.z > b)
|
||||
inline fun greaterThan(a: Half3, b: Half3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
|
||||
inline fun greaterThanEqual(a: Half3, b: Half) = Bool3(a.x >= b, a.y >= b, a.z >= b)
|
||||
inline fun greaterThanEqual(a: Half3, b: Half3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
|
||||
inline fun equal(a: Half3, b: Half) = Bool3(a.x == b, a.y == b, a.z == b)
|
||||
inline fun equal(a: Half3, b: Half3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
|
||||
inline fun notEqual(a: Half3, b: Half) = Bool3(a.x != b, a.y != b, a.z != b)
|
||||
inline fun notEqual(a: Half3, b: Half3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
|
||||
|
||||
inline infix fun Half3.lt(b: Half) = Bool3(x < b, y < b, z < b)
|
||||
inline infix fun Half3.lt(b: Half3) = Bool3(x < b.x, y < b.y, z < b.z)
|
||||
inline infix fun Half3.lte(b: Half) = Bool3(x <= b, y <= b, z <= b)
|
||||
inline infix fun Half3.lte(b: Half3) = Bool3(x <= b.x, y <= b.y, z <= b.z)
|
||||
inline infix fun Half3.gt(b: Half) = Bool3(x > b, y > b, z > b)
|
||||
inline infix fun Half3.gt(b: Half3) = Bool3(x > b.x, y > b.y, z > b.z)
|
||||
inline infix fun Half3.gte(b: Half) = Bool3(x >= b, y >= b, z >= b)
|
||||
inline infix fun Half3.gte(b: Half3) = Bool3(x >= b.x, y >= b.y, z >= b.z)
|
||||
inline infix fun Half3.eq(b: Half) = Bool3(x == b, y == b, z == b)
|
||||
inline infix fun Half3.eq(b: Half3) = Bool3(x == b.x, y == b.y, z == b.z)
|
||||
inline infix fun Half3.neq(b: Half) = Bool3(x != b, y != b, z != b)
|
||||
inline infix fun Half3.neq(b: Half3) = Bool3(x != b.x, y != b.y, z != b.z)
|
||||
|
||||
inline operator fun Half.plus(v: Half4) = Half4(this + v.x, this + v.y, this + v.z, this + v.w)
|
||||
inline operator fun Half.minus(v: Half4) = Half4(this - v.x, this - v.y, this - v.z, this - v.w)
|
||||
inline operator fun Half.times(v: Half4) = Half4(this * v.x, this * v.y, this * v.z, this * v.w)
|
||||
inline operator fun Half.div(v: Half4) = Half4(this / v.x, this / v.y, this / v.z, this / v.w)
|
||||
|
||||
inline fun abs(v: Half4) = Half4(abs(v.x), abs(v.y), abs(v.z), abs(v.w))
|
||||
inline fun length(v: Half4) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w)
|
||||
inline fun length2(v: Half4) = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w
|
||||
inline fun distance(a: Half4, b: Half4) = length(a - b)
|
||||
inline fun dot(a: Half4, b: Half4) = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
|
||||
fun normalize(v: Half4): Half4 {
|
||||
val l = HALF_ONE / length(v)
|
||||
return Half4(v.x * l, v.y * l, v.z * l, v.w * l)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half4, min: Half, max: Half): Half4 {
|
||||
return Half4(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max),
|
||||
clamp(v.w, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half4, min: Half4, max: Half4): Half4 {
|
||||
return Half4(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z),
|
||||
clamp(v.w, min.z, max.w)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half4, b: Half4, x: Half): Half4 {
|
||||
return Half4(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x),
|
||||
mix(a.w, b.w, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half4, b: Half4, x: Half4): Half4 {
|
||||
return Half4(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z),
|
||||
mix(a.w, b.w, x.w))
|
||||
}
|
||||
|
||||
inline fun min(v: Half4) = min(v.x, min(v.y, min(v.z, v.w)))
|
||||
inline fun min(a: Half4, b: Half4): Half4 {
|
||||
return Half4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w))
|
||||
}
|
||||
inline fun max(v: Half4) = max(v.x, max(v.y, max(v.z, v.w)))
|
||||
inline fun max(a: Half4, b: Half4): Half4 {
|
||||
return Half4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w))
|
||||
}
|
||||
|
||||
inline fun transform(v: Half4, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half4, b: Half) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
|
||||
inline fun lessThan(a: Half4, b: Half4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
|
||||
inline fun lessThanEqual(a: Half4, b: Half) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
|
||||
inline fun lessThanEqual(a: Half4, b: Half4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
inline fun greaterThan(a: Half4, b: Half) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
|
||||
inline fun greaterThan(a: Half4, b: Half4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
|
||||
inline fun greaterThanEqual(a: Half4, b: Half) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
|
||||
inline fun greaterThanEqual(a: Half4, b: Half4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
inline fun equal(a: Half4, b: Half) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
|
||||
inline fun equal(a: Half4, b: Half4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
|
||||
inline fun notEqual(a: Half4, b: Half) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
|
||||
inline fun notEqual(a: Half4, b: Half4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
|
||||
|
||||
inline infix fun Half4.lt(b: Half) = Bool4(x < b, y < b, z < b, a < b)
|
||||
inline infix fun Half4.lt(b: Half4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Half4.lte(b: Half) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Half4.lte(b: Half4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
inline infix fun Half4.gt(b: Half) = Bool4(x > b, y > b, z > b, w > b)
|
||||
inline infix fun Half4.gt(b: Half4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
|
||||
inline infix fun Half4.gte(b: Half) = Bool4(x >= b, y >= b, z >= b, w >= b)
|
||||
inline infix fun Half4.gte(b: Half4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
|
||||
inline infix fun Half4.eq(b: Half) = Bool4(x == b, y == b, z == b, w == b)
|
||||
inline infix fun Half4.eq(b: Half4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
|
||||
inline infix fun Half4.neq(b: Half) = Bool4(x != b, y != b, z != b, w != b)
|
||||
inline infix fun Half4.neq(b: Half4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.w)
|
||||
|
||||
@@ -16,13 +16,6 @@ android {
|
||||
excludes += ['lib/*/libfilament-jni.so']
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
singleVariant("fullRelease") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.36.0
|
||||
VERSION_NAME=1.32.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
@@ -18,9 +18,6 @@ POM_DEVELOPER_NAME=Filament Team
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
android.useAndroidX=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
com.google.android.filament.tools-dir=../../../out/release/filament
|
||||
com.google.android.filament.dist-dir=../out/android-release/filament
|
||||
|
||||
@@ -86,10 +86,63 @@ afterEvaluate { project ->
|
||||
}
|
||||
}
|
||||
|
||||
if (project.getPlugins().hasPlugin('com.android.application') ||
|
||||
project.getPlugins().hasPlugin('com.android.library')) {
|
||||
|
||||
task androidJavadocs(type: Javadoc) {
|
||||
source = android.sourceSets.main.java.source
|
||||
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||
excludes = ['**/*.kt']
|
||||
}
|
||||
|
||||
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
|
||||
classifier = 'javadoc'
|
||||
from androidJavadocs.destinationDir
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addBooleanOption('html5', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
if (project.getPlugins().hasPlugin('com.android.application') ||
|
||||
project.getPlugins().hasPlugin('com.android.library')) {
|
||||
archives androidSourcesJar
|
||||
archives androidJavadocsJar
|
||||
}
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
tasks.androidJavadocs.doFirst {
|
||||
classpath += files(variant.javaCompileProvider.get().classpath.files.join(File.pathSeparator))
|
||||
}
|
||||
}
|
||||
|
||||
publishing.publications.all { publication ->
|
||||
publication.groupId = GROUP
|
||||
publication.version = VERSION_NAME
|
||||
|
||||
publication.artifact androidSourcesJar
|
||||
publication.artifact androidJavadocsJar
|
||||
|
||||
configurePom(publication.pom)
|
||||
}
|
||||
|
||||
|
||||
+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-8.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -40,11 +40,6 @@ android {
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -40,11 +36,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -30,7 +30,6 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -402,8 +401,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -40,11 +36,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
+4
-26
@@ -29,7 +29,6 @@ import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
@@ -120,13 +119,8 @@ class MainActivity : Activity() {
|
||||
private fun setupView() {
|
||||
scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine)
|
||||
|
||||
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
|
||||
// post-processing is not supported at feature level 0
|
||||
view.isPostProcessingEnabled = false
|
||||
} else {
|
||||
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
|
||||
// view.isPostProcessingEnabled = false
|
||||
}
|
||||
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
|
||||
// view.isPostProcessingEnabled = false
|
||||
|
||||
// Tell the view which camera we want to use
|
||||
view.camera = camera
|
||||
@@ -160,11 +154,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
private fun loadMaterial() {
|
||||
var name = "materials/baked_color.filamat"
|
||||
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
|
||||
name = "materials/baked_color_es2.filamat"
|
||||
}
|
||||
readUncompressedAsset(name).let {
|
||||
readUncompressedAsset("materials/baked_color.filamat").let {
|
||||
material = Material.Builder().payload(it, it.remaining()).build(engine)
|
||||
}
|
||||
}
|
||||
@@ -314,17 +304,7 @@ class MainActivity : Activity() {
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
|
||||
// at feature level 0, we don't have post-processing, so we need to set
|
||||
// the colorspace to sRGB (FIXME: it's not supported everywhere!)
|
||||
var flags = uiHelper.swapChainFlags
|
||||
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
|
||||
if (SwapChain.isSRGBSwapChainSupported(engine)) {
|
||||
flags = flags or SwapChain.CONFIG_SRGB_COLORSPACE
|
||||
}
|
||||
}
|
||||
|
||||
swapChain = engine.createSwapChain(surface, flags)
|
||||
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
|
||||
displayHelper.attach(renderer, surfaceView.display);
|
||||
}
|
||||
|
||||
@@ -347,8 +327,6 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ material {
|
||||
],
|
||||
|
||||
// This material disables all lighting
|
||||
shadingModel : unlit
|
||||
shadingModel : unlit,
|
||||
}
|
||||
|
||||
fragment {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Simple unlit material that uses the colors associated with each vertex.
|
||||
//
|
||||
// This source material must be compiled to a binary material using the matc tool.
|
||||
// The command used to compile this material is:
|
||||
// matc -p mobile -a opengl -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
|
||||
//
|
||||
// See build.gradle for an example of how to compile materials automatically
|
||||
// Please refer to the documentation for more information about matc and the materials system.
|
||||
|
||||
material {
|
||||
name : baked_color,
|
||||
|
||||
// Lists the required vertex attributes
|
||||
// Here we only need a color (RGBA)
|
||||
requires : [
|
||||
color
|
||||
],
|
||||
|
||||
// This material disables all lighting
|
||||
shadingModel : unlit,
|
||||
featureLevel : 0
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
// You must always call the prepareMaterial() function
|
||||
prepareMaterial(material);
|
||||
|
||||
// We set the material's color to the color interpolated from
|
||||
// the model's vertices
|
||||
material.baseColor = getColor();
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -46,11 +42,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -304,8 +303,6 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -39,11 +35,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -29,7 +29,6 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -414,8 +413,6 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@ apply plugin: 'kotlin-android'
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.livewallpaper'
|
||||
|
||||
@@ -22,11 +18,6 @@ android {
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -31,7 +31,6 @@ import android.view.animation.LinearInterpolator
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
class FilamentLiveWallpaper : WallpaperService() {
|
||||
@@ -227,8 +226,6 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
|
||||
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
|
||||
@@ -50,11 +46,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import com.google.android.filament.filamat.MaterialBuilder
|
||||
|
||||
@@ -344,8 +343,6 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -39,11 +35,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -30,7 +30,6 @@ 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.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -459,8 +458,6 @@ class MainActivity : Activity() {
|
||||
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
|
||||
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
|
||||
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/studio_small_02_2k.hdr")
|
||||
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
||||
@@ -42,11 +38,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -37,7 +37,6 @@ import com.google.android.filament.Camera;
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Entity;
|
||||
import com.google.android.filament.EntityManager;
|
||||
import com.google.android.filament.Fence;
|
||||
import com.google.android.filament.Filament;
|
||||
import com.google.android.filament.IndirectLight;
|
||||
import com.google.android.filament.LightManager;
|
||||
@@ -50,7 +49,6 @@ import com.google.android.filament.TransformManager;
|
||||
import com.google.android.filament.Viewport;
|
||||
|
||||
import com.google.android.filament.android.DisplayHelper;
|
||||
import com.google.android.filament.android.FilamentHelper;
|
||||
import com.google.android.filament.android.TextureHelper;
|
||||
import com.google.android.filament.android.UiHelper;
|
||||
|
||||
@@ -109,7 +107,6 @@ public class MainActivity extends Activity
|
||||
mCamera.setProjection(60.0, aspect, 1.0, 2000.0, Camera.Fov.HORIZONTAL);
|
||||
}
|
||||
mView.setViewport(new Viewport(0, 0, width, height));
|
||||
FilamentHelper.synchronizePendingFrames(mEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -40,11 +36,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -38,7 +38,6 @@ import android.os.Build
|
||||
import android.view.MotionEvent
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
|
||||
|
||||
class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
@@ -402,8 +401,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -40,11 +36,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -29,7 +29,6 @@ import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
@@ -328,8 +327,6 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -47,11 +43,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.utils.*
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
@@ -324,8 +323,6 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -40,11 +36,6 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
-3
@@ -33,7 +33,6 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -351,8 +350,6 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -491,7 +491,6 @@ function build_android {
|
||||
./gradlew \
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${MATOPT_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleDebug
|
||||
done
|
||||
fi
|
||||
@@ -540,7 +539,6 @@ function build_android {
|
||||
./gradlew \
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${MATOPT_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleRelease
|
||||
done
|
||||
fi
|
||||
@@ -758,7 +756,7 @@ function run_tests {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacCfgijmp:q:uvslwtedk:b" opt; do
|
||||
while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
|
||||
@@ -44,14 +44,6 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
|
||||
fi
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
if [[ "$java_version" < 17 ]]; then
|
||||
echo "Android builds require Java 17, found version ${java_version} instead"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Unless explicitly specified, NDK version will be set to match exactly the required one
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
|
||||
|
||||
|
||||
@@ -3,4 +3,12 @@
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
|
||||
CONTINUOUS_INTEGRATION=true
|
||||
|
||||
# Force Java to be Java 11 minimum, it defaults to 8 in GitHub runners for some platforms
|
||||
export JAVA_HOME=${JAVA_HOME_11_X64}
|
||||
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
if [[ "$java_version" < 11 ]]; then
|
||||
echo "Android builds require Java 11, found version ${java_version} instead"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
+6
-6
File diff suppressed because one or more lines are too long
@@ -200,7 +200,7 @@ Energy conservation is one of the key components of a good BRDF for physically b
|
||||
|
||||
## Specular BRDF
|
||||
|
||||
For the specular term, $f_r$ is a mirror BRDF that can be modeled with the Fresnel law, noted $F$ in the Cook-Torrance approximation of the microfacet model integration:
|
||||
For the specular term, $f_m$ is a mirror BRDF that can be modeled with the Fresnel law, noted $F$ in the Cook-Torrance approximation of the microfacet model integration:
|
||||
|
||||
$$\begin{equation}
|
||||
f_r(v,l) = \frac{D(h, \alpha) G(v, l, \alpha) F(v, h, f0)}{4(\NoV)(\NoL)}
|
||||
@@ -485,7 +485,7 @@ void BRDF(...) {
|
||||
// perceptually linear roughness to roughness (see parameterization)
|
||||
float roughness = perceptualRoughness * perceptualRoughness;
|
||||
|
||||
float D = D_GGX(NoH, roughness);
|
||||
float D = D_GGX(NoH, a);
|
||||
vec3 F = F_Schlick(LoH, f0);
|
||||
float V = V_SmithGGXCorrelated(NoV, NoL, roughness);
|
||||
|
||||
@@ -2016,7 +2016,7 @@ I(f(n, v, \alpha)) \equiv \frac{1}{N}\sum_{\forall \, i \in image} f(l_i,
|
||||
\end{equation}$$
|
||||
|
||||
However, in practice we're using _importance sampling_ which needs to take the $pdf$ of the distribution
|
||||
into account and adds a term $\frac{4\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
|
||||
into account and adds a term $\frac{\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
|
||||
See Importance Sampling For The IBL section:
|
||||
|
||||
$$\begin{equation}\label{iblImportanceSampling}
|
||||
@@ -3486,15 +3486,15 @@ The _important direction samples_ $l_i$ are calculated as the reflection of $v$
|
||||
**do not** have the same PDF as $h_i$. The PDF of a transformed distribution is given by:
|
||||
|
||||
$$\begin{equation}
|
||||
p(T_r(x)) = p(x) |J(T_r)|^{-1}
|
||||
p(T_r(x)) = p(x) |J(T_r)|
|
||||
\end{equation}$$
|
||||
|
||||
Where $|J(T_r)|$ is the determinant of the Jacobian of the transform. In our case we're considering
|
||||
the transform from $h_i$ to $l_i$ and the determinant of its Jacobian is given in \ref{iblPDF}.
|
||||
|
||||
$$\begin{equation}\label{iblPDF}
|
||||
p(l,v,\Theta) = D(h,\alpha) \left< \NoH \right> |J_{h \rightarrow l}|^{-1} \\
|
||||
|J_{h \rightarrow l}| = 4 \left< \VoH \right>
|
||||
p(l,v,\Theta) = D(h,\alpha) \left< \NoH \right> |J_{h \rightarrow l}| \\
|
||||
|J_{h \rightarrow l}| = \frac{1}{4 \left< \VoH \right>}
|
||||
\end{equation}$$
|
||||
|
||||
### Choosing important directions
|
||||
|
||||
+77
-169
File diff suppressed because one or more lines are too long
+1
-67
@@ -1076,63 +1076,6 @@ fragment {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: constants
|
||||
|
||||
Type
|
||||
: array of constant objects
|
||||
|
||||
Value
|
||||
: Each entry is an object with the properties `name` and `type`, both of `string` type. The name
|
||||
must be a valid GLSL identifier. Entries also have an optional `default`, which can either be a
|
||||
`bool` or `number`, depending on the `type` of the constant. The type must be one of the types
|
||||
described in table [materialConstantsTypes].
|
||||
|
||||
Type | Description | Default
|
||||
:----------------------|:-----------------------------------------|:------------------
|
||||
int | A signed, 32 bit GLSL int | 0
|
||||
float | A single-precision GLSL float | 0.0
|
||||
bool | A GLSL bool | false
|
||||
[Table [materialConstantsTypes]: Material constants types]
|
||||
|
||||
Description
|
||||
: Lists the constant parameters accepted by your material. These constants can be set, or
|
||||
"specialized", at runtime when loading a material package. Multiple materials can be loaded from
|
||||
the same material package with differing constant parameter specializations. Once a material is
|
||||
loaded from a material package, its constant parameters cannot be changed. Compared to regular
|
||||
parameters, constant parameters allow the compiler to generate more efficient code. Access
|
||||
constant parameters from the shader by prefixing the name with `materialConstant_`. For example,
|
||||
a constant parameter named `myConstant` is accessed in the shader as
|
||||
`materialConstant_myConstant`. If a constant parameter is not set at runtime, the default is
|
||||
used.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
constants : [
|
||||
{
|
||||
name : overrideAlpha,
|
||||
type : bool
|
||||
},
|
||||
{
|
||||
name : customAlpha,
|
||||
type : float,
|
||||
default : 0.5
|
||||
}
|
||||
],
|
||||
shadingModel : lit,
|
||||
blending : transparent,
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
if (materialConstants_overrideAlpha) {
|
||||
material.baseColor.a = materialConstants_customAlpha;
|
||||
material.baseColor.rgb *= material.baseColor.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: variantFilter
|
||||
|
||||
Type
|
||||
@@ -2363,7 +2306,7 @@ type aliases:
|
||||
**getUserWorldFromWorldMatrix()** | float4x4 | Matrix that converts from world space to API-level (user) world space.
|
||||
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
|
||||
**getUserTime()** | float4 | Current time in seconds: `time`, `(double)time - time`, `0`, `0`
|
||||
**getUserTimeMod(float m)** | float | Current time modulo m in seconds
|
||||
**getUserTimeMode(float m)** | float | Current time modulo m in seconds
|
||||
**getExposure()** | float | Photometric exposure of the camera
|
||||
**getEV100()** | float | [Exposure value at ISO 100](https://en.wikipedia.org/wiki/Exposure_value) of the camera
|
||||
|
||||
@@ -2372,15 +2315,6 @@ type aliases:
|
||||
match the API-level world space. To obtain the position of the API-level camera, custom
|
||||
materials can use `getUserWorldFromWorldMatrix()` to transform `getWorldCameraPosition()`.
|
||||
|
||||
### Material globals
|
||||
|
||||
Name | Type | Description
|
||||
:-----------------------------------|:--------:|:------------------------------------
|
||||
**getMaterialGlobal0()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(0, float4)`. Its default value is {0,0,0,1}.
|
||||
**getMaterialGlobal1()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(1, float4)`. Its default value is {0,0,0,1}.
|
||||
**getMaterialGlobal2()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(2, float4)`. Its default value is {0,0,0,1}.
|
||||
**getMaterialGlobal3()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(3, float4)`. Its default value is {0,0,0,1}.
|
||||
|
||||
### Vertex only
|
||||
|
||||
The following APIs are only available from the vertex block:
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,6 @@ set(PUBLIC_HDRS
|
||||
include/filament/Frustum.h
|
||||
include/filament/IndexBuffer.h
|
||||
include/filament/IndirectLight.h
|
||||
include/filament/InstanceBuffer.h
|
||||
include/filament/LightManager.h
|
||||
include/filament/Material.h
|
||||
include/filament/MaterialInstance.h
|
||||
@@ -68,7 +67,6 @@ set(SRCS
|
||||
src/HwRenderPrimitiveFactory.cpp
|
||||
src/IndexBuffer.cpp
|
||||
src/IndirectLight.cpp
|
||||
src/InstanceBuffer.cpp
|
||||
src/LightManager.cpp
|
||||
src/Material.cpp
|
||||
src/MaterialInstance.cpp
|
||||
@@ -110,7 +108,6 @@ set(SRCS
|
||||
src/details/Fence.cpp
|
||||
src/details/IndexBuffer.cpp
|
||||
src/details/IndirectLight.cpp
|
||||
src/details/InstanceBuffer.cpp
|
||||
src/details/Material.cpp
|
||||
src/details/MaterialInstance.cpp
|
||||
src/details/MorphTargetBuffer.cpp
|
||||
@@ -174,7 +171,6 @@ set(PRIVATE_HDRS
|
||||
src/details/Fence.h
|
||||
src/details/IndexBuffer.h
|
||||
src/details/IndirectLight.h
|
||||
src/details/InstanceBuffer.h
|
||||
src/details/Material.h
|
||||
src/details/MaterialInstance.h
|
||||
src/details/MorphTargetBuffer.h
|
||||
@@ -216,7 +212,6 @@ set(MATERIAL_SRCS
|
||||
src/materials/colorGrading/colorGrading.mat
|
||||
src/materials/colorGrading/colorGradingAsSubpass.mat
|
||||
src/materials/colorGrading/customResolveAsSubpass.mat
|
||||
src/materials/debugShadowCascades.mat
|
||||
src/materials/defaultMaterial.mat
|
||||
src/materials/dof/dof.mat
|
||||
src/materials/dof/dofCoc.mat
|
||||
@@ -250,11 +245,6 @@ set(MATERIAL_SRCS
|
||||
src/materials/vsmMipmap.mat
|
||||
)
|
||||
|
||||
set(MATERIAL_ES2_SRCS
|
||||
src/materials/defaultMaterial0.mat
|
||||
src/materials/skybox0.mat
|
||||
)
|
||||
|
||||
# Embed the binary resource blob for materials.
|
||||
get_resgen_vars(${RESOURCE_DIR} materials)
|
||||
list(APPEND PRIVATE_HDRS ${RESGEN_HEADER})
|
||||
@@ -320,23 +310,6 @@ foreach (mat_src ${MATERIAL_SRCS})
|
||||
list(APPEND MATERIAL_BINS ${output_path})
|
||||
endforeach()
|
||||
|
||||
if (IS_MOBILE_TARGET AND FILAMENT_SUPPORTS_OPENGL)
|
||||
foreach (mat_src ${MATERIAL_ES2_SRCS})
|
||||
get_filename_component(localname "${mat_src}" NAME_WE)
|
||||
get_filename_component(fullname "${mat_src}" ABSOLUTE)
|
||||
set(output_path "${MATERIAL_DIR}/${localname}.filamat")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${output_path}
|
||||
COMMAND matc -a opengl -p ${MATC_TARGET} ${MATC_OPT_FLAGS} -o ${output_path} ${fullname}
|
||||
MAIN_DEPENDENCY ${fullname}
|
||||
DEPENDS matc
|
||||
COMMENT "Compiling material ${mat_src} to ${output_path}"
|
||||
)
|
||||
list(APPEND MATERIAL_BINS ${output_path})
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
# Additional dependencies on included files for materials
|
||||
|
||||
add_custom_command(
|
||||
@@ -591,7 +564,6 @@ elseif(WEBGL)
|
||||
else()
|
||||
set(OPTIMIZATION_FLAGS
|
||||
-ffast-math
|
||||
-fno-finite-math-only
|
||||
-ffp-contract=fast
|
||||
# TODO: aggressive vectorization is currently broken on Android
|
||||
# -fslp-vectorize-aggressive
|
||||
|
||||
@@ -96,7 +96,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
|
||||
list(APPEND SRCS src/opengl/platforms/CocoaTouchExternalImage.mm)
|
||||
elseif (APPLE)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformCocoaGL.mm)
|
||||
list(APPEND SRCS src/opengl/platforms/CocoaExternalImage.mm)
|
||||
elseif (WEBGL)
|
||||
list(APPEND SRCS src/opengl/platforms/PlatformWebGL.cpp)
|
||||
elseif (LINUX)
|
||||
@@ -175,19 +174,20 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
src/vulkan/VulkanFboCache.h
|
||||
src/vulkan/VulkanHandles.cpp
|
||||
src/vulkan/VulkanHandles.h
|
||||
src/vulkan/VulkanImageUtility.cpp
|
||||
src/vulkan/VulkanImageUtility.h
|
||||
src/vulkan/VulkanMemory.h
|
||||
src/vulkan/VulkanMemory.cpp
|
||||
src/vulkan/VulkanPipelineCache.cpp
|
||||
src/vulkan/VulkanPipelineCache.h
|
||||
src/vulkan/VulkanPlatform.cpp
|
||||
src/vulkan/VulkanReadPixels.cpp
|
||||
src/vulkan/VulkanReadPixels.h
|
||||
src/vulkan/VulkanSamplerCache.cpp
|
||||
src/vulkan/VulkanSamplerCache.h
|
||||
src/vulkan/VulkanStagePool.cpp
|
||||
src/vulkan/VulkanStagePool.h
|
||||
src/vulkan/VulkanSwapChain.cpp
|
||||
src/vulkan/VulkanSwapChain.h
|
||||
src/vulkan/VulkanTaskHandler.h
|
||||
src/vulkan/VulkanTexture.cpp
|
||||
src/vulkan/VulkanTexture.h
|
||||
src/vulkan/VulkanUtility.cpp
|
||||
@@ -335,7 +335,6 @@ elseif(WEBGL)
|
||||
else()
|
||||
set(OPTIMIZATION_FLAGS
|
||||
-ffast-math
|
||||
-fno-finite-math-only
|
||||
-ffp-contract=fast
|
||||
# TODO: aggressive vectorization is currently broken on Android
|
||||
# -fslp-vectorize-aggressive
|
||||
|
||||
@@ -106,8 +106,7 @@ static constexpr size_t CONFIG_SAMPLER_BINDING_COUNT = 4; // This is guarantee
|
||||
* Defines the backend's feature levels.
|
||||
*/
|
||||
enum class FeatureLevel : uint8_t {
|
||||
FEATURE_LEVEL_0 = 0, //!< OpenGL ES 2.0 features
|
||||
FEATURE_LEVEL_1, //!< OpenGL ES 3.0 features (default)
|
||||
FEATURE_LEVEL_1 = 1, //!< OpenGL ES 3.0 features (default)
|
||||
FEATURE_LEVEL_2, //!< OpenGL ES 3.1 features + 16 textures units + cubemap arrays
|
||||
FEATURE_LEVEL_3 //!< OpenGL ES 3.1 features + 31 textures units + cubemap arrays
|
||||
};
|
||||
@@ -280,15 +279,6 @@ enum class UniformType : uint8_t {
|
||||
STRUCT
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported constant parameter types
|
||||
*/
|
||||
enum class ConstantType : uint8_t {
|
||||
INT,
|
||||
FLOAT,
|
||||
BOOL
|
||||
};
|
||||
|
||||
enum class Precision : uint8_t {
|
||||
LOW,
|
||||
MEDIUM,
|
||||
@@ -1127,10 +1117,7 @@ enum class Workaround : uint16_t {
|
||||
// the whole render pass.
|
||||
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP,
|
||||
// for some uniform arrays, it's needed to do an initialization to avoid crash on adreno gpu
|
||||
ADRENO_UNIFORM_ARRAY_CRASH,
|
||||
// Workaround a Metal pipeline compilation error with the message:
|
||||
// "Could not statically determine the target of a texture". See light_indirect.fs
|
||||
A8X_STATIC_TEXTURE_TARGET_ERROR
|
||||
ADRENO_UNIFORM_ARRAY_CRASH
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -48,15 +48,7 @@ public:
|
||||
ShaderStageFlags stageFlags = ShaderStageFlags::ALL_SHADER_STAGE_FLAGS;
|
||||
};
|
||||
|
||||
struct Uniform {
|
||||
utils::CString name; // full qualified name of the uniform field
|
||||
uint16_t offset; // offset in 'uint32_t' into the uniform buffer
|
||||
uint8_t size; // >1 for arrays
|
||||
UniformType type; // uniform type
|
||||
};
|
||||
|
||||
using UniformBlockInfo = std::array<utils::CString, UNIFORM_BINDING_COUNT>;
|
||||
using UniformInfo = utils::FixedCapacityVector<Uniform>;
|
||||
using SamplerGroupInfo = std::array<SamplerGroupData, SAMPLER_BINDING_COUNT>;
|
||||
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
|
||||
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
|
||||
@@ -86,14 +78,6 @@ public:
|
||||
Program& uniformBlockBindings(
|
||||
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> const& uniformBlockBindings) noexcept;
|
||||
|
||||
// Note: This is only needed for GLES2.0, this is used to emulate UBO. This function tells
|
||||
// the program everything it needs to know about the uniforms at a given binding
|
||||
Program& uniforms(uint32_t index, UniformInfo const& uniforms) noexcept;
|
||||
|
||||
// Note: This is only needed for GLES2.0.
|
||||
Program& attributes(
|
||||
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> attributes) noexcept;
|
||||
|
||||
// sets the 'bindingPoint' sampler group descriptor for this program.
|
||||
// 'samplers' can be destroyed after this call.
|
||||
// This effectively associates a set of (BindingPoints, index) to a texture unit in the shader.
|
||||
@@ -119,12 +103,6 @@ public:
|
||||
SamplerGroupInfo const& getSamplerGroupInfo() const { return mSamplerGroups; }
|
||||
SamplerGroupInfo& getSamplerGroupInfo() { return mSamplerGroups; }
|
||||
|
||||
auto const& getBindingUniformInfo() const { return mBindingUniformInfo; }
|
||||
auto& getBindingUniformInfo() { return mBindingUniformInfo; }
|
||||
|
||||
auto const& getAttributes() const { return mAttributes; }
|
||||
auto& getAttributes() { return mAttributes; }
|
||||
|
||||
utils::CString const& getName() const noexcept { return mName; }
|
||||
utils::CString& getName() noexcept { return mName; }
|
||||
|
||||
@@ -144,8 +122,6 @@ private:
|
||||
utils::CString mName;
|
||||
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
|
||||
utils::FixedCapacityVector<SpecializationConstant> mSpecializationConstants;
|
||||
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> mAttributes;
|
||||
std::array<UniformInfo, Program::UNIFORM_BINDING_COUNT> mBindingUniformInfo;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -95,19 +95,6 @@ public:
|
||||
*/
|
||||
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
|
||||
|
||||
/**
|
||||
* Returns the set of buffers that must be preserved up to the call to commit().
|
||||
* The default value is TargetBufferFlags::NONE.
|
||||
* The color buffer is always preserved, however ancillary buffers, such as the depth buffer
|
||||
* are generally discarded. The preserve flags can be used to make sure those ancillary
|
||||
* buffers are preserved until the call to commit.
|
||||
*
|
||||
* @param swapChain
|
||||
* @return buffer that must be preserved
|
||||
* @see commit()
|
||||
*/
|
||||
virtual TargetBufferFlags getPreservedFlags(SwapChain* swapChain) noexcept;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -57,10 +57,6 @@ protected:
|
||||
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:
|
||||
PlatformCocoaGLImpl* pImpl = nullptr;
|
||||
|
||||
@@ -26,9 +26,6 @@
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
@@ -40,27 +37,6 @@ public:
|
||||
PlatformEGL() noexcept;
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Helper for EGL configs and attributes parameters
|
||||
|
||||
class Config {
|
||||
public:
|
||||
Config();
|
||||
Config(std::initializer_list<std::pair<EGLint, EGLint>> list);
|
||||
EGLint& operator[](EGLint name);
|
||||
EGLint operator[](EGLint name) const;
|
||||
void erase(EGLint name) noexcept;
|
||||
EGLint const* data() const noexcept {
|
||||
return reinterpret_cast<EGLint const*>(mConfig.data());
|
||||
}
|
||||
size_t size() const noexcept {
|
||||
return mConfig.size();
|
||||
}
|
||||
private:
|
||||
std::vector<std::pair<EGLint, EGLint>> mConfig = {{ EGL_NONE, EGL_NONE }};
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Platform Interface
|
||||
|
||||
@@ -103,8 +79,6 @@ protected:
|
||||
* @param name a string giving some context on the error. Typically __func__.
|
||||
*/
|
||||
static void logEglError(const char* name) noexcept;
|
||||
static void logEglError(const char* name, EGLint error) noexcept;
|
||||
static const char* getEglErrorName(EGLint error) noexcept;
|
||||
|
||||
/**
|
||||
* Calls glGetError() to clear the current error flags. logs a warning to log.w if
|
||||
@@ -131,10 +105,8 @@ protected:
|
||||
bool OES_EGL_image_external_essl3 = false;
|
||||
} gl;
|
||||
struct {
|
||||
bool ANDROID_recordable = false;
|
||||
bool KHR_create_context = false;
|
||||
bool KHR_gl_colorspace = false;
|
||||
bool KHR_no_config_context = false;
|
||||
bool KHR_gl_colorspace = false;
|
||||
} egl;
|
||||
} ext;
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ Program& Program::operator=(Program&& rhs) noexcept {
|
||||
mShadersSource.operator=(std::move(rhs.mShadersSource));
|
||||
mName.operator=(std::move(rhs.mName));
|
||||
mLogger.operator=(std::move(rhs.mLogger));
|
||||
mSpecializationConstants.operator=(std::move(rhs.mSpecializationConstants));
|
||||
mBindingUniformInfo.operator=(std::move(rhs.mBindingUniformInfo));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -62,19 +60,6 @@ Program& Program::uniformBlockBindings(
|
||||
return *this;
|
||||
}
|
||||
|
||||
Program& Program::uniforms(uint32_t index, UniformInfo const& uniforms) noexcept {
|
||||
assert_invariant(index < UNIFORM_BINDING_COUNT);
|
||||
mBindingUniformInfo[index] = uniforms;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Program& Program::attributes(
|
||||
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> attributes) noexcept {
|
||||
mAttributes = std::move(attributes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Program& Program::setSamplerGroup(size_t bindingPoint, ShaderStageFlags stageFlags,
|
||||
const Program::Sampler* samplers, size_t count) noexcept {
|
||||
auto& groupData = mSamplerGroups[bindingPoint];
|
||||
|
||||
@@ -73,10 +73,6 @@ struct MetalContext {
|
||||
uint8_t mac;
|
||||
} highestSupportedGpuFamily;
|
||||
|
||||
struct {
|
||||
bool a8xStaticTextureTargetError;
|
||||
} bugs;
|
||||
|
||||
// sampleCountLookup[requestedSamples] gives a <= sample count supported by the device.
|
||||
std::array<uint8_t, MAX_SAMPLE_COUNT + 1> sampleCountLookup;
|
||||
|
||||
|
||||
@@ -117,9 +117,6 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
|
||||
sc[s] = [mContext->device supportsTextureSampleCount:s] ? s : sc[s - 1];
|
||||
}
|
||||
|
||||
mContext->bugs.a8xStaticTextureTargetError =
|
||||
[mContext->device.name containsString:@"Apple A8X GPU"];
|
||||
|
||||
mContext->commandQueue = mPlatform.createCommandQueue(mContext->device);
|
||||
mContext->pipelineStateCache.setDevice(mContext->device);
|
||||
mContext->depthStencilStateCache.setDevice(mContext->device);
|
||||
@@ -722,8 +719,6 @@ bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
return true;
|
||||
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
|
||||
return false;
|
||||
case Workaround::A8X_STATIC_TEXTURE_TARGET_ERROR:
|
||||
return mContext->bugs.a8xStaticTextureTargetError;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,9 @@ const char* getFramebufferStatus(GLenum status) noexcept {
|
||||
case GL_FRAMEBUFFER_COMPLETE:
|
||||
string = "GL_FRAMEBUFFER_COMPLETE";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNDEFINED:
|
||||
string = "GL_FRAMEBUFFER_UNDEFINED";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
|
||||
string = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
|
||||
break;
|
||||
@@ -90,14 +93,9 @@ const char* getFramebufferStatus(GLenum status) noexcept {
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED:
|
||||
string = "GL_FRAMEBUFFER_UNSUPPORTED";
|
||||
break;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
case GL_FRAMEBUFFER_UNDEFINED:
|
||||
string = "GL_FRAMEBUFFER_UNDEFINED";
|
||||
break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
|
||||
string = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,14 +118,9 @@ constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) no
|
||||
case BufferObjectBinding::VERTEX:
|
||||
return GL_ARRAY_BUFFER;
|
||||
case BufferObjectBinding::UNIFORM:
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
return GL_UNIFORM_BUFFER;
|
||||
#else
|
||||
utils::panic(__func__, __FILE__, __LINE__, "UNIFORM not supported");
|
||||
return 0x8A11;
|
||||
#endif
|
||||
case BufferObjectBinding::SHADER_STORAGE:
|
||||
#ifdef BACKEND_OPENGL_LEVEL_GLES31
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
|
||||
return GL_SHADER_STORAGE_BUFFER;
|
||||
#else
|
||||
utils::panic(__func__, __FILE__, __LINE__, "SHADER_STORAGE not supported");
|
||||
@@ -174,12 +169,7 @@ constexpr inline GLenum getComponentType(ElementType type) noexcept {
|
||||
case ElementType::HALF2:
|
||||
case ElementType::HALF3:
|
||||
case ElementType::HALF4:
|
||||
// on ES2 we should never end-up here
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
return GL_HALF_FLOAT;
|
||||
#else
|
||||
return GL_HALF_FLOAT_OES;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +238,13 @@ constexpr inline GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline GLenum getCompareFunc(SamplerCompareFunc func) noexcept {
|
||||
constexpr inline GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
|
||||
return mode == SamplerCompareMode::NONE ?
|
||||
GL_NONE : GL_COMPARE_REF_TO_TEXTURE;
|
||||
}
|
||||
|
||||
constexpr inline GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
|
||||
using SamplerCompareFunc = SamplerCompareFunc;
|
||||
switch (func) {
|
||||
case SamplerCompareFunc::LE: return GL_LEQUAL;
|
||||
case SamplerCompareFunc::GE: return GL_GEQUAL;
|
||||
@@ -261,23 +257,12 @@ constexpr inline GLenum getCompareFunc(SamplerCompareFunc func) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
constexpr inline GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
|
||||
return mode == SamplerCompareMode::NONE ?
|
||||
GL_NONE : GL_COMPARE_REF_TO_TEXTURE;
|
||||
}
|
||||
|
||||
constexpr inline GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
|
||||
return getCompareFunc(func);
|
||||
}
|
||||
#endif
|
||||
|
||||
constexpr inline GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
|
||||
return getCompareFunc(func);
|
||||
return getTextureCompareFunc(func);
|
||||
}
|
||||
|
||||
constexpr inline GLenum getStencilFunc(SamplerCompareFunc func) noexcept {
|
||||
return getCompareFunc(func);
|
||||
return getTextureCompareFunc(func);
|
||||
}
|
||||
|
||||
constexpr inline GLenum getStencilOp(StencilOperation op) noexcept {
|
||||
@@ -296,24 +281,18 @@ constexpr inline GLenum getStencilOp(StencilOperation op) noexcept {
|
||||
constexpr inline GLenum getFormat(PixelDataFormat format) noexcept {
|
||||
using PixelDataFormat = PixelDataFormat;
|
||||
switch (format) {
|
||||
case PixelDataFormat::RGB: return GL_RGB;
|
||||
case PixelDataFormat::RGBA: return GL_RGBA;
|
||||
case PixelDataFormat::UNUSED: return GL_RGBA; // should never happen (used to be rgbm)
|
||||
case PixelDataFormat::DEPTH_COMPONENT: return GL_DEPTH_COMPONENT;
|
||||
case PixelDataFormat::ALPHA: return GL_ALPHA;
|
||||
case PixelDataFormat::DEPTH_STENCIL: return GL_DEPTH_STENCIL;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
// when context is ES2 we should never end-up here
|
||||
case PixelDataFormat::R: return GL_RED;
|
||||
case PixelDataFormat::R_INTEGER: return GL_RED_INTEGER;
|
||||
case PixelDataFormat::RG: return GL_RG;
|
||||
case PixelDataFormat::RG_INTEGER: return GL_RG_INTEGER;
|
||||
case PixelDataFormat::RGB: return GL_RGB;
|
||||
case PixelDataFormat::RGB_INTEGER: return GL_RGB_INTEGER;
|
||||
case PixelDataFormat::RGBA: return GL_RGBA;
|
||||
case PixelDataFormat::RGBA_INTEGER: return GL_RGBA_INTEGER;
|
||||
#else
|
||||
// silence compiler warning in ES2 headers mode
|
||||
default: return GL_NONE;
|
||||
#endif
|
||||
case PixelDataFormat::UNUSED: return GL_RGBA; // should never happen (used to be rgbm)
|
||||
case PixelDataFormat::DEPTH_COMPONENT: return GL_DEPTH_COMPONENT;
|
||||
case PixelDataFormat::DEPTH_STENCIL: return GL_DEPTH_STENCIL;
|
||||
case PixelDataFormat::ALPHA: return GL_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,34 +305,32 @@ constexpr inline GLenum getType(PixelDataType type) noexcept {
|
||||
case PixelDataType::SHORT: return GL_SHORT;
|
||||
case PixelDataType::UINT: return GL_UNSIGNED_INT;
|
||||
case PixelDataType::INT: return GL_INT;
|
||||
case PixelDataType::FLOAT: return GL_FLOAT;
|
||||
case PixelDataType::USHORT_565: return GL_UNSIGNED_SHORT_5_6_5;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
// when context is ES2 we should never end-up here
|
||||
case PixelDataType::HALF: return GL_HALF_FLOAT;
|
||||
case PixelDataType::FLOAT: return GL_FLOAT;
|
||||
case PixelDataType::UINT_10F_11F_11F_REV: return GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||
case PixelDataType::USHORT_565: return GL_UNSIGNED_SHORT_5_6_5;
|
||||
case PixelDataType::UINT_2_10_10_10_REV: return GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
case PixelDataType::COMPRESSED: return 0; // should never happen
|
||||
#else
|
||||
// silence compiler warning in ES2 headers mode
|
||||
default: return GL_NONE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
|
||||
constexpr inline GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
|
||||
using TextureSwizzle = TextureSwizzle;
|
||||
switch (c) {
|
||||
case TextureSwizzle::SUBSTITUTE_ZERO: return GL_ZERO;
|
||||
case TextureSwizzle::SUBSTITUTE_ONE: return GL_ONE;
|
||||
case TextureSwizzle::CHANNEL_0: return GL_RED;
|
||||
case TextureSwizzle::CHANNEL_1: return GL_GREEN;
|
||||
case TextureSwizzle::CHANNEL_2: return GL_BLUE;
|
||||
case TextureSwizzle::CHANNEL_3: return GL_ALPHA;
|
||||
case TextureSwizzle::SUBSTITUTE_ZERO:
|
||||
return GL_ZERO;
|
||||
case TextureSwizzle::SUBSTITUTE_ONE:
|
||||
return GL_ONE;
|
||||
case TextureSwizzle::CHANNEL_0:
|
||||
return GL_RED;
|
||||
case TextureSwizzle::CHANNEL_1:
|
||||
return GL_GREEN;
|
||||
case TextureSwizzle::CHANNEL_2:
|
||||
return GL_BLUE;
|
||||
case TextureSwizzle::CHANNEL_3:
|
||||
return GL_ALPHA;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
constexpr inline GLenum getCullingMode(CullingMode mode) noexcept {
|
||||
switch (mode) {
|
||||
@@ -369,56 +346,18 @@ constexpr inline GLenum getCullingMode(CullingMode mode) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
// ES2 supported internal formats for texturing and how they map to a format/type
|
||||
constexpr inline std::pair<GLenum, GLenum> textureFormatToFormatAndType(
|
||||
TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
case TextureFormat::RGB8: return { GL_RGB, GL_UNSIGNED_BYTE };
|
||||
case TextureFormat::RGBA8: return { GL_RGBA, GL_UNSIGNED_BYTE };
|
||||
case TextureFormat::RGB565: return { GL_RGB, GL_UNSIGNED_SHORT_5_6_5 };
|
||||
case TextureFormat::RGB5_A1: return { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 };
|
||||
case TextureFormat::RGBA4: return { GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 };
|
||||
case TextureFormat::DEPTH16: return { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT };
|
||||
case TextureFormat::DEPTH24: return { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT };
|
||||
case TextureFormat::DEPTH24_STENCIL8:
|
||||
return { GL_DEPTH24_STENCIL8, GL_UNSIGNED_INT_24_8 };
|
||||
default: return { GL_NONE, GL_NONE };
|
||||
}
|
||||
}
|
||||
|
||||
// clang loses it on this one, and generates a huge jump table when
|
||||
// clang looses it on this one, and generates a huge jump table when
|
||||
// inlined. So we don't mark it as inline (only constexpr) which solves the problem,
|
||||
// strangely, when not inlined, clang simply generates an array lookup.
|
||||
constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
|
||||
using TextureFormat = TextureFormat;
|
||||
switch (format) {
|
||||
|
||||
/* Formats supported by our ES2 implementations */
|
||||
|
||||
// 8-bits per element
|
||||
case TextureFormat::STENCIL8: return GL_STENCIL_INDEX8;
|
||||
|
||||
// 16-bits per element
|
||||
case TextureFormat::RGB565: return GL_RGB565;
|
||||
case TextureFormat::RGB5_A1: return GL_RGB5_A1;
|
||||
case TextureFormat::RGBA4: return GL_RGBA4;
|
||||
case TextureFormat::DEPTH16: return GL_DEPTH_COMPONENT16;
|
||||
|
||||
// 24-bits per element
|
||||
case TextureFormat::RGB8: return GL_RGB8;
|
||||
case TextureFormat::DEPTH24: return GL_DEPTH_COMPONENT24;
|
||||
|
||||
// 32-bits per element
|
||||
case TextureFormat::RGBA8: return GL_RGBA8;
|
||||
case TextureFormat::DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
|
||||
|
||||
/* Formats not supported by our ES2 implementations */
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
// 8-bits per element
|
||||
case TextureFormat::R8: return GL_R8;
|
||||
case TextureFormat::R8_SNORM: return GL_R8_SNORM;
|
||||
case TextureFormat::R8UI: return GL_R8UI;
|
||||
case TextureFormat::R8I: return GL_R8I;
|
||||
case TextureFormat::STENCIL8: return GL_STENCIL_INDEX8;
|
||||
|
||||
// 16-bits per element
|
||||
case TextureFormat::R16F: return GL_R16F;
|
||||
@@ -428,12 +367,18 @@ constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
|
||||
case TextureFormat::RG8_SNORM: return GL_RG8_SNORM;
|
||||
case TextureFormat::RG8UI: return GL_RG8UI;
|
||||
case TextureFormat::RG8I: return GL_RG8I;
|
||||
case TextureFormat::RGB565: return GL_RGB565;
|
||||
case TextureFormat::RGB5_A1: return GL_RGB5_A1;
|
||||
case TextureFormat::RGBA4: return GL_RGBA4;
|
||||
case TextureFormat::DEPTH16: return GL_DEPTH_COMPONENT16;
|
||||
|
||||
// 24-bits per element
|
||||
case TextureFormat::RGB8: return GL_RGB8;
|
||||
case TextureFormat::SRGB8: return GL_SRGB8;
|
||||
case TextureFormat::RGB8_SNORM: return GL_RGB8_SNORM;
|
||||
case TextureFormat::RGB8UI: return GL_RGB8UI;
|
||||
case TextureFormat::RGB8I: return GL_RGB8I;
|
||||
case TextureFormat::DEPTH24: return GL_DEPTH_COMPONENT24;
|
||||
|
||||
// 32-bits per element
|
||||
case TextureFormat::R32F: return GL_R32F;
|
||||
@@ -444,12 +389,14 @@ constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
|
||||
case TextureFormat::RG16I: return GL_RG16I;
|
||||
case TextureFormat::R11F_G11F_B10F: return GL_R11F_G11F_B10F;
|
||||
case TextureFormat::RGB9_E5: return GL_RGB9_E5;
|
||||
case TextureFormat::RGBA8: return GL_RGBA8;
|
||||
case TextureFormat::SRGB8_A8: return GL_SRGB8_ALPHA8;
|
||||
case TextureFormat::RGBA8_SNORM: return GL_RGBA8_SNORM;
|
||||
case TextureFormat::RGB10_A2: return GL_RGB10_A2;
|
||||
case TextureFormat::RGBA8UI: return GL_RGBA8UI;
|
||||
case TextureFormat::RGBA8I: return GL_RGBA8I;
|
||||
case TextureFormat::DEPTH32F: return GL_DEPTH_COMPONENT32F;
|
||||
case TextureFormat::DEPTH24_STENCIL8: return GL_DEPTH24_STENCIL8;
|
||||
case TextureFormat::DEPTH32F_STENCIL8: return GL_DEPTH32F_STENCIL8;
|
||||
|
||||
// 48-bits per element
|
||||
@@ -474,12 +421,6 @@ constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
|
||||
case TextureFormat::RGBA32F: return GL_RGBA32F;
|
||||
case TextureFormat::RGBA32UI: return GL_RGBA32UI;
|
||||
case TextureFormat::RGBA32I: return GL_RGBA32I;
|
||||
#else
|
||||
default:
|
||||
// this is just to squash the IDE warning about not having all cases when in
|
||||
// ES2 header mode.
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
// compressed formats
|
||||
#if defined(GL_ES_VERSION_3_0) || defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_ARB_ES3_compatibility)
|
||||
|
||||
@@ -29,17 +29,10 @@ namespace filament::backend {
|
||||
|
||||
bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept {
|
||||
#ifdef BACKEND_OPENGL_VERSION_GLES
|
||||
# ifdef BACKEND_OPENGL_LEVEL_GLES30
|
||||
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;
|
||||
return n == 2;
|
||||
# else
|
||||
// when we compile with GLES2.0 only, we force the context version to 2.0
|
||||
*major = 2;
|
||||
*minor = 0;
|
||||
return true;
|
||||
# endif
|
||||
#else
|
||||
// OpenGL version
|
||||
glGetIntegerv(GL_MAJOR_VERSION, major);
|
||||
@@ -67,54 +60,19 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
queryOpenGLVersion(&state.major, &state.minor);
|
||||
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &gets.max_renderbuffer_size);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gets.max_uniform_block_size);
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &gets.max_samples);
|
||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &gets.max_draw_buffers);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gets.max_texture_image_units);
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &gets.max_combined_texture_image_units);
|
||||
|
||||
if (state.major > 2) { // this check works for both GL and GLES, but is intended for GLES
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &gets.max_uniform_block_size);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gets.max_uniform_buffer_bindings);
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &gets.uniform_buffer_offset_alignment);
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &gets.max_samples);
|
||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &gets.max_draw_buffers);
|
||||
glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
|
||||
&gets.max_transform_feedback_separate_attribs);
|
||||
#endif
|
||||
} else {
|
||||
gets.max_uniform_block_size = 0;
|
||||
gets.max_uniform_buffer_bindings = 0;
|
||||
gets.uniform_buffer_offset_alignment = 0;
|
||||
gets.max_samples = 1;
|
||||
gets.max_draw_buffers = 1;
|
||||
gets.max_transform_feedback_separate_attribs = 0;
|
||||
}
|
||||
glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &gets.max_transform_feedback_separate_attribs);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gets.max_uniform_buffer_bindings);
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &gets.uniform_buffer_offset_alignment);
|
||||
|
||||
constexpr auto const caps3 = FEATURE_LEVEL_CAPS[+FeatureLevel::FEATURE_LEVEL_3];
|
||||
constexpr GLint MAX_VERTEX_SAMPLER_COUNT = caps3.MAX_VERTEX_SAMPLER_COUNT;
|
||||
constexpr GLint MAX_FRAGMENT_SAMPLER_COUNT = caps3.MAX_FRAGMENT_SAMPLER_COUNT;
|
||||
|
||||
// default procs that can be overridden based on runtime version
|
||||
#ifdef BACKEND_OPENGL_LEVEL_GLES30
|
||||
procs.genVertexArrays = glGenVertexArrays;
|
||||
procs.bindVertexArray = glBindVertexArray;
|
||||
procs.deleteVertexArrays = glDeleteVertexArrays;
|
||||
|
||||
// these are core in GL and GLES 3.x
|
||||
procs.genQueries = glGenQueries;
|
||||
procs.deleteQueries = glDeleteQueries;
|
||||
procs.beginQuery = glBeginQuery;
|
||||
procs.endQuery = glEndQuery;
|
||||
procs.getQueryObjectuiv = glGetQueryObjectuiv;
|
||||
# ifdef BACKEND_OPENGL_VERSION_GL
|
||||
procs.getQueryObjectui64v = glGetQueryObjectui64v; // only core in GL
|
||||
# elif defined(GL_EXT_disjoint_timer_query)
|
||||
procs.getQueryObjectui64v = glGetQueryObjectui64vEXT;
|
||||
# endif // BACKEND_OPENGL_VERSION_GL
|
||||
|
||||
// core in ES 3.0 and GL 4.3
|
||||
procs.invalidateFramebuffer = glInvalidateFramebuffer;
|
||||
#endif // BACKEND_OPENGL_LEVEL_GLES30
|
||||
|
||||
#ifdef BACKEND_OPENGL_VERSION_GLES
|
||||
initExtensionsGLES();
|
||||
if (state.major == 3) {
|
||||
@@ -134,48 +92,6 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef IOS // IOS is guaranteed to have ES3.x
|
||||
else if (UTILS_UNLIKELY(state.major == 2)) {
|
||||
// Runtime OpenGL version is ES 2.x
|
||||
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES30)
|
||||
// mandatory extensions (all supported by Mali-400 and Adreno 304)
|
||||
assert_invariant(ext.OES_depth_texture);
|
||||
assert_invariant(ext.OES_depth24);
|
||||
assert_invariant(ext.OES_packed_depth_stencil);
|
||||
assert_invariant(ext.OES_rgb8_rgba8);
|
||||
assert_invariant(ext.OES_standard_derivatives);
|
||||
assert_invariant(ext.OES_texture_npot);
|
||||
#endif
|
||||
|
||||
if (UTILS_LIKELY(ext.OES_vertex_array_object)) {
|
||||
procs.genVertexArrays = glGenVertexArraysOES;
|
||||
procs.bindVertexArray = glBindVertexArrayOES;
|
||||
procs.deleteVertexArrays = glDeleteVertexArraysOES;
|
||||
} else {
|
||||
// if we don't have OES_vertex_array_object, just don't do anything with real VAOs,
|
||||
// we'll just rebind everything each time. Most Mali-400 support this extension, but
|
||||
// a few don't.
|
||||
procs.genVertexArrays = +[](GLsizei, GLuint*) {};
|
||||
procs.bindVertexArray = +[](GLuint) {};
|
||||
procs.deleteVertexArrays = +[](GLsizei, GLuint const*) {};
|
||||
// we activate this workaround path, which does the reset of array buffer
|
||||
bugs.vao_doesnt_store_element_array_buffer_binding = true;
|
||||
}
|
||||
|
||||
// EXT_disjoint_timer_query is optional -- pointers will be null if not available
|
||||
procs.genQueries = glGenQueriesEXT;
|
||||
procs.deleteQueries = glDeleteQueriesEXT;
|
||||
procs.beginQuery = glBeginQueryEXT;
|
||||
procs.endQuery = glEndQueryEXT;
|
||||
procs.getQueryObjectuiv = glGetQueryObjectuivEXT;
|
||||
procs.getQueryObjectui64v = glGetQueryObjectui64vEXT;
|
||||
|
||||
procs.invalidateFramebuffer = glDiscardFramebufferEXT;
|
||||
|
||||
mFeatureLevel = FeatureLevel::FEATURE_LEVEL_0;
|
||||
}
|
||||
#endif // IOS
|
||||
#else
|
||||
initExtensionsGL();
|
||||
if (state.major == 4) {
|
||||
@@ -323,6 +239,8 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
}
|
||||
flush(slog.v);
|
||||
|
||||
assert_invariant(gets.max_draw_buffers >= 4); // minspec
|
||||
|
||||
#ifndef NDEBUG
|
||||
// this is useful for development
|
||||
slog.v << "GL_MAX_DRAW_BUFFERS = " << gets.max_draw_buffers << '\n'
|
||||
@@ -336,15 +254,10 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
flush(slog.v);
|
||||
#endif
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
assert_invariant(state.major <= 2 || gets.max_draw_buffers >= 4); // minspec
|
||||
#endif
|
||||
|
||||
setDefaultState();
|
||||
|
||||
#ifdef GL_EXT_texture_filter_anisotropic
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
if (state.major > 2 && ext.EXT_texture_filter_anisotropic) {
|
||||
if (ext.EXT_texture_filter_anisotropic) {
|
||||
// make sure we don't have any error flag
|
||||
while (glGetError() != GL_NO_ERROR) { }
|
||||
|
||||
@@ -358,7 +271,6 @@ OpenGLContext::OpenGLContext() noexcept {
|
||||
}
|
||||
glDeleteSamplers(1, &s);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// in practice KHR_Debug has never been useful, and actually is confusing. We keep this
|
||||
@@ -465,7 +377,6 @@ void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
ext.EXT_color_buffer_float = exts.has("GL_EXT_color_buffer_float"sv);
|
||||
ext.EXT_color_buffer_half_float = exts.has("GL_EXT_color_buffer_half_float"sv);
|
||||
ext.EXT_debug_marker = exts.has("GL_EXT_debug_marker"sv);
|
||||
ext.EXT_discard_framebuffer = exts.has("GL_EXT_discard_framebuffer"sv);
|
||||
ext.EXT_disjoint_timer_query = exts.has("GL_EXT_disjoint_timer_query"sv);
|
||||
ext.EXT_multisampled_render_to_texture = exts.has("GL_EXT_multisampled_render_to_texture"sv);
|
||||
ext.EXT_multisampled_render_to_texture2 = exts.has("GL_EXT_multisampled_render_to_texture2"sv);
|
||||
@@ -482,28 +393,14 @@ void OpenGLContext::initExtensionsGLES() noexcept {
|
||||
ext.KHR_debug = exts.has("GL_KHR_debug"sv);
|
||||
ext.KHR_texture_compression_astc_hdr = exts.has("GL_KHR_texture_compression_astc_hdr"sv);
|
||||
ext.KHR_texture_compression_astc_ldr = exts.has("GL_KHR_texture_compression_astc_ldr"sv);
|
||||
ext.OES_depth_texture = exts.has("GL_OES_depth_texture"sv);
|
||||
ext.OES_depth24 = exts.has("GL_OES_depth24"sv);
|
||||
ext.OES_packed_depth_stencil = exts.has("GL_OES_packed_depth_stencil"sv);
|
||||
ext.OES_EGL_image_external_essl3 = exts.has("GL_OES_EGL_image_external_essl3"sv);
|
||||
ext.OES_rgb8_rgba8 = exts.has("GL_OES_rgb8_rgba8"sv);
|
||||
ext.OES_standard_derivatives = exts.has("GL_OES_standard_derivatives"sv);
|
||||
ext.OES_texture_npot = exts.has("GL_OES_texture_npot"sv);
|
||||
ext.OES_vertex_array_object = exts.has("GL_OES_vertex_array_object"sv);
|
||||
ext.WEBGL_compressed_texture_etc = exts.has("WEBGL_compressed_texture_etc"sv);
|
||||
ext.WEBGL_compressed_texture_s3tc = exts.has("WEBGL_compressed_texture_s3tc"sv);
|
||||
ext.WEBGL_compressed_texture_s3tc_srgb = exts.has("WEBGL_compressed_texture_s3tc_srgb"sv);
|
||||
|
||||
// ES 3.2 implies EXT_color_buffer_float
|
||||
if (state.major > 3 || (state.major == 3 && state.minor >= 2)) {
|
||||
if (state.major >= 3 && state.minor >= 2) {
|
||||
ext.EXT_color_buffer_float = true;
|
||||
}
|
||||
|
||||
// ES 3.x implies EXT_discard_framebuffer and OES_vertex_array_object
|
||||
if (state.major >= 3) {
|
||||
ext.EXT_color_buffer_float = true;
|
||||
ext.OES_vertex_array_object = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BACKEND_OPENGL_VERSION_GLES
|
||||
@@ -525,12 +422,14 @@ void OpenGLContext::initExtensionsGL() noexcept {
|
||||
}
|
||||
|
||||
using namespace std::literals;
|
||||
auto major = state.major;
|
||||
auto minor = state.minor;
|
||||
ext.APPLE_color_buffer_packed_float = true; // Assumes core profile.
|
||||
ext.ARB_shading_language_packing = exts.has("GL_ARB_shading_language_packing"sv);
|
||||
ext.ARB_shading_language_packing = exts.has("GL_ARB_shading_language_packing"sv) || (major == 4 && minor >= 2);
|
||||
ext.EXT_clip_control = (major == 4 && minor >= 5);
|
||||
ext.EXT_color_buffer_float = true; // Assumes core profile.
|
||||
ext.EXT_color_buffer_half_float = true; // Assumes core profile.
|
||||
ext.EXT_debug_marker = exts.has("GL_EXT_debug_marker"sv);
|
||||
ext.EXT_discard_framebuffer = false;
|
||||
ext.EXT_disjoint_timer_query = true;
|
||||
ext.EXT_multisampled_render_to_texture = false;
|
||||
ext.EXT_multisampled_render_to_texture2 = false;
|
||||
@@ -544,35 +443,13 @@ void OpenGLContext::initExtensionsGL() noexcept {
|
||||
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);
|
||||
ext.KHR_debug = major >= 4 && minor >= 3;
|
||||
ext.KHR_texture_compression_astc_hdr = exts.has("GL_KHR_texture_compression_astc_hdr"sv);
|
||||
ext.KHR_texture_compression_astc_ldr = exts.has("GL_KHR_texture_compression_astc_ldr"sv);
|
||||
ext.OES_depth_texture = true;
|
||||
ext.OES_depth24 = true;
|
||||
ext.OES_EGL_image_external_essl3 = false;
|
||||
ext.OES_rgb8_rgba8 = true;
|
||||
ext.OES_standard_derivatives = true;
|
||||
ext.OES_texture_npot = true;
|
||||
ext.OES_vertex_array_object = true;
|
||||
ext.WEBGL_compressed_texture_etc = false;
|
||||
ext.WEBGL_compressed_texture_s3tc = false;
|
||||
ext.WEBGL_compressed_texture_s3tc_srgb = false;
|
||||
|
||||
auto const major = state.major;
|
||||
auto const minor = state.minor;
|
||||
|
||||
// OpenGL 4.2 implies ARB_shading_language_packing
|
||||
if (major > 4 || (major == 4 && minor >= 2)) {
|
||||
ext.ARB_shading_language_packing = true;
|
||||
}
|
||||
// OpenGL 4.3 implies EXT_discard_framebuffer
|
||||
if (major > 4 || (major == 4 && minor >= 3)) {
|
||||
ext.EXT_discard_framebuffer = true;
|
||||
ext.KHR_debug = true;
|
||||
}
|
||||
// OpenGL 4.5 implies EXT_clip_control
|
||||
if (major > 4 || (major == 4 && minor >= 5)) {
|
||||
ext.EXT_clip_control = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BACKEND_OPENGL_VERSION_GL
|
||||
@@ -608,18 +485,9 @@ void OpenGLContext::pixelStore(GLenum pname, GLint param) noexcept {
|
||||
// that cannot be duplicated at the call site (e.g. glTexImage2D or glReadPixels)
|
||||
|
||||
switch (pname) {
|
||||
case GL_PACK_ALIGNMENT:
|
||||
pcur = &state.pack.alignment;
|
||||
break;
|
||||
case GL_UNPACK_ALIGNMENT:
|
||||
pcur = &state.unpack.alignment;
|
||||
break;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
case GL_UNPACK_ROW_LENGTH:
|
||||
assert_invariant(state.major > 2);
|
||||
pcur = &state.unpack.row_length;
|
||||
break;
|
||||
#endif
|
||||
case GL_PACK_ALIGNMENT: pcur = &state.pack.alignment; break;
|
||||
case GL_UNPACK_ALIGNMENT: pcur = &state.unpack.alignment; break;
|
||||
case GL_UNPACK_ROW_LENGTH: pcur = &state.unpack.row_length; break;
|
||||
default:
|
||||
goto default_case;
|
||||
}
|
||||
@@ -665,11 +533,6 @@ void OpenGLContext::deleteBuffers(GLsizei n, const GLuint* buffers, GLenum targe
|
||||
genericBuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
assert_invariant(state.major > 2 ||
|
||||
(target != GL_UNIFORM_BUFFER && target != GL_TRANSFORM_FEEDBACK_BUFFER));
|
||||
|
||||
if (target == GL_UNIFORM_BUFFER || target == GL_TRANSFORM_FEEDBACK_BUFFER) {
|
||||
auto& indexedBuffer = state.buffers.targets[targetIndex];
|
||||
UTILS_NOUNROLL // clang generates >1 KiB of code!!
|
||||
@@ -684,11 +547,10 @@ void OpenGLContext::deleteBuffers(GLsizei n, const GLuint* buffers, GLenum targe
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLContext::deleteVertexArrays(GLsizei n, const GLuint* arrays) noexcept {
|
||||
procs.deleteVertexArrays(1, arrays);
|
||||
glDeleteVertexArrays(1, arrays);
|
||||
// binding of a bound VAO is reset to 0
|
||||
for (GLsizei i = 0; i < n; ++i) {
|
||||
if (state.vao.p->vao == arrays[i]) {
|
||||
@@ -699,24 +561,15 @@ void OpenGLContext::deleteVertexArrays(GLsizei n, const GLuint* arrays) noexcept
|
||||
|
||||
void OpenGLContext::resetState() noexcept {
|
||||
// Force GL state to match the Filament state
|
||||
if (state.major > 2) {
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, state.draw_fbo);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, state.read_fbo);
|
||||
#endif
|
||||
} else {
|
||||
assert_invariant(state.read_fbo == state.draw_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, state.draw_fbo);
|
||||
state.read_fbo = state.draw_fbo;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, state.draw_fbo);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, state.read_fbo);
|
||||
|
||||
// state.program
|
||||
glUseProgram(state.program.use);
|
||||
|
||||
// state.vao
|
||||
if (state.vao.p) {
|
||||
procs.bindVertexArray(state.vao.p->vao);
|
||||
glBindVertexArray(state.vao.p->vao);
|
||||
} else {
|
||||
bindVertexArray(nullptr);
|
||||
}
|
||||
@@ -778,34 +631,29 @@ 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 = {};
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
if (state.major > 2) {
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
for (auto const target: {
|
||||
GL_UNIFORM_BUFFER,
|
||||
GL_TRANSFORM_FEEDBACK_BUFFER,
|
||||
GLenum const bufferTargets[] = {
|
||||
GL_UNIFORM_BUFFER,
|
||||
GL_TRANSFORM_FEEDBACK_BUFFER,
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
|
||||
GL_SHADER_STORAGE_BUFFER,
|
||||
GL_SHADER_STORAGE_BUFFER,
|
||||
#endif
|
||||
GL_PIXEL_PACK_BUFFER,
|
||||
GL_PIXEL_UNPACK_BUFFER,
|
||||
}) {
|
||||
glBindBuffer(target, 0);
|
||||
GL_ARRAY_BUFFER,
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
GL_PIXEL_PACK_BUFFER,
|
||||
GL_PIXEL_UNPACK_BUFFER,
|
||||
};
|
||||
for (auto const target : bufferTargets) {
|
||||
glBindBuffer(target, 0);
|
||||
}
|
||||
|
||||
for (size_t bufferIndex = 0; bufferIndex < MAX_BUFFER_BINDINGS; ++bufferIndex) {
|
||||
if (bufferIndex < (size_t)gets.max_uniform_buffer_bindings) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, bufferIndex, 0);
|
||||
}
|
||||
|
||||
for (size_t bufferIndex = 0; bufferIndex < MAX_BUFFER_BINDINGS; ++bufferIndex) {
|
||||
if (bufferIndex < (size_t)gets.max_uniform_buffer_bindings) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, bufferIndex, 0);
|
||||
}
|
||||
|
||||
if (bufferIndex < (size_t)gets.max_transform_feedback_separate_attribs) {
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, bufferIndex, 0);
|
||||
}
|
||||
if (bufferIndex < (size_t)gets.max_transform_feedback_separate_attribs) {
|
||||
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, bufferIndex, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// state.textures
|
||||
@@ -831,11 +679,7 @@ void OpenGLContext::resetState() noexcept {
|
||||
};
|
||||
for (GLint unit = 0; unit < gets.max_combined_texture_image_units; ++unit) {
|
||||
glActiveTexture(GL_TEXTURE0 + unit);
|
||||
if (state.major > 2) {
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
glBindSampler(unit, 0);
|
||||
#endif
|
||||
}
|
||||
glBindSampler(unit, 0);
|
||||
for (auto [target, available] : textureTargets) {
|
||||
if (available) {
|
||||
glBindTexture(target, 0);
|
||||
@@ -846,20 +690,11 @@ void OpenGLContext::resetState() noexcept {
|
||||
|
||||
// state.unpack
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, state.unpack.alignment);
|
||||
if (state.major > 2) {
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, state.unpack.row_length);
|
||||
#endif
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, state.unpack.row_length);
|
||||
|
||||
// state.pack
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, state.pack.alignment);
|
||||
if (state.major > 2) {
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0); // we rely on GL_PACK_ROW_LENGTH being zero
|
||||
#endif
|
||||
}
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0); // we rely on GL_PACK_ROW_LENGTH being zero
|
||||
|
||||
// state.window
|
||||
glScissor(
|
||||
@@ -879,50 +714,20 @@ void OpenGLContext::resetState() noexcept {
|
||||
}
|
||||
|
||||
OpenGLContext::FenceSync OpenGLContext::createFenceSync(
|
||||
OpenGLPlatform& platform) noexcept {
|
||||
|
||||
if (UTILS_UNLIKELY(isES2())) {
|
||||
assert_invariant(platform.canCreateFence());
|
||||
return { .fence = platform.createFence() };
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
OpenGLPlatform&) noexcept {
|
||||
auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
return { .sync = sync };
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLContext::destroyFenceSync(
|
||||
OpenGLPlatform& platform, FenceSync sync) noexcept {
|
||||
|
||||
if (UTILS_UNLIKELY(isES2())) {
|
||||
platform.destroyFence(static_cast<Platform::Fence*>(sync.fence));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
OpenGLPlatform&, FenceSync sync) noexcept {
|
||||
glDeleteSync(sync.sync);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
OpenGLContext::FenceSync::Status OpenGLContext::clientWaitSync(
|
||||
OpenGLPlatform& platform, FenceSync sync) const noexcept {
|
||||
|
||||
if (UTILS_UNLIKELY(isES2())) {
|
||||
using Status = OpenGLContext::FenceSync::Status;
|
||||
auto const status = platform.waitFence(static_cast<Platform::Fence*>(sync.fence), 0u);
|
||||
switch (status) {
|
||||
case FenceStatus::ERROR: return Status::FAILURE;
|
||||
case FenceStatus::CONDITION_SATISFIED: return Status::CONDITION_SATISFIED;
|
||||
case FenceStatus::TIMEOUT_EXPIRED: return Status ::TIMEOUT_EXPIRED;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
OpenGLPlatform&, FenceSync sync) const noexcept {
|
||||
GLenum const status = glClientWaitSync(sync.sync, 0, 0u);
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
using Status = OpenGLContext::FenceSync::Status;
|
||||
@@ -932,9 +737,6 @@ OpenGLContext::FenceSync::Status OpenGLContext::clientWaitSync(
|
||||
case GL_CONDITION_SATISFIED: return Status::CONDITION_SATISFIED;
|
||||
default: return Status::FAILURE;
|
||||
}
|
||||
#else
|
||||
return FenceSync::Status::FAILURE;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namesapce filament
|
||||
|
||||
@@ -38,7 +38,7 @@ class OpenGLPlatform;
|
||||
class OpenGLContext {
|
||||
public:
|
||||
static constexpr const size_t MAX_TEXTURE_UNIT_COUNT = MAX_SAMPLER_COUNT;
|
||||
static constexpr const size_t DUMMY_TEXTURE_BINDING = 7; // highest binding guaranteed to work with ES2
|
||||
static constexpr const size_t DUMMY_TEXTURE_BINDING = 31; // highest binding less than 32
|
||||
static constexpr const size_t MAX_BUFFER_BINDINGS = 32;
|
||||
typedef math::details::TVec4<GLint> vec4gli;
|
||||
typedef math::details::TVec2<GLclampf> vec2glf;
|
||||
@@ -69,32 +69,20 @@ public:
|
||||
|
||||
OpenGLContext() noexcept;
|
||||
|
||||
template<int MAJOR, int MINOR>
|
||||
inline bool isAtLeastGL() const noexcept {
|
||||
constexpr bool isAtLeastGL(int major, int minor) const noexcept {
|
||||
#ifdef BACKEND_OPENGL_VERSION_GL
|
||||
return state.major > MAJOR || (state.major == MAJOR && state.minor >= MINOR);
|
||||
return state.major > major || (state.major == major && state.minor >= minor);
|
||||
#else
|
||||
(void)major, (void)minor;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
template<int MAJOR, int MINOR>
|
||||
inline bool isAtLeastGLES() const noexcept {
|
||||
constexpr bool isAtLeastGLES(int major, int minor) const noexcept {
|
||||
#ifdef BACKEND_OPENGL_VERSION_GLES
|
||||
return state.major > MAJOR || (state.major == MAJOR && state.minor >= MINOR);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool isES2() const noexcept {
|
||||
#if defined(BACKEND_OPENGL_VERSION_GLES) && !defined(IOS)
|
||||
# ifndef BACKEND_OPENGL_LEVEL_GLES30
|
||||
return true;
|
||||
# else
|
||||
return state.major == 2;
|
||||
# endif
|
||||
return state.major > major || (state.major == major && state.minor >= minor);
|
||||
#else
|
||||
(void)major, (void)minor;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -198,7 +186,6 @@ public:
|
||||
bool EXT_color_buffer_half_float;
|
||||
bool EXT_debug_marker;
|
||||
bool EXT_disjoint_timer_query;
|
||||
bool EXT_discard_framebuffer;
|
||||
bool EXT_multisampled_render_to_texture2;
|
||||
bool EXT_multisampled_render_to_texture;
|
||||
bool EXT_shader_framebuffer_fetch;
|
||||
@@ -214,14 +201,7 @@ public:
|
||||
bool KHR_debug;
|
||||
bool KHR_texture_compression_astc_hdr;
|
||||
bool KHR_texture_compression_astc_ldr;
|
||||
bool OES_depth_texture;
|
||||
bool OES_depth24;
|
||||
bool OES_packed_depth_stencil;
|
||||
bool OES_EGL_image_external_essl3;
|
||||
bool OES_rgb8_rgba8;
|
||||
bool OES_standard_derivatives;
|
||||
bool OES_texture_npot;
|
||||
bool OES_vertex_array_object;
|
||||
bool WEBGL_compressed_texture_etc;
|
||||
bool WEBGL_compressed_texture_s3tc;
|
||||
bool WEBGL_compressed_texture_s3tc_srgb;
|
||||
@@ -401,21 +381,6 @@ public:
|
||||
} window;
|
||||
} state;
|
||||
|
||||
struct {
|
||||
void (* bindVertexArray)(GLuint array);
|
||||
void (* deleteVertexArrays)(GLsizei n, const GLuint* arrays);
|
||||
void (* genVertexArrays)(GLsizei n, GLuint* arrays);
|
||||
|
||||
void (* genQueries)(GLsizei n, GLuint* ids);
|
||||
void (* deleteQueries)(GLsizei n, const GLuint* ids);
|
||||
void (* beginQuery)(GLenum target, GLuint id);
|
||||
void (* endQuery)(GLenum target);
|
||||
void (* getQueryObjectuiv)(GLuint id, GLenum pname, GLuint* params);
|
||||
void (* getQueryObjectui64v)(GLuint id, GLenum pname, GLuint64* params);
|
||||
|
||||
void (* invalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
|
||||
} procs{};
|
||||
|
||||
private:
|
||||
ShaderModel mShaderModel = ShaderModel::MOBILE;
|
||||
FeatureLevel mFeatureLevel = FeatureLevel::FEATURE_LEVEL_1;
|
||||
@@ -534,19 +499,15 @@ constexpr size_t OpenGLContext::getIndexForBufferTarget(GLenum target) noexcept
|
||||
size_t index = 0;
|
||||
switch (target) {
|
||||
// The indexed buffers MUST be first in this list (those usable with bindBufferRange)
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
case GL_UNIFORM_BUFFER: index = 0; break;
|
||||
case GL_TRANSFORM_FEEDBACK_BUFFER: index = 1; break;
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
|
||||
case GL_SHADER_STORAGE_BUFFER: index = 2; break;
|
||||
#endif
|
||||
#endif
|
||||
case GL_ARRAY_BUFFER: index = 3; break;
|
||||
case GL_ELEMENT_ARRAY_BUFFER: index = 4; break;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
case GL_PIXEL_PACK_BUFFER: index = 5; break;
|
||||
case GL_PIXEL_UNPACK_BUFFER: index = 6; break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
assert_invariant(index < sizeof(state.buffers.genericBinding)/sizeof(state.buffers.genericBinding[0])); // NOLINT(misc-redundant-expression)
|
||||
@@ -564,12 +525,9 @@ void OpenGLContext::activeTexture(GLuint unit) noexcept {
|
||||
|
||||
void OpenGLContext::bindSampler(GLuint unit, GLuint sampler) noexcept {
|
||||
assert_invariant(unit < MAX_TEXTURE_UNIT_COUNT);
|
||||
assert_invariant(state.major > 2);
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
update_state(state.textures.units[unit].sampler, sampler, [&]() {
|
||||
glBindSampler(unit, sampler);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLContext::setScissor(GLint left, GLint bottom, GLsizei width, GLsizei height) noexcept {
|
||||
@@ -596,7 +554,7 @@ void OpenGLContext::depthRange(GLclampf near, GLclampf far) noexcept {
|
||||
void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept {
|
||||
RenderPrimitive* vao = p ? const_cast<RenderPrimitive *>(p) : &mDefaultVAO;
|
||||
update_state(state.vao.p, vao, [&]() {
|
||||
procs.bindVertexArray(vao->vao);
|
||||
glBindVertexArray(vao->vao);
|
||||
// update GL_ELEMENT_ARRAY_BUFFER, which is updated by glBindVertexArray
|
||||
size_t const targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
|
||||
state.buffers.genericBinding[targetIndex] = vao->elementArray;
|
||||
@@ -610,22 +568,12 @@ void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept {
|
||||
|
||||
void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer,
|
||||
GLintptr offset, GLsizeiptr size) noexcept {
|
||||
assert_invariant(state.major > 2);
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
# ifdef BACKEND_OPENGL_LEVEL_GLES31
|
||||
assert_invariant(false
|
||||
|| target == GL_UNIFORM_BUFFER
|
||||
|| target == GL_TRANSFORM_FEEDBACK_BUFFER
|
||||
|| target == GL_SHADER_STORAGE_BUFFER);
|
||||
# else
|
||||
assert_invariant(false
|
||||
|| target == GL_UNIFORM_BUFFER
|
||||
|| target == GL_TRANSFORM_FEEDBACK_BUFFER);
|
||||
# endif
|
||||
size_t const targetIndex = getIndexForBufferTarget(target);
|
||||
// this ALSO sets the generic binding
|
||||
|
||||
// validity check
|
||||
assert_invariant(targetIndex < sizeof(state.buffers.targets) / sizeof(*state.buffers.targets));
|
||||
|
||||
// this ALSO sets the generic binding
|
||||
if ( state.buffers.targets[targetIndex].buffers[index].name != buffer
|
||||
|| state.buffers.targets[targetIndex].buffers[index].offset != offset
|
||||
|| state.buffers.targets[targetIndex].buffers[index].size != size) {
|
||||
@@ -635,7 +583,6 @@ void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer,
|
||||
state.buffers.genericBinding[targetIndex] = buffer;
|
||||
glBindBufferRange(target, index, buffer, offset, size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
|
||||
@@ -646,7 +593,6 @@ void OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
|
||||
glBindFramebuffer(target, buffer);
|
||||
}
|
||||
break;
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
case GL_DRAW_FRAMEBUFFER:
|
||||
if (state.draw_fbo != buffer) {
|
||||
state.draw_fbo = buffer;
|
||||
@@ -659,7 +605,6 @@ void OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
|
||||
glBindFramebuffer(target, buffer);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user