Compare commits
83 Commits
sceneform-
...
sceneform-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad4c4148f4 | ||
|
|
a35762bdf2 | ||
|
|
1ca2b1b642 | ||
|
|
373e519292 | ||
|
|
acea32aae8 | ||
|
|
150fd321bc | ||
|
|
1bbe203a15 | ||
|
|
37201e742f | ||
|
|
ba8adc2d49 | ||
|
|
d3efbd810e | ||
|
|
91c946cfbd | ||
|
|
98d39b7e7e | ||
|
|
e7169cb889 | ||
|
|
8f70f8f879 | ||
|
|
8c6ac11c2d | ||
|
|
d9bebaa8e7 | ||
|
|
5baa699c7c | ||
|
|
8c8cfb6528 | ||
|
|
f1c6acafff | ||
|
|
03161226f2 | ||
|
|
4d0859b266 | ||
|
|
896c85c324 | ||
|
|
49f1464016 | ||
|
|
c8b3544a36 | ||
|
|
321845d04a | ||
|
|
a31928600e | ||
|
|
f3752a42c8 | ||
|
|
2f35f26148 | ||
|
|
d47e6f9456 | ||
|
|
6bb385f354 | ||
|
|
dd7af66516 | ||
|
|
04f3268961 | ||
|
|
a3c939894c | ||
|
|
b460d2f547 | ||
|
|
9ea81bc2fd | ||
|
|
cebc83e8fa | ||
|
|
b3cd6a7f59 | ||
|
|
c8f5190099 | ||
|
|
28ab087f79 | ||
|
|
e66aeb0c94 | ||
|
|
749817b64b | ||
|
|
1b18724b6b | ||
|
|
ff5a2a7a99 | ||
|
|
125f79e5e0 | ||
|
|
fac084dfdf | ||
|
|
f8ebc047e0 | ||
|
|
00f6fa24f7 | ||
|
|
0394aeb23b | ||
|
|
c4989da047 | ||
|
|
60363e518d | ||
|
|
2a74397101 | ||
|
|
0cccbda9b9 | ||
|
|
0c1fdc88ec | ||
|
|
8228deb209 | ||
|
|
8029ad5cc3 | ||
|
|
045274bbdb | ||
|
|
206512add0 | ||
|
|
f876171239 | ||
|
|
f96501215b | ||
|
|
0158e7e858 | ||
|
|
c6444fb502 | ||
|
|
60d304a83b | ||
|
|
422bf8631b | ||
|
|
013d735242 | ||
|
|
3be10d816a | ||
|
|
9ce88e6e23 | ||
|
|
83c40e6664 | ||
|
|
28f2806beb | ||
|
|
d37e21f4ea | ||
|
|
d113af8afb | ||
|
|
f676d3d3ea | ||
|
|
cd2786a2ef | ||
|
|
5ea35ab87e | ||
|
|
c21d11e20f | ||
|
|
8fe11a067d | ||
|
|
67ffa91843 | ||
|
|
55fbb300ca | ||
|
|
4901f6f72a | ||
|
|
cfb9c03226 | ||
|
|
d6de2bf426 | ||
|
|
b5eb00bdb1 | ||
|
|
ede9f7fdbb | ||
|
|
eaf790aaa7 |
@@ -169,7 +169,10 @@ endif()
|
||||
# -fsanitize=undefined causes extremely long link times
|
||||
# -fsanitize=address causes a crash with assimp, which we can't explain for now
|
||||
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
# clang-cl.exe on Windows does not support -fstack-protector.
|
||||
if (NOT CLANG_CL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -288,19 +291,18 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
|
||||
${ARCHIVE_DIR}/${ARCHIVE_NAME}.apple.S
|
||||
${ARCHIVE_DIR}/${ARCHIVE_NAME}.h
|
||||
)
|
||||
if (NOT WIN32)
|
||||
set(ASM_ARCH_FLAG "-arch ${DIST_ARCH}")
|
||||
endif()
|
||||
set(ASM_ARCH_FLAG "-arch ${DIST_ARCH}")
|
||||
if (APPLE)
|
||||
set(ASM_SUFFIX ".apple")
|
||||
endif()
|
||||
if (WEBGL)
|
||||
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
|
||||
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
|
||||
# Visual Studio makes it difficult to use assembly without using MASM. MASM doesn't support
|
||||
# the equivalent of .incbin, so on Windows we'll just tell resgen to output a C file.
|
||||
if (WEBGL OR WIN32)
|
||||
set(RESGEN_OUTPUTS "${OUTPUTS};${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
|
||||
set(RESGEN_FLAGS -cx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
|
||||
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
|
||||
else()
|
||||
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
|
||||
set(RESGEN_OUTPUTS "${OUTPUTS}" PARENT_SCOPE)
|
||||
set(RESGEN_FLAGS -x ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
|
||||
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}${ASM_SUFFIX}.S" PARENT_SCOPE)
|
||||
@@ -311,17 +313,10 @@ endfunction()
|
||||
# ==================================================================================================
|
||||
# Sub-projects
|
||||
# ==================================================================================================
|
||||
# spirv-tools must come before filamat, as filamat relies on the presence of the
|
||||
# spirv-tools_SOURCE_DIR variable.
|
||||
add_subdirectory(${EXTERNAL}/spirv-tools)
|
||||
add_subdirectory(${EXTERNAL}/glslang/tnt)
|
||||
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
|
||||
|
||||
# Common to all platforms
|
||||
add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filamat)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
@@ -354,13 +349,20 @@ if (WEBGL)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
# spirv-tools must come before filamat, as filamat relies on the presence of the
|
||||
# spirv-tools_SOURCE_DIR variable.
|
||||
add_subdirectory(${EXTERNAL}/spirv-tools)
|
||||
add_subdirectory(${EXTERNAL}/glslang/tnt)
|
||||
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
|
||||
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
add_subdirectory(${LIBRARIES}/filamat)
|
||||
add_subdirectory(${LIBRARIES}/imageio)
|
||||
|
||||
add_subdirectory(${FILAMENT}/java)
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
@@ -375,6 +377,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
|
||||
add_subdirectory(${TOOLS}/cmgen)
|
||||
add_subdirectory(${TOOLS}/filamesh)
|
||||
add_subdirectory(${TOOLS}/glslminifier)
|
||||
add_subdirectory(${TOOLS}/matc)
|
||||
add_subdirectory(${TOOLS}/matinfo)
|
||||
add_subdirectory(${TOOLS}/mipgen)
|
||||
@@ -387,5 +390,5 @@ endif()
|
||||
|
||||
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
export(TARGETS matc cmgen filamesh mipgen resgen FILE ${IMPORT_EXECUTABLES})
|
||||
export(TARGETS matc cmgen filamesh mipgen resgen glslminifier FILE ${IMPORT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
37
README.md
@@ -18,6 +18,9 @@ Android devices and as the renderer inside the Android Studio plugin.
|
||||
|
||||
[Download Filament releases](https://github.com/google/filament/releases) to access stable builds.
|
||||
|
||||
Make sure you always use tools from the same release as the runtime library. This is particularly
|
||||
important for `matc` (material compiler).
|
||||
|
||||
If you prefer to live on the edge, you can download a continuous build by clicking one of the build
|
||||
badges above.
|
||||
|
||||
@@ -102,6 +105,7 @@ and tools.
|
||||
|
||||
- `android`: Android libraries and projects
|
||||
- `build`: Custom Gradle tasks for Android builds
|
||||
- `filamat-android`: Filament material generation library (AAR) for Android
|
||||
- `filament-android`: Filament library (AAR) for Android
|
||||
- `samples`: Android-specific Filament samples
|
||||
- `art`: Source for various artworks (logos, PDF manuals, etc.)
|
||||
@@ -133,6 +137,7 @@ and tools.
|
||||
- `tools`: Host tools
|
||||
- `cmgen`: Image-based lighting asset generator
|
||||
- `filamesh`: Mesh converter
|
||||
- `glslminifier`: Minifies GLSL source code
|
||||
- `matc`: Material compiler
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image
|
||||
@@ -162,7 +167,7 @@ section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 3.1
|
||||
- Android Studio 3.3
|
||||
- Android SDK
|
||||
- Android NDK
|
||||
|
||||
@@ -327,14 +332,21 @@ Google employees require additional steps which can be found here [go/filawin](h
|
||||
Install the following components:
|
||||
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Visual Studio 2015](https://www.visualstudio.com/downloads)
|
||||
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
|
||||
- [Clang 6](http://releases.llvm.org/download.html)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [Git 2.16.1 or later](https://github.com/git-for-windows/git/releases/download/v2.16.1.windows.4/PortableGit-2.16.1.4-64-bit.7z.exe)
|
||||
- [Cmake 3.11 or later](https://cmake.org/files/v3.11/cmake-3.11.0-rc1-win64-x64.msi)
|
||||
|
||||
Open an VS2015 x64 Native Tools terminal (click the start button, type "x64 native tools" and
|
||||
select: "VS2015 x64 Native Tools Command Prompt").
|
||||
If you're using Visual Studio 2017, you'll also need to install the [LLVM Compiler
|
||||
Toolchain](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain)
|
||||
extension.
|
||||
|
||||
Open an appropriate Native Tools terminal for the version of Visual Studio you are using:
|
||||
- VS 2015: VS2015 x64 Native Tools Command Prompt
|
||||
- VS 2017: x64 Native Tools Command Prompt for VS 2017
|
||||
|
||||
You can find these by clicking the start button and typing "x64 native tools".
|
||||
|
||||
Create a working directory:
|
||||
```
|
||||
@@ -344,11 +356,20 @@ Create a working directory:
|
||||
|
||||
Create the msBuild project:
|
||||
```
|
||||
# Visual Studio 2015:
|
||||
> cmake -T"LLVM-vs2014" -G "Visual Studio 14 2015 Win64" ../..
|
||||
|
||||
# Visual Studio 2017
|
||||
> cmake ..\.. -T"LLVM" -G "Visual Studio 15 2017 Win64" ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe"
|
||||
```
|
||||
|
||||
Check out the output and make sure Clang for Windows frontend was found. You should see a line
|
||||
showing the following output.
|
||||
showing the following output. Note that for Visual Studio 2017 this line may list Microsoft's
|
||||
compiler, but the build will still in fact use Clang and you can proceed.
|
||||
|
||||
```
|
||||
Clang:C:/Program Files/LLVM/msbuild-bin/cl.exe
|
||||
```
|
||||
@@ -379,11 +400,11 @@ Alternatively, you can use [Ninja](https://ninja-build.org/) to build for Window
|
||||
installation is still necessary.
|
||||
|
||||
First, install the dependencies listed under [Windows](#Windows) as well as Ninja. Then open up a
|
||||
VS2015 x64 Native Tools terminal as before. Create a build directory inside Filament and run the
|
||||
Native Tools terminal as before. Create a build directory inside Filament and run the
|
||||
following CMake command:
|
||||
|
||||
```
|
||||
cmake .. -G Ninja ^
|
||||
> cmake .. -G Ninja ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
|
||||
@@ -426,6 +447,8 @@ Filament can be built for the following architectures:
|
||||
Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
|
||||
foremost for `arm64-v8a`.
|
||||
|
||||
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
|
||||
|
||||
#### Easy Android build
|
||||
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
|
||||
160
android/Windows.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# Building Filament for Android on Windows
|
||||
|
||||
## Prerequisites
|
||||
|
||||
In addition to the requirements for [building Filament on Windows](../README.md#windows), you'll
|
||||
need the Android SDK and NDK. See [Getting Started with the
|
||||
NDK](https://developer.android.com/ndk/guides/) for detailed installation instructions.
|
||||
|
||||
Ensure the `%ANDROID_HOME%` environment variable is set to your Android SDK installation location.
|
||||
|
||||
All of the following commands should be executed in a Visual Studio x64 Native Tools Command Prompt.
|
||||
|
||||
## Desktop Tools
|
||||
|
||||
First, a few Filament tools need to be compiled for desktop.
|
||||
|
||||
1. From Filament's root directory, create a desktop build directory and run CMake.
|
||||
|
||||
```
|
||||
mkdir out\cmake-release
|
||||
cd out\cmake-release
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="C:\Program Files\LLVM\bin\clang-cl.exe" ^
|
||||
-DCMAKE_LINKER:PATH="C:\Program Files\LLVM\bin\lld-link.exe" ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\release\filament ^
|
||||
-DENABLE_JAVA=NO ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
..\..
|
||||
```
|
||||
|
||||
2. Build the required desktop host tools.
|
||||
|
||||
```
|
||||
ninja matc resgen cmgen
|
||||
```
|
||||
|
||||
The build should succeed and a `ImportExecutables-Release.cmake` file should automatically be
|
||||
created at Filament's root directory.
|
||||
|
||||
## Toolchains
|
||||
|
||||
Generate a toolchain for each Android architecture you're interested in building for.
|
||||
|
||||
From Filament's root directory, run the NDK `make_standalone_toolchain.py` script for each
|
||||
architecture.
|
||||
|
||||
```
|
||||
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
|
||||
--arch arm64 ^
|
||||
--api 21 ^
|
||||
--stl libc++ ^
|
||||
--force ^
|
||||
--install-dir "toolchains/Windows/aarch64-linux-android-4.9"
|
||||
|
||||
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
|
||||
--arch arm ^
|
||||
--api 21 ^
|
||||
--stl libc++ ^
|
||||
--force ^
|
||||
--install-dir "toolchains/Windows/arm-linux-android-4.9"
|
||||
|
||||
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
|
||||
--arch x86_64 ^
|
||||
--api 21 ^
|
||||
--stl libc++ ^
|
||||
--force ^
|
||||
--install-dir "toolchains/Windows/x86_64-linux-android-4.9"
|
||||
|
||||
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
|
||||
--arch x86 ^
|
||||
--api 21 ^
|
||||
--stl libc++ ^
|
||||
--force ^
|
||||
--install-dir "toolchains/Windows/x86-linux-android-4.9"
|
||||
````
|
||||
|
||||
## Build
|
||||
|
||||
1. Create the build directories.
|
||||
|
||||
```
|
||||
mkdir out\cmake-android-release-aarch64
|
||||
mkdir out\cmake-android-release-arm7
|
||||
mkdir out\cmake-android-release-x86_64
|
||||
mkdir out\cmake-android-release-x86
|
||||
```
|
||||
|
||||
2. Run CMake for each architecture.
|
||||
|
||||
```
|
||||
cd out\cmake-android-release-aarch64
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-aarch64-linux-android.cmake ^
|
||||
..\..
|
||||
|
||||
cd out\cmake-android-release-arm7
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-arm7-linux-android.cmake ^
|
||||
..\..
|
||||
|
||||
cd out\cmake-android-release-x86_64
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-x86_64-linux-android.cmake ^
|
||||
..\..
|
||||
|
||||
cd out\cmake-android-release-x86
|
||||
cmake ^
|
||||
-G Ninja ^
|
||||
-DCMAKE_BUILD_TYPE=Release ^
|
||||
-DCMAKE_INSTALL_PREFIX=..\android-release\filament ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=..\..\build\toolchain-x86-linux-android.cmake ^
|
||||
..\..
|
||||
```
|
||||
|
||||
3. Build.
|
||||
|
||||
Inside of each build directory, run:
|
||||
|
||||
```
|
||||
ninja install
|
||||
```
|
||||
|
||||
## Generate AAR
|
||||
|
||||
The Gradle project used to generate the AAR is located at `<filament>\android\filament-android`.
|
||||
|
||||
```
|
||||
cd android\filament-android
|
||||
gradlew -Pfilament_dist_dir=..\..\out\android-release\filament assembleRelease
|
||||
copy build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
```
|
||||
|
||||
If you're only interested in building for a single ABI, you'll need to add an `abiFilters` override
|
||||
inside the `build.gradle` file underneath `defaultConfig`:
|
||||
|
||||
```
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
```
|
||||
|
||||
See
|
||||
[NdkOptions](https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.NdkOptions.html#com.android.build.gradle.internal.dsl.NdkOptions:abiFilters)
|
||||
for more information.
|
||||
|
||||
`filament-android-release.aar` should now be present at `<filament>\out\filament-android-release.aar`.
|
||||
|
||||
See [Using Filament's AAR](../README.md#using-filaments-aar) for usage instructions.
|
||||
|
||||
@@ -96,7 +96,7 @@ class MaterialCompiler extends DefaultTask {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${matcPath}"
|
||||
args('-p', 'mobile', '-o', getOutputFile(file), file)
|
||||
args('-a', 'all', '-p', 'mobile', '-o', getOutputFile(file), file)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
android/filamat-android/.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
78
android/filamat-android/build.gradle
Normal file
@@ -0,0 +1,78 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../../dist-android-release assembleRelease
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
group = "com.google.android.filament"
|
||||
version = "0.1"
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
def filament_path = file("../../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filament_path = file("$filament_dist_dir").absolutePath
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jniLibs.srcDirs "${filament_path}/lib"
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that only the libfilamat-jni.so library is included in the AAR, in case any other
|
||||
// libraries happen to be present.
|
||||
packagingOptions {
|
||||
exclude '**/*.so'
|
||||
merge '**/libfilamat-jni.so'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.android.support:support-annotations:28.0.0'
|
||||
}
|
||||
|
||||
BIN
android/filamat-android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
android/filamat-android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
172
android/filamat-android/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
android/filamat-android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
10
android/filamat-android/settings.gradle
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user guide at https://docs.gradle.org/4.6/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
rootProject.name = 'filamat-android'
|
||||
2
android/filamat-android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.filament.filamat" />
|
||||
121
android/filamat-android/src/main/cpp/MaterialBuilder.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filamat/MaterialBuilder.h>
|
||||
|
||||
#include <filament/EngineEnums.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace filamat;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nCreateMaterialBuilder(JNIEnv *env,
|
||||
jclass type) {
|
||||
return (jlong) new MaterialBuilder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyMaterialBuilder(JNIEnv *env,
|
||||
jclass type, jlong nativeBuilder) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nBuilderBuild(JNIEnv* env, jclass type,
|
||||
jlong nativeBuilder) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
return (jlong) new Package(builder->build());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jbyteArray JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nGetPackageBytes(JNIEnv* env, jclass type,
|
||||
jlong nativePackage) {
|
||||
auto package = (Package*) nativePackage;
|
||||
auto size = jsize(package->getSize());
|
||||
jbyteArray ret = env->NewByteArray(size);
|
||||
auto data = (jbyte*) package->getData();
|
||||
env->SetByteArrayRegion(ret, 0, size, data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nGetPackageIsValid(JNIEnv* env,
|
||||
jclass type, jlong nativePackage) {
|
||||
auto* package = (Package*) nativePackage;
|
||||
return jboolean(package->isValid());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyPackage(JNIEnv* env, jclass type,
|
||||
jlong nativePackage) {
|
||||
Package* package = (Package*) nativePackage;
|
||||
delete package;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderName(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jstring name_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* name = env->GetStringUTFChars(name_, nullptr);
|
||||
builder->name(name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShading(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint shading) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->shading((Shading) shading);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRequire(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint attribute) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->require((VertexAttribute) attribute);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterial(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jstring code_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* code = env->GetStringUTFChars(code_, nullptr);
|
||||
builder->material(code);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterialVertex(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jstring code_) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
const char* code = env->GetStringUTFChars(code_, nullptr);
|
||||
builder->materialVertex(code);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWrite(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jboolean enable) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->colorWrite(enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderPlatform(JNIEnv* env,
|
||||
jclass type, jlong nativeBuilder, jint platform) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->platform((MaterialBuilder::Platform) platform);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialBuilder {
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeObject;
|
||||
|
||||
public enum VertexAttribute {
|
||||
POSITION, // XYZ position (float3)
|
||||
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
|
||||
COLOR, // vertex color (float4)
|
||||
UV0, // texture coordinates (float2)
|
||||
UV1, // texture coordinates (float2)
|
||||
BONE_INDICES, // indices of 4 bones (uvec4)
|
||||
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
|
||||
}
|
||||
|
||||
public enum Shading {
|
||||
UNLIT, // no lighting applied, emissive possible
|
||||
LIT, // default, standard lighting
|
||||
SUBSURFACE, // subsurface lighting model
|
||||
CLOTH // cloth lighting model
|
||||
}
|
||||
|
||||
public enum Platform {
|
||||
DESKTOP,
|
||||
MOBILE,
|
||||
ALL
|
||||
}
|
||||
|
||||
public MaterialBuilder() {
|
||||
mNativeObject = nCreateMaterialBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeObject);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder name(@NonNull String name) {
|
||||
nMaterialBuilderName(mNativeObject, name);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder shading(@NonNull Shading shading) {
|
||||
nMaterialBuilderShading(mNativeObject, shading.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder require(@NonNull VertexAttribute attribute) {
|
||||
nMaterialBuilderRequire(mNativeObject, attribute.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder material(@NonNull String code) {
|
||||
nMaterialBuilderMaterial(mNativeObject, code);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder materialVertex(@NonNull String code) {
|
||||
nMaterialBuilderMaterialVertex(mNativeObject, code);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder colorWrite(boolean enable) {
|
||||
nMaterialBuilderColorWrite(mNativeObject, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder platform(@NonNull Platform platform) {
|
||||
nMaterialBuilderPlatform(mNativeObject, platform.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialPackage build() {
|
||||
long nativePackage = nBuilderBuild(mNativeObject);
|
||||
byte[] data = nGetPackageBytes(nativePackage);
|
||||
MaterialPackage result =
|
||||
new MaterialPackage(ByteBuffer.wrap(data), nGetPackageIsValid(nativePackage));
|
||||
nDestroyPackage(nativePackage);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class BuilderFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
BuilderFinalizer(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyMaterialBuilder(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native long nCreateMaterialBuilder();
|
||||
private static native void nDestroyMaterialBuilder(long nativeBuilder);
|
||||
|
||||
private static native long nBuilderBuild(long nativeBuilder);
|
||||
private static native byte[] nGetPackageBytes(long nativePackage);
|
||||
private static native boolean nGetPackageIsValid(long nativePackage);
|
||||
private static native void nDestroyPackage(long nativePackage);
|
||||
|
||||
private static native void nMaterialBuilderName(long nativeBuilder, String name);
|
||||
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
|
||||
private static native void nMaterialBuilderRequire(long nativeBuilder, int attribute);
|
||||
private static native void nMaterialBuilderMaterial(long nativeBuilder, String code);
|
||||
private static native void nMaterialBuilderMaterialVertex(long nativeBuilder, String code);
|
||||
private static native void nMaterialBuilderColorWrite(long nativeBuilder, boolean enable);
|
||||
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialPackage {
|
||||
|
||||
private final ByteBuffer mBuffer;
|
||||
private final boolean mIsValid;
|
||||
|
||||
MaterialPackage(@NonNull ByteBuffer buffer, boolean isValid) {
|
||||
mBuffer = buffer;
|
||||
mIsValid = isValid;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ByteBuffer getBuffer() {
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return mIsValid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:04:36 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
@@ -22,9 +22,9 @@ using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateEngine(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_Engine_nCreateEngine(JNIEnv*, jclass, jlong backend,
|
||||
jlong sharedContext) {
|
||||
return (jlong) Engine::create(Engine::Backend::OPENGL, nullptr, (void*) sharedContext);
|
||||
return (jlong) Engine::create((Engine::Backend) backend, nullptr, (void*) sharedContext);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -65,9 +65,9 @@ Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jcl
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jint attribute) {
|
||||
jlong nativeBuilder, jint attribute, jboolean normalized) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
builder->normalized((VertexAttribute) attribute);
|
||||
builder->normalized((VertexAttribute) attribute, normalized);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
|
||||
@@ -24,6 +24,13 @@ public class Engine {
|
||||
@NonNull private final LightManager mLightManager;
|
||||
@NonNull private final RenderableManager mRenderableManager;
|
||||
|
||||
public enum Backend {
|
||||
DEFAULT, // Automatically selects an appropriate driver for the platform.
|
||||
OPENGL, // Selects the OpenGL ES driver.
|
||||
VULKAN, // Selects the experimental Vulkan driver.
|
||||
NOOP, // Selects the no-op driver for testing purposes.
|
||||
}
|
||||
|
||||
private Engine(long nativeEngine) {
|
||||
mNativeObject = nativeEngine;
|
||||
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
|
||||
@@ -33,7 +40,14 @@ public class Engine {
|
||||
|
||||
@NonNull
|
||||
public static Engine create() {
|
||||
long nativeEngine = nCreateEngine(0);
|
||||
long nativeEngine = nCreateEngine(0, 0);
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Backend backend) {
|
||||
long nativeEngine = nCreateEngine(backend.ordinal(), 0);
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
}
|
||||
@@ -46,7 +60,7 @@ public class Engine {
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Object sharedContext) {
|
||||
if (Platform.get().validateSharedContext(sharedContext)) {
|
||||
long nativeEngine = nCreateEngine(
|
||||
long nativeEngine = nCreateEngine(0,
|
||||
Platform.get().getSharedContextNativeHandle(sharedContext));
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
@@ -263,7 +277,7 @@ public class Engine {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static native long nCreateEngine(long sharedContext);
|
||||
private static native long nCreateEngine(long backend, long sharedContext);
|
||||
private static native void nDestroyEngine(long nativeEngine);
|
||||
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
|
||||
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
|
||||
|
||||
@@ -108,7 +108,13 @@ public class VertexBuffer {
|
||||
|
||||
@NonNull
|
||||
public Builder normalized(@NonNull VertexAttribute attribute) {
|
||||
nBuilderNormalized(mNativeBuilder, attribute.ordinal());
|
||||
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), true);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder normalized(@NonNull VertexAttribute attribute, boolean enabled) {
|
||||
nBuilderNormalized(mNativeBuilder, attribute.ordinal(), enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -183,7 +189,8 @@ public class VertexBuffer {
|
||||
private static native void nBuilderBufferCount(long nativeBuilder, int bufferCount);
|
||||
private static native void nBuilderAttribute(long nativeBuilder, int attribute,
|
||||
int bufferIndex, int attributeType, int byteOffset, int byteStride);
|
||||
private static native void nBuilderNormalized(long nativeBuilder, int attribute);
|
||||
private static native void nBuilderNormalized(long nativeBuilder, int attribute,
|
||||
boolean normalized);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetVertexCount(long nativeVertexBuffer);
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.SurfaceTexture;
|
||||
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
@@ -27,6 +29,98 @@ import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import com.google.android.filament.SwapChain;
|
||||
|
||||
/**
|
||||
* UiHelper is a simple class that can manage either a SurfaceView or a TextureView so it can
|
||||
* be used to render into with Filament.
|
||||
*
|
||||
* Here is a simple example with a SurfaceView. The code would be exactly the same with a
|
||||
* TextureView:
|
||||
*
|
||||
* <pre>
|
||||
* public class FilamentActivity extends Activity {
|
||||
* private UiHelper mUiHelper;
|
||||
* private SurfaceView mSurfaceView;
|
||||
*
|
||||
* // Filament specific APIs
|
||||
* private Engine mEngine;
|
||||
* private Renderer mRenderer;
|
||||
* private View mView; // com.google.android.filament.View, not android.view.View
|
||||
* private SwapChain mSwapChain;
|
||||
*
|
||||
* public void onCreate(Bundle savedInstanceState) {
|
||||
* super.onCreate(savedInstanceState);
|
||||
*
|
||||
* // Create a SurfaceView and add it to the activity
|
||||
* mSurfaceView = new SurfaceView(this);
|
||||
* setContentView(mSurfaceView);
|
||||
*
|
||||
* // Create the Filament UI helper
|
||||
* mUiHelper = new UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK);
|
||||
*
|
||||
* // Attach the SurfaceView to the helper, you could do the same with a TextureView
|
||||
* mUiHelper.attachTo(surfaceView)
|
||||
*
|
||||
* // Set a rendering callback that we will use to invoke Filament
|
||||
* mUiHelper.setRenderCallback(new UiHelper.RendererCallback() {
|
||||
* public void onNativeWindowChanged(Surface surface) {
|
||||
* if (mSwapChain != null) mEngine.destroySwapChain(mSwapChain);
|
||||
* mSwapChain = mEngine.createSwapChain(surface, mUiHelper.getSwapChainFlags());
|
||||
* }
|
||||
*
|
||||
* // The native surface went away, we must stop rendering.
|
||||
* public void onDetachedFromSurface() {
|
||||
* if (mSwapChain != null) {
|
||||
* mEngine.destroySwapChain(mSwapChain);
|
||||
*
|
||||
* // Required to ensure we don't return before Filament is done executing the
|
||||
* // destroySwapChain command, otherwise Android might destroy the Surface
|
||||
* // too early
|
||||
* mEngine.flushAndWait();
|
||||
*
|
||||
* mSwapChain = null;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // 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) {
|
||||
* // Compute camera projection and set the viewport on the view
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* mEngine = Engine.create();
|
||||
* mRenderer = mEngine.createRenderer();
|
||||
* mView = mEngine.createView();
|
||||
* // Create scene, camera, etc.
|
||||
* }
|
||||
*
|
||||
* public void onDestroy() {
|
||||
* super.onDestroy()
|
||||
* // Always detach the surface before destroying the engine
|
||||
* mUiHelper.detach()
|
||||
*
|
||||
* // This ensures that all the commands we've sent to Filament have
|
||||
* // been processed before we attempt to destroy anything
|
||||
* Fence.waitAndDestroy(mEngine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH);
|
||||
*
|
||||
* mEngine.destroy()
|
||||
* }
|
||||
*
|
||||
* // This is an example of a render function. You will most likely invoke this from
|
||||
* // a Choreographer callback to trigger rendering at vsync.
|
||||
* public void render() {
|
||||
* if (mUiHelper.isReadyToRender) {
|
||||
* // If beginFrame() returns false you should skip the frame
|
||||
* // This means you are sending frames too quickly to the GPU
|
||||
* if (mRenderer.beginFrame(swapChain)) {
|
||||
* mRenderer.render(mView)
|
||||
* mRenderer.endFrame()
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class UiHelper {
|
||||
private static final String LOG_TAG = "UiHelper";
|
||||
private static final boolean LOGGING = false;
|
||||
@@ -42,22 +136,39 @@ public class UiHelper {
|
||||
|
||||
private boolean mOpaque = true;
|
||||
|
||||
/**
|
||||
* Enum used to decide whether UiHelper should perform extra error checking.
|
||||
*
|
||||
* @see UiHelper#UiHelper(ContextErrorPolicy)
|
||||
*/
|
||||
public enum ContextErrorPolicy {
|
||||
CHECK, DONT_CHECK
|
||||
/** Check for extra errors. */
|
||||
CHECK,
|
||||
/** Do not check for extra errors. */
|
||||
DONT_CHECK
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface used to know when the native surface is created, destroyed or resized.
|
||||
*
|
||||
* @see #setRenderCallback(RendererCallback)
|
||||
*/
|
||||
public interface RendererCallback {
|
||||
|
||||
// called when the underlying native window has changed
|
||||
// NOTE: this could be called from UiHelper's constructor.
|
||||
/**
|
||||
* Called when the underlying native window has changed.
|
||||
*/
|
||||
void onNativeWindowChanged(Surface surface);
|
||||
|
||||
// called when the surface is going away. after this call isReadyToRender() returns false.
|
||||
// you MUST have stopped drawing when returning.
|
||||
// This is called from detach() or if the surface disappears on its own.
|
||||
/**
|
||||
* Called when the surface is going away. After this call <code>isReadyToRender()</code>
|
||||
* returns false. You MUST have stopped drawing when returning.
|
||||
* This is called from detach() or if the surface disappears on its own.
|
||||
*/
|
||||
void onDetachedFromSurface();
|
||||
|
||||
// called when the underlying native window has been resized
|
||||
/**
|
||||
* Called when the underlying native window has been resized.
|
||||
*/
|
||||
void onResized(int width, int height);
|
||||
}
|
||||
|
||||
@@ -114,29 +225,44 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a UiHelper which will help manage the EGL context
|
||||
* and EGL surfaces. UiHelper handles SurfaceView and TextureView.
|
||||
*
|
||||
* When this call returns, OpenGL ES is ready to use.
|
||||
* Creates a UiHelper which will help manage the native surface provided by a
|
||||
* SurfaceView or a TextureView.
|
||||
*/
|
||||
public UiHelper() {
|
||||
this(ContextErrorPolicy.CHECK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a UiHelper which will help manage the native surface provided by a
|
||||
* SurfaceView or a TextureView.
|
||||
*
|
||||
* @param policy The error checking policy to use.
|
||||
*/
|
||||
public UiHelper(ContextErrorPolicy policy) {
|
||||
// TODO: do something with policy
|
||||
}
|
||||
|
||||
public void setRenderCallback(RendererCallback renderCallback) {
|
||||
/**
|
||||
* Sets the renderer callback that will be notified when the native surface is
|
||||
* created, destroyed or resized.
|
||||
*
|
||||
* @param renderCallback The callback to register.
|
||||
*/
|
||||
public void setRenderCallback(@Nullable RendererCallback renderCallback) {
|
||||
mRenderCallback = renderCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current render callback associated with this UiHelper.
|
||||
*/
|
||||
@Nullable
|
||||
public RendererCallback getRenderCallback() {
|
||||
return mRenderCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free resources associated to the native window specified in attachTo().
|
||||
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)}
|
||||
* or {@link #attachTo(TextureView)}.
|
||||
*/
|
||||
public void detach() {
|
||||
destroySwapChain();
|
||||
@@ -144,13 +270,6 @@ public class UiHelper {
|
||||
mRenderSurface = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
// TODO: check that detach() has been called
|
||||
// TODO: call Surface.release() if not already done
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether we are ready to render into the attached surface.
|
||||
*
|
||||
@@ -164,7 +283,7 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the render target buffers.
|
||||
* Set the size of the render target buffers of the native surface.
|
||||
*/
|
||||
public void setDesiredSize(int width, int height) {
|
||||
mDesiredWidth = width;
|
||||
@@ -174,10 +293,16 @@ public class UiHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested width for the native surface.
|
||||
*/
|
||||
public int getDesiredWidth() {
|
||||
return mDesiredWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested height for the native surface.
|
||||
*/
|
||||
public int getDesiredHeight() {
|
||||
return mDesiredHeight;
|
||||
}
|
||||
@@ -202,6 +327,11 @@ public class UiHelper {
|
||||
mOpaque = opaque;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags to pass to
|
||||
* {@link com.google.android.filament.Engine#createSwapChain(Object, long)} to honor all
|
||||
* the options set on this UiHelper.
|
||||
*/
|
||||
public long getSwapChainFlags() {
|
||||
return isOpaque() ? SwapChain.CONFIG_DEFAULT : SwapChain.CONFIG_TRANSPARENT;
|
||||
}
|
||||
@@ -212,7 +342,7 @@ public class UiHelper {
|
||||
* As soon as SurfaceView is ready (i.e. has a Surface), we'll create the
|
||||
* EGL resources needed, and call user callbacks if needed.
|
||||
*/
|
||||
public void attachTo(SurfaceView view) {
|
||||
public void attachTo(@NonNull SurfaceView view) {
|
||||
if (attach(view)) {
|
||||
if (!isOpaque()) {
|
||||
view.setZOrderOnTop(true);
|
||||
@@ -261,7 +391,7 @@ public class UiHelper {
|
||||
* As soon as TextureView is ready (i.e. has a buffer), we'll create the
|
||||
* EGL resources needed, and call user callbacks if needed.
|
||||
*/
|
||||
public void attachTo(TextureView view) {
|
||||
public void attachTo(@NonNull TextureView view) {
|
||||
if (attach(view)) {
|
||||
view.setOpaque(isOpaque());
|
||||
|
||||
@@ -274,13 +404,20 @@ public class UiHelper {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
}
|
||||
|
||||
Surface surface = new Surface(surfaceTexture);
|
||||
TextureViewHandler textureViewHandler = (TextureViewHandler) mRenderSurface;
|
||||
textureViewHandler.setSurface(surface);
|
||||
|
||||
createSwapChain(surface);
|
||||
|
||||
// Call this the first time because onSurfaceTextureSizeChanged()
|
||||
// isn't called at initialization time
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -311,7 +448,7 @@ public class UiHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean attach(Object nativeWindow) {
|
||||
private boolean attach(@NonNull Object nativeWindow) {
|
||||
if (mNativeWindow != null) {
|
||||
// we are already attached to a native window
|
||||
if (mNativeWindow == nativeWindow) {
|
||||
@@ -324,8 +461,8 @@ public class UiHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void createSwapChain(Surface sur) {
|
||||
mRenderCallback.onNativeWindowChanged(sur);
|
||||
private void createSwapChain(@NonNull Surface surface) {
|
||||
mRenderCallback.onNativeWindowChanged(surface);
|
||||
mHasSwapChain = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ Demonstrates how to render into a transparent `SurfaceView`:
|
||||
|
||||

|
||||
|
||||
### `texture-view`
|
||||
|
||||
Demonstrates how to render into a `TextureView` instead of a `SurfaceView`:
|
||||
|
||||

|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
|
||||
@@ -66,8 +72,7 @@ SDK. This includes the project `filament-android` in the parent directory.
|
||||
|
||||
## Android Studio
|
||||
|
||||
Due to issues with composite builds in Android Studio 3.1, it is highly recommended to use
|
||||
Android Studio 3.2 or higher to open this project.
|
||||
You must use Android Studio 3.3 or higher to open these projects.
|
||||
|
||||
## Compiling
|
||||
|
||||
|
||||
@@ -18,23 +18,20 @@ package com.google.android.filament.hellotriangle
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.graphics.PixelFormat
|
||||
import android.opengl.Matrix
|
||||
import android.os.Bundle
|
||||
import android.view.Choreographer
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceView
|
||||
import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.nio.channels.Channels
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:09:37 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
@@ -60,7 +60,7 @@ private fun loadIndirectLight(
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine): Pair<IndirectLight, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/nx.rgbm")
|
||||
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
@@ -142,6 +142,7 @@ private fun loadCubemap(texture: Texture,
|
||||
|
||||
// Rewind the texture buffer
|
||||
storage.flip()
|
||||
android.util.Log.d("Texture", "Cubemap level: $level $faceSize ${texture.getWidth(level)}")
|
||||
|
||||
val buffer = Texture.PixelBufferDescriptor(storage, Texture.Format.RGBM, Texture.Type.UBYTE)
|
||||
texture.setImage(engine, level, buffer, offsets)
|
||||
|
||||
@@ -69,12 +69,16 @@ fun loadMesh(assets: AssetManager, name: String,
|
||||
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
|
||||
private const val MAX_UINT32 = 4294967295
|
||||
|
||||
private const val HEADER_FLAG_INTERLEAVED = 0x1L
|
||||
private const val HEADER_FLAG_SNORM16_UV = 0x2L
|
||||
private const val HEADER_FLAG_COMPRESSED = 0x4L
|
||||
|
||||
private class Header {
|
||||
var valid = false
|
||||
var versionNumber = 0L
|
||||
var parts = 0L
|
||||
var aabb = Box()
|
||||
var interleaved = 0L
|
||||
var flags = 0L
|
||||
var posOffset = 0L
|
||||
var positionStride = 0L
|
||||
var tangentOffset = 0L
|
||||
@@ -121,7 +125,7 @@ private fun readHeader(input: InputStream): Header {
|
||||
header.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
header.interleaved = readUIntLE(input)
|
||||
header.flags = readUIntLE(input)
|
||||
header.posOffset = readUIntLE(input)
|
||||
header.positionStride = readUIntLE(input)
|
||||
header.tangentOffset = readUIntLE(input)
|
||||
@@ -142,7 +146,6 @@ private fun readHeader(input: InputStream): Header {
|
||||
return header
|
||||
}
|
||||
|
||||
|
||||
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
|
||||
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
@@ -190,7 +193,15 @@ private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer):
|
||||
.apply { setBuffer(engine, data) }
|
||||
}
|
||||
|
||||
private fun uvNormalized(header: Header) = header.flags and HEADER_FLAG_SNORM16_UV != 0L
|
||||
|
||||
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
|
||||
val uvType = if (!uvNormalized(header)) {
|
||||
HALF2
|
||||
} else {
|
||||
SHORT2
|
||||
}
|
||||
|
||||
val vertexBufferBuilder = VertexBuffer.Builder()
|
||||
.bufferCount(1)
|
||||
.vertexCount(header.totalVertices.toInt())
|
||||
@@ -203,11 +214,18 @@ private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer)
|
||||
.attribute(POSITION, 0, HALF4, header.posOffset.toInt(), header.positionStride.toInt())
|
||||
.attribute(TANGENTS, 0, SHORT4, header.tangentOffset.toInt(), header.tangentStride.toInt())
|
||||
.attribute(COLOR, 0, UBYTE4, header.colorOffset.toInt(), header.colorStride.toInt())
|
||||
.attribute(UV0, 0, HALF2, header.uv0Offset.toInt(), header.uv0Stride.toInt())
|
||||
// UV coordinates are stored as normalized 16-bit integers or half-floats depending on
|
||||
// the range they span. When stored as half-float, there is only enough precision for
|
||||
// sub-pixel addressing in textures that are <= 1024x1024
|
||||
.attribute(UV0, 0, uvType, header.uv0Offset.toInt(), header.uv0Stride.toInt())
|
||||
// When UV coordinates are stored as 16-bit integers we must normalize them (we want
|
||||
// values in the range -1..1)
|
||||
.normalized(UV0, uvNormalized(header))
|
||||
|
||||
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
|
||||
vertexBufferBuilder
|
||||
.attribute(UV1, 0, HALF2, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
.attribute(UV1, 0, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
.normalized(UV1, uvNormalized(header))
|
||||
}
|
||||
|
||||
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
|
||||
@@ -224,7 +242,7 @@ private fun createRenderable(
|
||||
|
||||
val builder = RenderableManager.Builder(header.parts.toInt()).boundingBox(header.aabb)
|
||||
|
||||
(0 until header.parts.toInt()).forEach { i ->
|
||||
repeat(header.parts.toInt()) { i ->
|
||||
builder.geometry(i,
|
||||
RenderableManager.PrimitiveType.TRIANGLES,
|
||||
vertexBuffer,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:08:47 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:08:15 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
12
android/samples/texture-view/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/app/src/main/assets/materials/*.filamat
|
||||
.externalNativeBuild
|
||||
1
android/samples/texture-view/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
80
android/samples/texture-view/app/build.gradle
Normal file
@@ -0,0 +1,80 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
apply from: '../../../build/filament-tasks.gradle'
|
||||
|
||||
compileMaterials {
|
||||
group 'Filament'
|
||||
description 'Compile materials'
|
||||
|
||||
inputDir = file("src/main/materials")
|
||||
outputDir = file("src/main/assets/materials")
|
||||
}
|
||||
|
||||
preBuild.dependsOn compileMaterials
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textureview"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 28
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
// Filament comes with native code, the following declarations
|
||||
// can be used to generate architecture specific APKs
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
}
|
||||
arm7 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
x86_64 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86_64'
|
||||
}
|
||||
}
|
||||
x86 {
|
||||
dimension 'cpuArch'
|
||||
ndk {
|
||||
abiFilters 'x86'
|
||||
}
|
||||
}
|
||||
universal {
|
||||
dimension 'cpuArch'
|
||||
}
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
noCompress 'filamat'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
// Depend on Filament
|
||||
implementation 'com.google.android.filament:filament-android'
|
||||
}
|
||||
21
android/samples/texture-view/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.google.android.filament.textureview">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.textureview
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.opengl.Matrix
|
||||
import android.os.Bundle
|
||||
import android.view.Choreographer
|
||||
import android.view.Surface
|
||||
import android.view.TextureView
|
||||
import android.view.animation.LinearInterpolator
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.nio.channels.Channels
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
class MainActivity : Activity() {
|
||||
// Make sure to initialize Filament first
|
||||
// This loads the JNI library needed by most API calls
|
||||
companion object {
|
||||
init {
|
||||
Filament.init()
|
||||
}
|
||||
}
|
||||
|
||||
// The View we want to render into
|
||||
private lateinit var textureView: TextureView
|
||||
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
|
||||
private lateinit var uiHelper: UiHelper
|
||||
// Choreographer is used to schedule new frames
|
||||
private lateinit var choreographer: Choreographer
|
||||
|
||||
// Engine creates and destroys Filament resources
|
||||
// Each engine must be accessed from a single thread of your choosing
|
||||
// Resources cannot be shared across engines
|
||||
private lateinit var engine: Engine
|
||||
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
|
||||
private lateinit var renderer: Renderer
|
||||
// A scene holds all the renderable, lights, etc. to be drawn
|
||||
private lateinit var scene: Scene
|
||||
// A view defines a viewport, a scene and a camera for rendering
|
||||
private lateinit var view: View
|
||||
// Should be pretty obvious :)
|
||||
private lateinit var camera: Camera
|
||||
|
||||
private lateinit var material: Material
|
||||
private lateinit var vertexBuffer: VertexBuffer
|
||||
private lateinit var indexBuffer: IndexBuffer
|
||||
|
||||
// Filament entity representing a renderable object
|
||||
@Entity private var renderable = 0
|
||||
|
||||
// A swap chain is Filament's representation of a surface
|
||||
private var swapChain: SwapChain? = null
|
||||
|
||||
// Performs the rendering and schedules new frames
|
||||
private val frameScheduler = FrameCallback()
|
||||
|
||||
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
textureView = TextureView(this)
|
||||
setContentView(textureView)
|
||||
|
||||
choreographer = Choreographer.getInstance()
|
||||
|
||||
setupSurfaceView()
|
||||
setupFilament()
|
||||
setupView()
|
||||
setupScene()
|
||||
}
|
||||
|
||||
private fun setupSurfaceView() {
|
||||
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
|
||||
uiHelper.renderCallback = SurfaceCallback()
|
||||
|
||||
// NOTE: To choose a specific rendering resolution, add the following line:
|
||||
// uiHelper.setDesiredSize(1280, 720)
|
||||
uiHelper.attachTo(textureView)
|
||||
}
|
||||
|
||||
private fun setupFilament() {
|
||||
engine = Engine.create()
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
// Clear the background to middle-grey
|
||||
// Setting up a clear color is useful for debugging but usually
|
||||
// unnecessary when using a skybox
|
||||
view.setClearColor(0.035f, 0.035f, 0.035f, 1.0f)
|
||||
|
||||
// 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
|
||||
|
||||
// Tell the view which scene we want to render
|
||||
view.scene = scene
|
||||
}
|
||||
|
||||
private fun setupScene() {
|
||||
loadMaterial()
|
||||
createMesh()
|
||||
|
||||
// To create a renderable we first create a generic entity
|
||||
renderable = EntityManager.get().create()
|
||||
|
||||
// We then create a renderable component on that entity
|
||||
// A renderable is made of several primitives; in this case we declare only 1
|
||||
RenderableManager.Builder(1)
|
||||
// Overall bounding box of the renderable
|
||||
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.01f))
|
||||
// Sets the mesh data of the first primitive
|
||||
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
|
||||
// Sets the material of the first primitive
|
||||
.material(0, material.defaultInstance)
|
||||
.build(engine, renderable)
|
||||
|
||||
// Add the entity to the scene to render it
|
||||
scene.addEntity(renderable)
|
||||
|
||||
startAnimation()
|
||||
}
|
||||
|
||||
private fun loadMaterial() {
|
||||
readUncompressedAsset("materials/baked_color.filamat").let {
|
||||
material = Material.Builder().payload(it, it.remaining()).build(engine)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMesh() {
|
||||
val intSize = 4
|
||||
val floatSize = 4
|
||||
val shortSize = 2
|
||||
// A vertex is a position + a color:
|
||||
// 3 floats for XYZ position, 1 integer for color
|
||||
val vertexSize = 3 * floatSize + intSize
|
||||
|
||||
// Define a vertex and a function to put a vertex in a ByteBuffer
|
||||
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
|
||||
fun ByteBuffer.put(v: Vertex): ByteBuffer {
|
||||
putFloat(v.x)
|
||||
putFloat(v.y)
|
||||
putFloat(v.z)
|
||||
putInt(v.color)
|
||||
return this
|
||||
}
|
||||
|
||||
// We are going to generate a single triangle
|
||||
val vertexCount = 3
|
||||
val a1 = PI * 2.0 / 3.0
|
||||
val a2 = PI * 4.0 / 3.0
|
||||
|
||||
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
|
||||
// It is important to respect the native byte order
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
|
||||
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
|
||||
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
|
||||
// Make sure the cursor is pointing in the right place in the byte buffer
|
||||
.flip()
|
||||
|
||||
// Declare the layout of our mesh
|
||||
vertexBuffer = VertexBuffer.Builder()
|
||||
.bufferCount(1)
|
||||
.vertexCount(vertexCount)
|
||||
// Because we interleave position and color data we must specify offset and stride
|
||||
// We could use de-interleaved data by declaring two buffers and giving each
|
||||
// attribute a different buffer index
|
||||
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
|
||||
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
|
||||
// We store colors as unsigned bytes but since we want values between 0 and 1
|
||||
// in the material (shaders), we must mark the attribute as normalized
|
||||
.normalized(VertexAttribute.COLOR)
|
||||
.build(engine)
|
||||
|
||||
// Feed the vertex data to the mesh
|
||||
// We only set 1 buffer because the data is interleaved
|
||||
vertexBuffer.setBufferAt(engine, 0, vertexData)
|
||||
|
||||
// Create the indices
|
||||
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
.putShort(0)
|
||||
.putShort(1)
|
||||
.putShort(2)
|
||||
.flip()
|
||||
|
||||
indexBuffer = IndexBuffer.Builder()
|
||||
.indexCount(3)
|
||||
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
|
||||
.build(engine)
|
||||
indexBuffer.setBuffer(engine, indexData)
|
||||
}
|
||||
|
||||
private fun startAnimation() {
|
||||
// Animate the triangle
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.duration = 4000
|
||||
animator.repeatMode = ValueAnimator.RESTART
|
||||
animator.repeatCount = ValueAnimator.INFINITE
|
||||
animator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener {
|
||||
val transformMatrix = FloatArray(16)
|
||||
override fun onAnimationUpdate(a: ValueAnimator) {
|
||||
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
|
||||
val tcm = engine.transformManager
|
||||
tcm.setTransform(tcm.getInstance(renderable), transformMatrix)
|
||||
}
|
||||
})
|
||||
animator.start()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
choreographer.postFrameCallback(frameScheduler)
|
||||
animator.start()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
|
||||
// This ensures that all the commands we've sent to Filament have
|
||||
// been processed before we attempt to destroy anything
|
||||
Fence.waitAndDestroy(engine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH)
|
||||
|
||||
// Cleanup all resources
|
||||
engine.destroyEntity(renderable)
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyVertexBuffer(vertexBuffer)
|
||||
engine.destroyIndexBuffer(indexBuffer)
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
engine.destroy()
|
||||
}
|
||||
|
||||
inner class FrameCallback : Choreographer.FrameCallback {
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
// Schedule the next frame
|
||||
choreographer.postFrameCallback(this)
|
||||
|
||||
// This check guarantees that we have a swap chain
|
||||
if (uiHelper.isReadyToRender) {
|
||||
// If beginFrame() returns false you should skip the frame
|
||||
// This means you are sending frames too quickly to the GPU
|
||||
if (renderer.beginFrame(swapChain!!)) {
|
||||
renderer.render(view)
|
||||
renderer.endFrame()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
|
||||
}
|
||||
|
||||
override fun onDetachedFromSurface() {
|
||||
swapChain?.let {
|
||||
engine.destroySwapChain(it)
|
||||
// Required to ensure we don't return before Filament is done executing the
|
||||
// destroySwapChain command, otherwise Android might destroy the Surface
|
||||
// too early
|
||||
engine.flushAndWait()
|
||||
swapChain = null
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResized(width: Int, height: Int) {
|
||||
val zoom = 1.5
|
||||
val aspect = width.toDouble() / height.toDouble()
|
||||
camera.setProjection(Camera.Projection.ORTHO,
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readUncompressedAsset(assetName: String): ByteBuffer {
|
||||
assets.openFd(assetName).use { fd ->
|
||||
val input = fd.createInputStream()
|
||||
val dst = ByteBuffer.allocate(fd.length.toInt())
|
||||
|
||||
val src = Channels.newChannel(input)
|
||||
src.read(dst)
|
||||
src.close()
|
||||
|
||||
return dst.apply { rewind() }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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,
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0"/>
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">Texture View</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
27
android/samples/texture-view/build.gradle
Normal file
@@ -0,0 +1,27 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
13
android/samples/texture-view/gradle.properties
Normal file
@@ -0,0 +1,13 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
BIN
android/samples/texture-view/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
android/samples/texture-view/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Mon Jan 14 11:07:34 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
172
android/samples/texture-view/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
android/samples/texture-view/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
3
android/samples/texture-view/settings.gradle
Normal file
@@ -0,0 +1,3 @@
|
||||
includeBuild '../../filament-android'
|
||||
|
||||
include ':app'
|
||||
@@ -60,7 +60,7 @@ private fun loadIndirectLight(
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine): Pair<IndirectLight, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/nx.rgbm")
|
||||
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
|
||||
@@ -69,12 +69,16 @@ fun loadMesh(assets: AssetManager, name: String,
|
||||
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
|
||||
private const val MAX_UINT32 = 4294967295
|
||||
|
||||
private const val HEADER_FLAG_INTERLEAVED = 0x1L
|
||||
private const val HEADER_FLAG_SNORM16_UV = 0x2L
|
||||
private const val HEADER_FLAG_COMPRESSED = 0x4L
|
||||
|
||||
private class Header {
|
||||
var valid = false
|
||||
var versionNumber = 0L
|
||||
var parts = 0L
|
||||
var aabb = Box()
|
||||
var interleaved = 0L
|
||||
var flags = 0L
|
||||
var posOffset = 0L
|
||||
var positionStride = 0L
|
||||
var tangentOffset = 0L
|
||||
@@ -121,7 +125,7 @@ private fun readHeader(input: InputStream): Header {
|
||||
header.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
header.interleaved = readUIntLE(input)
|
||||
header.flags = readUIntLE(input)
|
||||
header.posOffset = readUIntLE(input)
|
||||
header.positionStride = readUIntLE(input)
|
||||
header.tangentOffset = readUIntLE(input)
|
||||
@@ -142,7 +146,6 @@ private fun readHeader(input: InputStream): Header {
|
||||
return header
|
||||
}
|
||||
|
||||
|
||||
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
|
||||
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
@@ -190,7 +193,15 @@ private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer):
|
||||
.apply { setBuffer(engine, data) }
|
||||
}
|
||||
|
||||
private fun uvNormalized(header: Header) = header.flags and HEADER_FLAG_SNORM16_UV != 0L
|
||||
|
||||
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
|
||||
val uvType = if (!uvNormalized(header)) {
|
||||
HALF2
|
||||
} else {
|
||||
SHORT2
|
||||
}
|
||||
|
||||
val vertexBufferBuilder = VertexBuffer.Builder()
|
||||
.bufferCount(1)
|
||||
.vertexCount(header.totalVertices.toInt())
|
||||
@@ -203,13 +214,18 @@ private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer)
|
||||
.attribute(POSITION, 0, HALF4, header.posOffset.toInt(), header.positionStride.toInt())
|
||||
.attribute(TANGENTS, 0, SHORT4, header.tangentOffset.toInt(), header.tangentStride.toInt())
|
||||
.attribute(COLOR, 0, UBYTE4, header.colorOffset.toInt(), header.colorStride.toInt())
|
||||
// UV coordinates are stored in fp16, which gives sub-pixel precision only
|
||||
// for textures up to 1024x1024
|
||||
.attribute(UV0, 0, HALF2, header.uv0Offset.toInt(), header.uv0Stride.toInt())
|
||||
// UV coordinates are stored as normalized 16-bit integers or half-floats depending on
|
||||
// the range they span. When stored as half-float, there is only enough precision for
|
||||
// sub-pixel addressing in textures that are <= 1024x1024
|
||||
.attribute(UV0, 0, uvType, header.uv0Offset.toInt(), header.uv0Stride.toInt())
|
||||
// When UV coordinates are stored as 16-bit integers we must normalize them (we want
|
||||
// values in the range -1..1)
|
||||
.normalized(UV0, uvNormalized(header))
|
||||
|
||||
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
|
||||
vertexBufferBuilder
|
||||
.attribute(UV1, 0, HALF2, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
.attribute(UV1, 0, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
.normalized(UV1, uvNormalized(header))
|
||||
}
|
||||
|
||||
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:04:36 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.0'
|
||||
ext.kotlin_version = '1.3.11'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
#Mon Jan 14 11:05:59 PST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
|
||||
28
build.sh
@@ -4,7 +4,8 @@ set -e
|
||||
# NDK API level
|
||||
API_LEVEL=21
|
||||
# Host tools required by Android, WebGL, and iOS builds
|
||||
HOST_TOOLS="matc cmgen filamesh mipgen resgen"
|
||||
MOBILE_HOST_TOOLS="matc resgen cmgen"
|
||||
WEB_HOST_TOOLS="${MOBILE_HOST_TOOLS} mipgen filamesh"
|
||||
IOS_TOOLCHAIN_URL="https://opensource.apple.com/source/clang/clang-800.0.38/src/cmake/platforms/iOS.cmake"
|
||||
|
||||
function print_help {
|
||||
@@ -215,6 +216,8 @@ function build_webgl_with_target {
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
fi
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
# Apply the emscripten environment within a subshell.
|
||||
(
|
||||
source ${EMSDK}/emsdk_env.sh
|
||||
cmake \
|
||||
-G "$BUILD_GENERATOR" \
|
||||
@@ -224,6 +227,7 @@ function build_webgl_with_target {
|
||||
-DWEBGL=1 \
|
||||
../..
|
||||
${BUILD_COMMAND} ${BUILD_TARGETS}
|
||||
)
|
||||
fi
|
||||
|
||||
if [ -d "web/filament-js" ]; then
|
||||
@@ -263,7 +267,7 @@ function build_webgl {
|
||||
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}; INSTALL_COMMAND=
|
||||
OLD_ISSUE_DEBUG_BUILD=${ISSUE_DEBUG_BUILD}; ISSUE_DEBUG_BUILD=false
|
||||
OLD_ISSUE_RELEASE_BUILD=${ISSUE_RELEASE_BUILD}; ISSUE_RELEASE_BUILD=true
|
||||
build_desktop "${HOST_TOOLS}"
|
||||
build_desktop "${WEB_HOST_TOOLS}"
|
||||
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
|
||||
ISSUE_DEBUG_BUILD=${OLD_ISSUE_DEBUG_BUILD}
|
||||
ISSUE_RELEASE_BUILD=${OLD_ISSUE_RELEASE_BUILD}
|
||||
@@ -338,7 +342,7 @@ function build_android {
|
||||
# Supress intermediate desktop tools install
|
||||
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
build_desktop "${HOST_TOOLS}"
|
||||
build_desktop "${MOBILE_HOST_TOOLS}"
|
||||
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
|
||||
|
||||
build_android_arch "aarch64" "aarch64-linux-android" "arm64"
|
||||
@@ -450,7 +454,7 @@ function build_ios {
|
||||
# Supress intermediate desktop tools install
|
||||
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
build_desktop "${HOST_TOOLS}"
|
||||
build_desktop "${MOBILE_HOST_TOOLS}"
|
||||
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
|
||||
|
||||
ensure_ios_toolchain
|
||||
@@ -523,9 +527,17 @@ function run_test {
|
||||
}
|
||||
|
||||
function run_tests {
|
||||
while read test; do
|
||||
run_test "$test"
|
||||
done < build/common/test_list.txt
|
||||
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
|
||||
echo "TypeScript `tsc --version`"
|
||||
tsc --noEmit \
|
||||
third_party/gl-matrix/gl-matrix.d.ts \
|
||||
web/filament-js/filament.d.ts \
|
||||
web/filament-js/test.ts
|
||||
else
|
||||
while read test; do
|
||||
run_test "$test"
|
||||
done < build/common/test_list.txt
|
||||
fi
|
||||
}
|
||||
|
||||
# Beginning of the script
|
||||
@@ -599,7 +611,7 @@ while getopts ":hacfijmp:tuvs" opt; do
|
||||
echo "To switch your application to Vulkan, in Android Studio go to "
|
||||
echo "File > Settings > Build > Compiler. In the command-line options field, "
|
||||
echo "add -Pextra_cmake_args=-DFILAMENT_SUPPORTS_VULKAN=ON."
|
||||
echo "Also be sure to pass Backend::VULKAN to Engine::create."
|
||||
echo "Also be sure to pass Engine.Backend.VULKAN to Engine.create."
|
||||
echo ""
|
||||
;;
|
||||
s)
|
||||
|
||||
@@ -26,5 +26,8 @@ elif [ "$LC_UNAME" == "darwin" ]; then
|
||||
fi
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
yes | $ANDROID_HOME/tools/bin/sdkmanager --update >/dev/null && \
|
||||
yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses >/dev/null
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
./build.sh -p android -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData
|
||||
filament/test/test_filament_exposure --gtest_filter=-FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100
|
||||
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100
|
||||
libs/math/test_math
|
||||
libs/image/test_image compare libs/image/tests/reference/
|
||||
libs/utils/test_utils
|
||||
libs/filamat/test_filamat
|
||||
tools/matc/test_matc
|
||||
tools/cmgen/test_cmgen compare
|
||||
tools/glslminifier/test_glslminifier
|
||||
libs/filameshio/test_filameshio
|
||||
|
||||
@@ -28,8 +28,13 @@ set(DIST_ARCH arm64-v8a)
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
|
||||
# specify the cross compiler
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
|
||||
set(COMPILER_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
|
||||
@@ -28,8 +28,13 @@ set(DIST_ARCH armeabi-v7a)
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
|
||||
# specify the cross compiler
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
|
||||
set(COMPILER_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
|
||||
@@ -28,8 +28,13 @@ set(DIST_ARCH x86)
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
|
||||
# specify the cross compiler
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
|
||||
set(COMPILER_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
|
||||
@@ -28,8 +28,13 @@ set(DIST_ARCH x86_64)
|
||||
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
|
||||
|
||||
# specify the cross compiler
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang)
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++)
|
||||
set(COMPILER_SUFFIX)
|
||||
if(WIN32)
|
||||
set(COMPILER_SUFFIX ".cmd")
|
||||
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
|
||||
endif()
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
|
||||
|
||||
# where is the target environment
|
||||
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
|
||||
|
||||
@@ -14,6 +14,6 @@ set -x
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
./build.sh -p webgl -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
./build.sh -p webgl -c $RUN_TESTS $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
@@ -10,6 +10,10 @@ export PATH="$PWD:$PATH"
|
||||
python3 --version
|
||||
pip3 install mistletoe pygments jsbeautifier future_fstrings
|
||||
|
||||
# Install a typescript compiler to allow testing.
|
||||
npm install -g typescript
|
||||
|
||||
# Install a specific version of emscripen to avoid surprises.
|
||||
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
|
||||
unzip emsdk.zip
|
||||
mv emsdk-* emsdk
|
||||
|
||||
@@ -1084,6 +1084,48 @@ fragment {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### curvatureToRoughness
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: Reduces specular aliasing by increasing roughness based on the local geometric curvature.
|
||||
This property is particularly effective if you only use MSAA.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
curvatureToRoughness : true
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
![Figure [curvatureToRoughness]: Close up of a glossy metallic surface rendered normally (left) and
|
||||
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.png)
|
||||
|
||||
### limitOverInterpolation
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: Reduces specular aliasing by attempting to eliminate normal over-interpolation. When this
|
||||
property is turned on, the material switches to centroid normal interpolation when the
|
||||
interpolated normals are too long. This property should only be used if your anti-aliasing
|
||||
method is MSAA. The effects are a lot more subtle than `curvatureToRoughness`, which should be
|
||||
used first to eliminate specular aliasing.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
limitOverInterpolation : true
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### variantFilter
|
||||
|
||||
Type
|
||||
@@ -1117,6 +1159,25 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### flipUV
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `true`.
|
||||
|
||||
Description
|
||||
: When set to `true` (default value), the Y coordinate of UV attributes will be flipped when
|
||||
read by this material's vertex shader. Flipping is equivalent to `y = 1.0 - y`. When set
|
||||
to `false`, flipping is disabled and the UV attributes are read as is.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
flipUV : false
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
## Vertex block
|
||||
|
||||
The vertex block is optional and can be used to control the vertex shading stage of the material.
|
||||
@@ -1173,6 +1234,11 @@ struct MaterialVertexInputs {
|
||||
};
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
!!! TIP: UV attributes
|
||||
By default the vertex shader of a material will flip the Y coordinate of the UV attributes
|
||||
of the current mesh: `material.uv0 = vec2(mesh_uv0.x, 1.0 - mesh_uv0.y)`. You can control
|
||||
this behavior using the `flipUV` property and setting it to `false`.
|
||||
|
||||
## Fragment block
|
||||
|
||||
The fragment block must be used to control the fragment shading stage of the material. The vertex
|
||||
|
||||
BIN
docs/images/samples/sample_texture_view.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
BIN
docs/images/screenshot_curvature_to_roughness.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
@@ -46,6 +46,9 @@ set(SRCS
|
||||
src/components/LightManager.cpp
|
||||
src/components/RenderableManager.cpp
|
||||
src/components/TransformManager.cpp
|
||||
src/fg/FrameGraph.cpp
|
||||
src/driver/noop/NoopDriver.cpp
|
||||
src/driver/noop/PlatformNoop.cpp
|
||||
src/driver/opengl/gl_headers.cpp
|
||||
src/driver/opengl/OpenGLBlitter.cpp
|
||||
src/driver/opengl/GLUtils.cpp
|
||||
@@ -100,6 +103,10 @@ set(PRIVATE_HDRS
|
||||
src/components/LightManager.h
|
||||
src/components/RenderableManager.h
|
||||
src/components/TransformManager.h
|
||||
src/fg/FrameGraph.h
|
||||
src/fg/FrameGraphPass.h
|
||||
src/fg/FrameGraphPassResources.h
|
||||
src/fg/FrameGraphResource.h
|
||||
src/details/Allocators.h
|
||||
src/details/Camera.h
|
||||
src/details/Culler.h
|
||||
@@ -128,6 +135,7 @@ set(PRIVATE_HDRS
|
||||
src/driver/CommandBufferQueue.h
|
||||
src/driver/CommandStream.h
|
||||
src/driver/CommandStreamDispatcher.h
|
||||
src/driver/DataReshaper.h
|
||||
src/driver/Driver.h
|
||||
src/driver/DriverAPI.inc
|
||||
src/driver/DriverApi.h
|
||||
@@ -152,17 +160,6 @@ set(MATERIAL_SRCS
|
||||
src/materials/skyboxRGBM.mat
|
||||
)
|
||||
|
||||
# The noop driver is only useful for ensuring we don't have certain build issues.
|
||||
# Remove it from release builds, since it uses some space needlessly.
|
||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
list(APPEND SRCS src/driver/noop/NoopDriver.cpp)
|
||||
list(APPEND SRCS src/driver/noop/PlatformNoop.cpp)
|
||||
endif()
|
||||
|
||||
if(IOS AND NOT FILAMENT_SUPPORTS_VULKAN)
|
||||
message(FATAL_ERROR "Filament for iOS must be built with Vulkan support.")
|
||||
endif()
|
||||
|
||||
# Embed the binary resource blob for materials.
|
||||
get_resgen_vars(${RESOURCE_DIR} materials)
|
||||
list(APPEND PRIVATE_HDRS ${RESGEN_HEADER})
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <math/vec4.h>
|
||||
#include <math/vec2.h>
|
||||
|
||||
#include <utils/unwindows.h> // Because we define NEAR and FAR in the Plane enum.
|
||||
|
||||
namespace filament {
|
||||
|
||||
namespace details {
|
||||
|
||||
@@ -136,8 +136,6 @@ class FLightManager;
|
||||
* On the other hand, a scene can contain hundreds of non overlapping lights without
|
||||
* incurring a significant overhead.
|
||||
*
|
||||
* 3. Use Type.Static Lights as much as possible.
|
||||
*
|
||||
*/
|
||||
class UTILS_PUBLIC LightManager : public FilamentAPI {
|
||||
struct BuilderDetails;
|
||||
@@ -477,8 +475,6 @@ public:
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param position Light's position in world space. The default is at the origin.
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.position()
|
||||
*/
|
||||
void setPosition(Instance i, const math::float3& position) noexcept;
|
||||
@@ -493,8 +489,6 @@ public:
|
||||
* @param direction Light's direction in world space. Should be a unit vector.
|
||||
* The default is {0,-1,0}.
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.direction()
|
||||
*/
|
||||
void setDirection(Instance i, const math::float3& direction) noexcept;
|
||||
@@ -509,8 +503,6 @@ public:
|
||||
* @param color Color of the light specified in the linear sRGB color-space.
|
||||
* The default is white {1,1,1}.
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.color(), getInstance()
|
||||
*/
|
||||
void setColor(Instance i, const LinearColor& color) noexcept;
|
||||
@@ -531,8 +523,6 @@ public:
|
||||
* - For point lights and spot lights, it specifies the luminous power
|
||||
* in *lumen*.
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.intensity()
|
||||
*/
|
||||
void setIntensity(Instance i, float intensity) noexcept;
|
||||
@@ -554,8 +544,6 @@ public:
|
||||
* LED | 8.7%
|
||||
* Fluorescent | 10.7%
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.intensity(float watts, float efficiency)
|
||||
*/
|
||||
void setIntensity(Instance i, float watts, float efficiency) noexcept {
|
||||
@@ -579,8 +567,6 @@ public:
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param radius falloff distance in world units. Default is 1 meter.
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.falloff()
|
||||
*/
|
||||
void setFalloff(Instance i, float radius) noexcept;
|
||||
@@ -599,8 +585,6 @@ public:
|
||||
* @param inner inner cone angle in *radians* between 0 and @f$ \pi @f$
|
||||
* @param outer outer cone angle in *radians* between 0 and @f$ \pi @f$
|
||||
*
|
||||
* @note ignored for Mode.STATIC lights.
|
||||
*
|
||||
* @see Builder.spotLightCone()
|
||||
*/
|
||||
void setSpotLightCone(Instance i, float inner, float outer) noexcept;
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
uint8_t byteStride = 0) noexcept; // default is attribute size
|
||||
|
||||
// no-op if attribute is an invalid enum
|
||||
Builder& normalized(VertexAttribute attribute) noexcept;
|
||||
Builder& normalized(VertexAttribute attribute, bool normalize = true) noexcept;
|
||||
|
||||
/**
|
||||
* Creates the VertexBuffer object and returns a pointer to it.
|
||||
|
||||
@@ -257,6 +257,8 @@ void FEngine::shutdown() {
|
||||
destroy(mDefaultIblTexture);
|
||||
destroy(mDefaultIbl);
|
||||
|
||||
destroy(mDefaultMaterial);
|
||||
|
||||
/*
|
||||
* clean-up after the user -- we call terminate on each "leaked" object and clear each list.
|
||||
*
|
||||
@@ -354,10 +356,8 @@ int FEngine::loop() {
|
||||
if (platform == nullptr) {
|
||||
platform = Platform::create(&mBackend);
|
||||
mPlatform = platform;
|
||||
#if !defined(NDEBUG)
|
||||
slog.d << "FEngine resolved backend: "
|
||||
<< (mBackend == driver::Backend::VULKAN ? "Vulkan" : "OpenGL") << io::endl;
|
||||
#endif
|
||||
}
|
||||
mDriver = platform->createDriver(mSharedGLContext);
|
||||
mDriverBarrier.latch();
|
||||
@@ -416,9 +416,10 @@ Handle<HwProgram> FEngine::createPostProcessProgram(MaterialParser& parser,
|
||||
// need to populate a SamplerBindingMap and pass a weak reference to Program. Binding maps are
|
||||
// normally owned by Material, but in this case we'll simply own a copy right here in static
|
||||
// storage.
|
||||
static const SamplerBindingMap* pBindings = [] {
|
||||
static const SamplerBindingMap* pBindings = [backend = this->mBackend] {
|
||||
static SamplerBindingMap bindings;
|
||||
bindings.populate();
|
||||
uint8_t offset = filament::getSamplerBindingsStart(backend);
|
||||
bindings.populate(offset);
|
||||
return &bindings;
|
||||
}();
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "FilamentAPI-impl.h"
|
||||
|
||||
#include <filament/driver/DriverEnums.h>
|
||||
|
||||
#include <private/filament/SibGenerator.h>
|
||||
#include <private/filament/UibGenerator.h>
|
||||
#include <private/filament/Variant.h>
|
||||
@@ -123,9 +125,9 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
|
||||
UTILS_UNUSED_IN_RELEASE bool uibOK = parser->getUIB(&mUniformInterfaceBlock);
|
||||
assert(uibOK);
|
||||
|
||||
// Sampler bindings are only required for Vulkan.
|
||||
UTILS_UNUSED_IN_RELEASE bool sbOK = parser->getSamplerBindingMap(&mSamplerBindings);
|
||||
assert(engine.getBackend() == Backend::OPENGL || sbOK);
|
||||
// Populate sampler bindings for the backend that will consume this Material.
|
||||
const uint8_t offset = getSamplerBindingsStart(engine.getBackend());
|
||||
mSamplerBindings.populate(offset, &mSamplerInterfaceBlock);
|
||||
|
||||
parser->getShading(&mShading);
|
||||
parser->getBlendingMode(&mBlendingMode);
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "details/Engine.h"
|
||||
|
||||
#include "fg/FrameGraph.h"
|
||||
|
||||
#include <private/filament/SibGenerator.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
@@ -39,7 +41,8 @@ void PostProcessManager::init(FEngine& engine) noexcept {
|
||||
// create sampler for post-process FBO
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
mPostProcessSbh = driver.createSamplerBuffer(engine.getPostProcessSib().getSize());
|
||||
mPostProcessUbh = driver.createUniformBuffer(engine.getPerPostProcessUib().getSize(), driver::BufferUsage::DYNAMIC);
|
||||
mPostProcessUbh = driver.createUniformBuffer(engine.getPerPostProcessUib().getSize(),
|
||||
driver::BufferUsage::DYNAMIC);
|
||||
driver.bindSamplers(BindingPoints::POST_PROCESS, mPostProcessSbh);
|
||||
driver.bindUniformBuffer(BindingPoints::POST_PROCESS, mPostProcessUbh);
|
||||
}
|
||||
@@ -50,7 +53,7 @@ void PostProcessManager::terminate(driver::DriverApi& driver) noexcept {
|
||||
}
|
||||
|
||||
void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeight,
|
||||
const RenderTargetPool::Target* pos) const noexcept {
|
||||
Handle<HwTexture> texture, uint32_t textureWidth, uint32_t textureHeight) const noexcept {
|
||||
FEngine& engine = *mEngine;
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
@@ -60,7 +63,7 @@ void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeig
|
||||
params.filterMag = SamplerMagFilter::LINEAR;
|
||||
params.filterMin = SamplerMinFilter::LINEAR;
|
||||
SamplerBuffer sb(engine.getPostProcessSib());
|
||||
sb.setSampler(PostProcessSib::COLOR_BUFFER, pos->texture, params);
|
||||
sb.setSampler(PostProcessSib::COLOR_BUFFER, texture, params);
|
||||
|
||||
auto duration = engine.getEngineTime();
|
||||
float fraction = (duration.count() % 1000000000) / 1000000000.0f;
|
||||
@@ -68,11 +71,11 @@ void PostProcessManager::setSource(uint32_t viewportWidth, uint32_t viewportHeig
|
||||
UniformBuffer& ub = mPostProcessUb;
|
||||
ub.setUniform(offsetof(PostProcessingUib, time), fraction);
|
||||
ub.setUniform(offsetof(PostProcessingUib, uvScale),
|
||||
math::float2{ viewportWidth, viewportHeight } / math::float2{ pos->w, pos->h });
|
||||
math::float2{ viewportWidth, viewportHeight } / math::float2{ textureWidth, textureHeight });
|
||||
|
||||
// The shader may need to know the offset between the top of the texture and the top
|
||||
// of the rectangle that it actually needs to sample from.
|
||||
const float yOffset = pos->h - viewportHeight;
|
||||
const float yOffset = textureHeight - viewportHeight;
|
||||
ub.setUniform(offsetof(PostProcessingUib, yOffset), yOffset);
|
||||
|
||||
driver.updateSamplerBuffer(mPostProcessSbh, std::move(sb));
|
||||
@@ -134,7 +137,7 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
|
||||
|
||||
if (commands[i].program) {
|
||||
// set the source for this pass (i.e. previous target)
|
||||
setSource(params.width, params.height, previous);
|
||||
setSource(params.width, params.height, previous->texture, previous->w, previous->h);
|
||||
|
||||
// draw a full screen triangle
|
||||
pipeline.program = commands[i].program;
|
||||
@@ -164,7 +167,7 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
|
||||
params.width = vp.width;
|
||||
params.height = vp.height;
|
||||
|
||||
setSource(params.width, params.height, previous);
|
||||
setSource(params.width, params.height, previous->texture, previous->w, previous->h);
|
||||
pipeline.program = commands.back().program;
|
||||
driver.beginRenderPass(viewRenderTarget, params);
|
||||
driver.draw(pipeline, fullScreenRenderPrimitive);
|
||||
@@ -182,4 +185,175 @@ void PostProcessManager::finish(driver::TargetBufferFlags discarded,
|
||||
commands.clear();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
FrameGraphResource PostProcessManager::msaa(FrameGraph& fg,
|
||||
FrameGraphResource input, driver::TextureFormat outFormat) noexcept {
|
||||
|
||||
struct PostProcessMSAA {
|
||||
FrameGraphResource input;
|
||||
FrameGraphResource output;
|
||||
};
|
||||
|
||||
auto& ppMSAA = fg.addPass<PostProcessMSAA>("msaa",
|
||||
[&](FrameGraph::Builder& builder, PostProcessMSAA& data) {
|
||||
auto const* inputDesc = fg.getDescriptor(input);
|
||||
data.input = builder.blit(input);
|
||||
|
||||
FrameGraphResource::Descriptor outputDesc{
|
||||
.width = inputDesc->width,
|
||||
.height = inputDesc->height,
|
||||
.format = outFormat
|
||||
};
|
||||
data.output = builder.write(builder.createResource("msaa output", outputDesc));
|
||||
},
|
||||
[=](FrameGraphPassResources const& resources,
|
||||
PostProcessMSAA const& data, DriverApi& driver) {
|
||||
auto in = resources.getRenderTarget(data.input);
|
||||
auto out = resources.getRenderTarget(data.output);
|
||||
auto const& desc = resources.getDescriptor(data.input);
|
||||
driver.blit(TargetBufferFlags::COLOR,
|
||||
out.target, 0, 0, desc.width, desc.height,
|
||||
in.target, 0, 0, desc.width, desc.height);
|
||||
});
|
||||
|
||||
return ppMSAA.getData().output;
|
||||
}
|
||||
|
||||
FrameGraphResource PostProcessManager::toneMapping(FrameGraph& fg,
|
||||
FrameGraphResource input, driver::TextureFormat outFormat, bool translucent) noexcept {
|
||||
|
||||
FEngine* engine = mEngine;
|
||||
Handle<HwRenderPrimitive> const& fullScreenRenderPrimitive = engine->getFullScreenRenderPrimitive();
|
||||
|
||||
struct PostProcessToneMapping {
|
||||
FrameGraphResource input;
|
||||
FrameGraphResource output;
|
||||
};
|
||||
Handle<HwProgram> toneMappingProgram = engine->getPostProcessProgram(
|
||||
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
|
||||
: PostProcessStage::TONE_MAPPING_OPAQUE);
|
||||
|
||||
auto& ppToneMapping = fg.addPass<PostProcessToneMapping>("tonemapping",
|
||||
[&](FrameGraph::Builder& builder, PostProcessToneMapping& data) {
|
||||
auto const* inputDesc = fg.getDescriptor(input);
|
||||
data.input = builder.read(input);
|
||||
|
||||
FrameGraphResource::Descriptor outputDesc{
|
||||
.width = inputDesc->width,
|
||||
.height = inputDesc->height,
|
||||
.format = outFormat
|
||||
};
|
||||
data.output = builder.write(
|
||||
builder.createResource("tonemapping output", outputDesc));
|
||||
},
|
||||
[=](FrameGraphPassResources const& resources,
|
||||
PostProcessToneMapping const& data, DriverApi& driver) {
|
||||
Driver::PipelineState pipeline;
|
||||
pipeline.rasterState.culling = Driver::RasterState::CullingMode::NONE;
|
||||
pipeline.rasterState.colorWrite = true;
|
||||
pipeline.rasterState.depthFunc = Driver::RasterState::DepthFunc::A;
|
||||
pipeline.program = toneMappingProgram;
|
||||
|
||||
auto const& targetDesc = resources.getDescriptor(data.output);
|
||||
auto const& textureDesc = resources.getDescriptor(data.input);
|
||||
auto const& texture = resources.getTexture(data.input, TextureUsage::COLOR_ATTACHMENT);
|
||||
setSource(targetDesc.width, targetDesc.height, texture, textureDesc.width, textureDesc.height);
|
||||
|
||||
auto const& target = resources.getRenderTarget(data.output);
|
||||
driver.beginRenderPass(target.target, target.params);
|
||||
driver.draw(pipeline, fullScreenRenderPrimitive);
|
||||
driver.endRenderPass();
|
||||
});
|
||||
|
||||
return ppToneMapping.getData().output;
|
||||
}
|
||||
|
||||
FrameGraphResource PostProcessManager::fxaa(FrameGraph& fg,
|
||||
FrameGraphResource input, driver::TextureFormat outFormat, bool translucent) noexcept {
|
||||
|
||||
FEngine* engine = mEngine;
|
||||
Handle<HwRenderPrimitive> const& fullScreenRenderPrimitive = engine->getFullScreenRenderPrimitive();
|
||||
|
||||
struct PostProcessFXAA {
|
||||
FrameGraphResource input;
|
||||
FrameGraphResource output;
|
||||
};
|
||||
|
||||
Handle<HwProgram> antiAliasingProgram = engine->getPostProcessProgram(
|
||||
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
|
||||
: PostProcessStage::ANTI_ALIASING_OPAQUE);
|
||||
|
||||
auto& ppFXAA = fg.addPass<PostProcessFXAA>("fxaa",
|
||||
[&](FrameGraph::Builder& builder, PostProcessFXAA& data) {
|
||||
auto* inputDesc = fg.getDescriptor(input);
|
||||
inputDesc->format = TextureFormat::RGBA8;
|
||||
data.input = builder.read(input);
|
||||
|
||||
FrameGraphResource::Descriptor outputDesc{
|
||||
.width = inputDesc->width,
|
||||
.height = inputDesc->height,
|
||||
.format = outFormat
|
||||
};
|
||||
data.output = builder.write(builder.createResource("fxaa output", outputDesc));
|
||||
},
|
||||
[=](FrameGraphPassResources const& resources,
|
||||
PostProcessFXAA const& data, DriverApi& driver) {
|
||||
Driver::PipelineState pipeline;
|
||||
pipeline.rasterState.culling = Driver::RasterState::CullingMode::NONE;
|
||||
pipeline.rasterState.colorWrite = true;
|
||||
pipeline.rasterState.depthFunc = Driver::RasterState::DepthFunc::A;
|
||||
pipeline.program = antiAliasingProgram;
|
||||
|
||||
auto const& targetDesc = resources.getDescriptor(data.output);
|
||||
auto const& textureDesc = resources.getDescriptor(data.input);
|
||||
auto const& texture = resources.getTexture(data.input, TextureUsage::COLOR_ATTACHMENT);
|
||||
setSource(targetDesc.width, targetDesc.height, texture, textureDesc.width, textureDesc.height);
|
||||
|
||||
auto const& target = resources.getRenderTarget(data.output);
|
||||
driver.beginRenderPass(target.target, target.params);
|
||||
driver.draw(pipeline, fullScreenRenderPrimitive);
|
||||
driver.endRenderPass();
|
||||
});
|
||||
|
||||
return ppFXAA.getData().output;
|
||||
}
|
||||
|
||||
FrameGraphResource PostProcessManager::dynamicScaling(FrameGraph& fg,
|
||||
FrameGraphResource input, driver::TextureFormat outFormat,
|
||||
Viewport const& outViewport) noexcept {
|
||||
|
||||
struct PostProcessScaling {
|
||||
FrameGraphResource input;
|
||||
FrameGraphResource output;
|
||||
};
|
||||
|
||||
auto& ppScaling = fg.addPass<PostProcessScaling>("scaling",
|
||||
[&](FrameGraph::Builder& builder, PostProcessScaling& data) {
|
||||
auto* inputDesc = fg.getDescriptor(input);
|
||||
data.input = builder.blit(input);
|
||||
|
||||
FrameGraphResource::Descriptor outputDesc{
|
||||
.width = inputDesc->width,
|
||||
.height = inputDesc->height,
|
||||
.format = outFormat
|
||||
};
|
||||
data.output = builder.write(builder.createResource("scale output", outputDesc));
|
||||
},
|
||||
[=](FrameGraphPassResources const& resources,
|
||||
PostProcessScaling const& data, DriverApi& driver) {
|
||||
auto in = resources.getRenderTarget(data.input);
|
||||
auto out = resources.getRenderTarget(data.output);
|
||||
auto const& inDesc = resources.getDescriptor(data.input);
|
||||
driver.blit(TargetBufferFlags::COLOR,
|
||||
out.target, outViewport.left, outViewport.bottom, outViewport.width,
|
||||
outViewport.height,
|
||||
in.target, 0, 0, inDesc.width, inDesc.height);
|
||||
});
|
||||
|
||||
return ppScaling.getData().output;
|
||||
}
|
||||
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "UniformBuffer.h"
|
||||
|
||||
#include "fg/FrameGraphResource.h"
|
||||
|
||||
#include "driver/DriverApiForward.h"
|
||||
#include "driver/Handle.h"
|
||||
|
||||
@@ -41,8 +43,8 @@ class PostProcessManager {
|
||||
public:
|
||||
void init(details::FEngine& engine) noexcept;
|
||||
void terminate(driver::DriverApi& driver) noexcept;
|
||||
void setSource(uint32_t viewportWidth, uint32_t viewportHeight,
|
||||
const RenderTargetPool::Target* pos) const noexcept;
|
||||
void setSource(uint32_t viewportWidth, uint32_t viewportHeight, Handle <HwTexture> texture,
|
||||
uint32_t textureWidth, uint32_t textureHeight) const noexcept;
|
||||
|
||||
// start() is a scam, it does nothing
|
||||
void start() noexcept { }
|
||||
@@ -60,6 +62,23 @@ public:
|
||||
Viewport const& svp);
|
||||
|
||||
|
||||
FrameGraphResource msaa(
|
||||
FrameGraph& fg, FrameGraphResource input,
|
||||
driver::TextureFormat outFormat) noexcept;
|
||||
|
||||
FrameGraphResource toneMapping(
|
||||
FrameGraph& fg, FrameGraphResource input, driver::TextureFormat outFormat,
|
||||
bool translucent) noexcept;
|
||||
|
||||
FrameGraphResource fxaa(
|
||||
FrameGraph& fg, FrameGraphResource input, driver::TextureFormat outFormat,
|
||||
bool translucent) noexcept;
|
||||
|
||||
FrameGraphResource dynamicScaling(
|
||||
FrameGraph& fg, FrameGraphResource input,
|
||||
driver::TextureFormat outFormat, Viewport const& outViewport) noexcept;
|
||||
|
||||
|
||||
private:
|
||||
details::FEngine* mEngine = nullptr;
|
||||
|
||||
|
||||
@@ -25,15 +25,18 @@
|
||||
#include "details/View.h"
|
||||
|
||||
#include <filament/Scene.h>
|
||||
#include <filament/Renderer.h>
|
||||
|
||||
#include <filament/driver/PixelBufferDescriptor.h>
|
||||
|
||||
#include "fg/FrameGraph.h"
|
||||
#include "fg/FrameGraphResource.h"
|
||||
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/vector.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <filament/Renderer.h>
|
||||
|
||||
|
||||
using namespace math;
|
||||
@@ -146,7 +149,6 @@ void FRenderer::render(FView const* view) {
|
||||
|
||||
// and wait for all jobs to finish as a safety (this should be a no-op)
|
||||
js.runAndWait(masterJob);
|
||||
js.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,37 +230,89 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
* Post Processing...
|
||||
*/
|
||||
|
||||
|
||||
#define USE_FRAME_GRAPH false
|
||||
|
||||
if (UTILS_LIKELY(hasPostProcess)) {
|
||||
driver.pushGroupMarker("Post Processing");
|
||||
|
||||
ppm.start();
|
||||
assert(colorTarget);
|
||||
|
||||
if (USE_FRAME_GRAPH) {
|
||||
FrameGraph fg;
|
||||
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
|
||||
FrameGraphResource::Descriptor colorDesc{
|
||||
.width = colorTarget->w,
|
||||
.height= colorTarget->h,
|
||||
.format= colorTarget->format,
|
||||
.samples= colorTarget->samples
|
||||
};
|
||||
|
||||
FrameGraphResource::Descriptor viewRenderTargetDesc{
|
||||
.width = vp.width,
|
||||
.height= vp.height
|
||||
};
|
||||
|
||||
FrameGraphResource input = fg.importResource("colorTarget", colorDesc,
|
||||
colorTarget->target, colorTarget->texture);
|
||||
|
||||
FrameGraphResource output = fg.importResource("viewRenderTarget",
|
||||
viewRenderTargetDesc, viewRenderTarget);
|
||||
|
||||
if (useMSAA > 1) {
|
||||
input = ppm.msaa(fg, input, hdrFormat);
|
||||
}
|
||||
input = ppm.toneMapping(fg, input, ldrFormat, translucent);
|
||||
if (useFXAA) {
|
||||
input = ppm.fxaa(fg, input, ldrFormat, translucent);
|
||||
}
|
||||
if (scaled) {
|
||||
input = ppm.dynamicScaling(fg, input, ldrFormat, vp);
|
||||
}
|
||||
|
||||
fg.moveResource(output, input);
|
||||
fg.present(output, FrameGraph::Builder::COLOR);
|
||||
|
||||
fg.compile();
|
||||
//fg.export_graphviz(slog.d);
|
||||
fg.execute(driver);
|
||||
|
||||
rtp.put(colorTarget);
|
||||
|
||||
} else {
|
||||
|
||||
ppm.start();
|
||||
|
||||
if (useMSAA > 1) {
|
||||
// Note: MSAA, when used is applied before tone-mapping (which is not ideal)
|
||||
// (tone mapping currently only works without multi-sampling)
|
||||
// this blit does a MSAA resolve
|
||||
ppm.blit(hdrFormat);
|
||||
}
|
||||
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
Handle<HwProgram> toneMappingProgram = engine.getPostProcessProgram(
|
||||
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
|
||||
: PostProcessStage::TONE_MAPPING_OPAQUE);
|
||||
ppm.pass(useFXAA ? TextureFormat::RGBA8 : ldrFormat, toneMappingProgram);
|
||||
|
||||
if (useFXAA) {
|
||||
Handle<HwProgram> antiAliasingProgram = engine.getPostProcessProgram(
|
||||
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
|
||||
: PostProcessStage::ANTI_ALIASING_OPAQUE);
|
||||
ppm.pass(ldrFormat, antiAliasingProgram);
|
||||
}
|
||||
|
||||
if (scaled) {
|
||||
// because it's the last command, the TextureFormat is not relevant
|
||||
ppm.blit();
|
||||
}
|
||||
ppm.finish(view.getDiscardedTargetBuffers(), viewRenderTarget, vp, colorTarget, svp);
|
||||
|
||||
if (useMSAA > 1) {
|
||||
// Note: MSAA, when used is applied before tone-mapping (which is not ideal)
|
||||
// (tone mapping currently only works without multi-sampling)
|
||||
// this blit does a MSAA resolve
|
||||
ppm.blit(hdrFormat);
|
||||
}
|
||||
|
||||
const bool translucent = mSwapChain->isTransparent();
|
||||
Handle<HwProgram> toneMappingProgram = engine.getPostProcessProgram(
|
||||
translucent ? PostProcessStage::TONE_MAPPING_TRANSLUCENT
|
||||
: PostProcessStage::TONE_MAPPING_OPAQUE);
|
||||
ppm.pass(useFXAA ? TextureFormat::RGBA8 : ldrFormat, toneMappingProgram);
|
||||
|
||||
if (useFXAA) {
|
||||
Handle<HwProgram> antiAliasingProgram = engine.getPostProcessProgram(
|
||||
translucent ? PostProcessStage::ANTI_ALIASING_TRANSLUCENT
|
||||
: PostProcessStage::ANTI_ALIASING_OPAQUE);
|
||||
ppm.pass(ldrFormat, antiAliasingProgram);
|
||||
}
|
||||
|
||||
if (scaled) {
|
||||
// because it's the last command, the TextureFormat is not relevant
|
||||
ppm.blit();
|
||||
}
|
||||
ppm.finish(view.getDiscardedTargetBuffers(), viewRenderTarget, vp, colorTarget, svp);
|
||||
|
||||
driver.popGroupMarker();
|
||||
}
|
||||
|
||||
@@ -384,13 +438,13 @@ void FRenderer::endFrame() {
|
||||
}
|
||||
mFrameSkipper.endFrame();
|
||||
|
||||
driver.endFrame(mFrameId);
|
||||
|
||||
if (mSwapChain) {
|
||||
mSwapChain->commit(driver);
|
||||
mSwapChain = nullptr;
|
||||
}
|
||||
|
||||
driver.endFrame(mFrameId);
|
||||
|
||||
// Run the component managers' GC in parallel
|
||||
// WARNING: while doing this we can't access any component manager
|
||||
auto& js = engine.getJobSystem();
|
||||
|
||||
@@ -67,21 +67,26 @@ void FScene::prepare(const math::mat4f& worldOriginTransform) {
|
||||
// NOTE: we can't know in advance how many entities are renderable or lights because the corresponding
|
||||
// component can be added after the entity is added to the scene.
|
||||
|
||||
// for the purpose of allocation, we'll assume all our entities are renderables
|
||||
size_t capacity = entities.size();
|
||||
size_t renderableDataCapacity = entities.size();
|
||||
// we need the capacity to be multiple of 16 for SIMD loops
|
||||
capacity = (capacity + 0xF) & ~0xF;
|
||||
renderableDataCapacity = (renderableDataCapacity + 0xF) & ~0xF;
|
||||
// we need 1 extra entry at the end for the summed primitive count
|
||||
capacity = capacity + 1;
|
||||
renderableDataCapacity = renderableDataCapacity + 1;
|
||||
|
||||
sceneData.clear();
|
||||
if (sceneData.capacity() < capacity) {
|
||||
sceneData.setCapacity(capacity);
|
||||
if (sceneData.capacity() < renderableDataCapacity) {
|
||||
sceneData.setCapacity(renderableDataCapacity);
|
||||
}
|
||||
|
||||
// The light data list will always contain at least one entry for the
|
||||
// dominating directional light, even if there are no entities.
|
||||
size_t lightDataCapacity = std::max<size_t>(1, entities.size());
|
||||
// we need the capacity to be multiple of 16 for SIMD loops
|
||||
lightDataCapacity = (lightDataCapacity + 0xF) & ~0xF;
|
||||
|
||||
lightData.clear();
|
||||
if (lightData.capacity() < capacity) {
|
||||
lightData.setCapacity(capacity);
|
||||
if (lightData.capacity() < lightDataCapacity) {
|
||||
lightData.setCapacity(lightDataCapacity);
|
||||
}
|
||||
// the first entries are reserved for the directional lights (currently only one)
|
||||
lightData.resize(DIRECTIONAL_LIGHTS_COUNT);
|
||||
|
||||
@@ -100,10 +100,15 @@ VertexBuffer::Builder& VertexBuffer::Builder::attribute(VertexAttribute attribut
|
||||
return *this;
|
||||
}
|
||||
|
||||
VertexBuffer::Builder& VertexBuffer::Builder::normalized(VertexAttribute attribute) noexcept {
|
||||
VertexBuffer::Builder& VertexBuffer::Builder::normalized(VertexAttribute attribute,
|
||||
bool normalized) noexcept {
|
||||
if (size_t(attribute) < MAX_ATTRIBUTE_BUFFERS_COUNT) {
|
||||
AttributeData& entry = mImpl->mAttributes[attribute];
|
||||
entry.flags |= Driver::Attribute::FLAG_NORMALIZED;
|
||||
if (normalized) {
|
||||
entry.flags |= Driver::Attribute::FLAG_NORMALIZED;
|
||||
} else {
|
||||
entry.flags &= ~Driver::Attribute::FLAG_NORMALIZED;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -602,6 +602,7 @@ void FView::prepareCamera(const CameraInfo& camera, const Viewport& viewport) co
|
||||
const mat4f clipFromView(projectionMatrix);
|
||||
const mat4f viewFromClip(Camera::inverseProjection(clipFromView));
|
||||
const mat4f clipFromWorld(clipFromView * viewFromWorld);
|
||||
const mat4f worldFromClip(worldFromView * viewFromClip);
|
||||
|
||||
UniformBuffer& u = getUb();
|
||||
u.setUniform(offsetof(PerViewUib, viewFromWorldMatrix), viewFromWorld); // view
|
||||
@@ -609,6 +610,7 @@ void FView::prepareCamera(const CameraInfo& camera, const Viewport& viewport) co
|
||||
u.setUniform(offsetof(PerViewUib, clipFromViewMatrix), clipFromView); // projection
|
||||
u.setUniform(offsetof(PerViewUib, viewFromClipMatrix), viewFromClip); // 1/projection
|
||||
u.setUniform(offsetof(PerViewUib, clipFromWorldMatrix), clipFromWorld); // projection * view
|
||||
u.setUniform(offsetof(PerViewUib, worldFromClipMatrix), worldFromClip); // 1/(projection * view)
|
||||
|
||||
const float w = viewport.width;
|
||||
const float h = viewport.height;
|
||||
|
||||
50
filament/src/driver/DataReshaper.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_DRIVER_DATARESHAPER_H
|
||||
#define TNT_FILAMENT_DRIVER_DATARESHAPER_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
// This little utility adds padding to multi-channel interleaved data by inserting dummy values.
|
||||
// This is very useful for platforms that only accept 4-component data, since users often wish to
|
||||
// submit 3-component data.
|
||||
class DataReshaper {
|
||||
public:
|
||||
template<typename componentType, int numSrcChannels, int numDstChannels>
|
||||
static void reshape(void* dest, const void* src, size_t numSrcBytes) {
|
||||
const componentType maxValue = std::numeric_limits<componentType>::max();
|
||||
const componentType* in = (const componentType*) src;
|
||||
componentType* out = (componentType*) dest;
|
||||
const size_t numWords = numSrcBytes / numSrcChannels;
|
||||
for (size_t word = 0; word < numWords; ++word) {
|
||||
for (size_t component = 0; component < numSrcChannels; ++component) {
|
||||
out[component] = in[component];
|
||||
}
|
||||
for (size_t component = numSrcChannels; component < numDstChannels; ++component) {
|
||||
out[component] = maxValue;
|
||||
}
|
||||
in += numSrcChannels;
|
||||
out += numDstChannels;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_DRIVER_DATARESHAPER_H
|
||||
@@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// The noop driver is only useful for ensuring we don't have certain build issues.
|
||||
// Remove it from release builds, since it uses some space needlessly.
|
||||
#ifndef NDEBUG
|
||||
|
||||
#include "driver/noop/NoopDriver.h"
|
||||
#include "driver/CommandStreamDispatcher.h"
|
||||
|
||||
@@ -41,3 +45,5 @@ driver::ShaderModel NoopDriver::getShaderModel() const noexcept {
|
||||
template class ConcreteDispatcher<NoopDriver>;
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// The noop driver is only useful for ensuring we don't have certain build issues.
|
||||
// Remove it from release builds, since it uses some space needlessly.
|
||||
#ifndef NDEBUG
|
||||
|
||||
#include "driver/noop/PlatformNoop.h"
|
||||
|
||||
#include "driver/noop/NoopDriver.h"
|
||||
@@ -25,3 +29,5 @@ Driver* PlatformNoop::createDriver(void* const sharedGLContext) noexcept {
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif
|
||||
|
||||
@@ -575,7 +575,7 @@ void OpenGLDriver::blendFunction(GLenum srcRGB, GLenum srcA, GLenum dstRGB, GLen
|
||||
state.raster.blendFunctionSrcA = srcA;
|
||||
state.raster.blendFunctionDstRGB = dstRGB;
|
||||
state.raster.blendFunctionDstA = dstA;
|
||||
glBlendFuncSeparate(srcRGB, dstRGB, dstA, srcA);
|
||||
glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1301,7 +1301,7 @@ void OpenGLDriver::destroyRenderPrimitive(Driver::RenderPrimitiveHandle rph) {
|
||||
glDeleteVertexArrays(1, &rp->gl.vao);
|
||||
// binding of a bound VAO is reset to 0
|
||||
if (state.vao.p == rp) {
|
||||
state.vao.p = &mDefaultVAO;
|
||||
bindVertexArray(nullptr);
|
||||
}
|
||||
destruct(rph, rp);
|
||||
}
|
||||
|
||||