Compare commits
173 Commits
sceneform-
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a052d6cf49 | ||
|
|
591c9f2454 | ||
|
|
e580bfed56 | ||
|
|
e2896f4632 | ||
|
|
a33c64c736 | ||
|
|
7ea04957d2 | ||
|
|
8c6cfdba67 | ||
|
|
e5cfbeff4d | ||
|
|
68c6afa72e | ||
|
|
bb3e9a47e5 | ||
|
|
8d410af4b3 | ||
|
|
61112c02c1 | ||
|
|
816fb99b2f | ||
|
|
9de7ffaf84 | ||
|
|
e3e16fe28b | ||
|
|
bb0c21b8ea | ||
|
|
c46ecc6e05 | ||
|
|
fffb2c8c97 | ||
|
|
a42dcd2291 | ||
|
|
4e3a88bbab | ||
|
|
02d45d464c | ||
|
|
c758b53f00 | ||
|
|
4e3c2582e0 | ||
|
|
cc1ba4fac7 | ||
|
|
f52087ec1e | ||
|
|
2ac04c27d8 | ||
|
|
211eddfbe0 | ||
|
|
522a8bedb8 | ||
|
|
8ad655766b | ||
|
|
5da454f652 | ||
|
|
0deafea0da | ||
|
|
69e379cf90 | ||
|
|
e8fddba494 | ||
|
|
31b9801f17 | ||
|
|
4860ff816f | ||
|
|
82e61ddc88 | ||
|
|
3a9f3a1984 | ||
|
|
3b793a7994 | ||
|
|
e2777b9100 | ||
|
|
96cb5d5951 | ||
|
|
e6bb8a6235 | ||
|
|
934b75e68b | ||
|
|
58f36d1a7f | ||
|
|
83e4402e90 | ||
|
|
c6a1900beb | ||
|
|
17021a1167 | ||
|
|
f0fbdaec28 | ||
|
|
b73f58e6ef | ||
|
|
254e3db215 | ||
|
|
d9df864de4 | ||
|
|
995b8361b8 | ||
|
|
a61af02038 | ||
|
|
84bfbac5fa | ||
|
|
912b301790 | ||
|
|
b707027401 | ||
|
|
68dfb5ae80 | ||
|
|
ab3770d281 | ||
|
|
28c56eb354 | ||
|
|
30eccc78b6 | ||
|
|
ab24665396 | ||
|
|
9e7b589d0a | ||
|
|
979b6f00fd | ||
|
|
0754edbf9b | ||
|
|
9916af3ab1 | ||
|
|
dcfbe694b1 | ||
|
|
835cc93b71 | ||
|
|
2f14ac64a7 | ||
|
|
e96f982c9f | ||
|
|
605a836565 | ||
|
|
1cde20d822 | ||
|
|
a547f11a8c | ||
|
|
83de0fc3e8 | ||
|
|
3ed2dd08fb | ||
|
|
db729b157a | ||
|
|
29119c7248 | ||
|
|
356c3a2c24 | ||
|
|
b0853b5eb6 | ||
|
|
d324dc724a | ||
|
|
e6435a7431 | ||
|
|
d3e7f40398 | ||
|
|
f5319f2492 | ||
|
|
e00ba80561 | ||
|
|
d15e275de0 | ||
|
|
920cc7a84a | ||
|
|
3b504f2941 | ||
|
|
f697b41a2b | ||
|
|
8452c4f8f2 | ||
|
|
c238027e49 | ||
|
|
b374340ebb | ||
|
|
c581b755fd | ||
|
|
9e5f44bd34 | ||
|
|
d9204052c8 | ||
|
|
5a8d4d818c | ||
|
|
cd84980c84 | ||
|
|
9b8d5fdf12 | ||
|
|
7cb01929a3 | ||
|
|
e7777ef330 | ||
|
|
0326d60d0a | ||
|
|
0d709b6074 | ||
|
|
6992c8a584 | ||
|
|
7c54faa8bd | ||
|
|
3a0f9791cc | ||
|
|
473824b15e | ||
|
|
b4c77166b7 | ||
|
|
920113b076 | ||
|
|
2a10f8122d | ||
|
|
182d95c6ce | ||
|
|
ed76aa04ca | ||
|
|
76035711f4 | ||
|
|
7959f31ebf | ||
|
|
10a3addf1a | ||
|
|
89982e6e97 | ||
|
|
7485cc5fd0 | ||
|
|
95a2686555 | ||
|
|
b29432e330 | ||
|
|
94d224eac3 | ||
|
|
8a70e02bea | ||
|
|
66e66e4b45 | ||
|
|
238c796026 | ||
|
|
8ed132b675 | ||
|
|
24adeb9b8e | ||
|
|
b905adfcb5 | ||
|
|
fc672aa8a4 | ||
|
|
aa980682e6 | ||
|
|
c2ce7f8ffd | ||
|
|
faddb10a00 | ||
|
|
6c66bc26e7 | ||
|
|
27a2d05c8a | ||
|
|
c6cef9ff9c | ||
|
|
06fc8e2f4c | ||
|
|
5ac2c96cb5 | ||
|
|
9516080d21 | ||
|
|
fcf52a72e8 | ||
|
|
da698f2e36 | ||
|
|
311d2804bb | ||
|
|
2c4ecebf11 | ||
|
|
eed2f72466 | ||
|
|
23efe17380 | ||
|
|
473b173647 | ||
|
|
001965cf42 | ||
|
|
8a0c714108 | ||
|
|
af5a168277 | ||
|
|
43070b413e | ||
|
|
551fe7ef8b | ||
|
|
e74a306df2 | ||
|
|
4302d9dcc3 | ||
|
|
18504b1928 | ||
|
|
3defd8a855 | ||
|
|
541db4fea5 | ||
|
|
5325f57e8f | ||
|
|
37a42ee854 | ||
|
|
cc61e4649b | ||
|
|
2eeb92fc4c | ||
|
|
eaf82961de | ||
|
|
69bdb6d1c9 | ||
|
|
8e9ef497f6 | ||
|
|
70a4c4f887 | ||
|
|
3ad0574878 | ||
|
|
3185d0f237 | ||
|
|
1748724826 | ||
|
|
741b1a412d | ||
|
|
4177eb14ed | ||
|
|
4ddfd52ad8 | ||
|
|
33e0e34aa4 | ||
|
|
395b3a398d | ||
|
|
b25e693f6b | ||
|
|
6ed331d74c | ||
|
|
fae92f2750 | ||
|
|
17cfd55d3c | ||
|
|
ec31a55094 | ||
|
|
13e70f7afa | ||
|
|
cb34ab217b | ||
|
|
4764eefafc |
@@ -270,6 +270,7 @@ 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)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
@@ -289,7 +290,8 @@ endif()
|
||||
set (FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
|
||||
|
||||
if (WEBGL)
|
||||
add_subdirectory(${FILAMENT}/samples/web)
|
||||
add_subdirectory(web/filament-js)
|
||||
add_subdirectory(web/samples)
|
||||
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
|
||||
@@ -297,7 +299,7 @@ if (WEBGL)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WEBGL)
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
add_subdirectory(${FILAMENT}/samples)
|
||||
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
@@ -309,6 +311,8 @@ if (NOT ANDROID AND NOT WEBGL)
|
||||
# must come first because of glslang
|
||||
add_subdirectory(${EXTERNAL}/spirv-tools)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
add_subdirectory(${EXTERNAL}/glslang/tnt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
@@ -332,7 +336,7 @@ if (NOT ANDROID AND NOT WEBGL)
|
||||
add_subdirectory(${TOOLS}/specular-color)
|
||||
endif()
|
||||
|
||||
# Generate exported executables for cross-compiled builds (Android and WebGL)
|
||||
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
export(TARGETS matc cmgen filamesh mipgen FILE ${IMPORT_EXECUTABLES})
|
||||
endif()
|
||||
|
||||
@@ -120,6 +120,9 @@ private:
|
||||
- other headers are sorted in reverse order of their layering, that is, lower layer headers last
|
||||
- within a layer, headers are sorted alphabetically
|
||||
- strive for implementing one class per file
|
||||
- `STL` limited in public headers to:
|
||||
- `type_traits`
|
||||
- `limits`
|
||||
|
||||
*Sorting the headers is important to help catching missing `#include` directives.*
|
||||
|
||||
|
||||
53
README.md
@@ -1,13 +1,14 @@
|
||||
# Filament
|
||||
|
||||
<img alt="Android" src="build/img/android.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_android.html)
|
||||
<img alt="iOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_ios.html)
|
||||
<img alt="Linux" src="build/img/linux.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_linux.html)
|
||||
<img alt="macOS" src="build/img/macos.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_mac.html)
|
||||
<img alt="Windows" src="build/img/windows.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_windows.html)
|
||||
<img alt="Web" src="build/img/web.png" width="20px" height="20px" hspace="2px"/>[](https://filament-build.storage.googleapis.com/badges/build_link_web.html)
|
||||
|
||||
Filament is a real-time physically based rendering engine for Android, Linux, macOS, Windows, and
|
||||
WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||
Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows,
|
||||
and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||
|
||||
Filament is currently used in the
|
||||
[Sceneform](https://developers.google.com/ar/develop/java/sceneform/) library both at runtime on
|
||||
@@ -53,13 +54,14 @@ Here are a few sample materials rendered with Filament:
|
||||
|
||||
- Native C++ API for Android, Linux, macOS and Windows
|
||||
- Java/JNI API for Android, Linux, macOS and Windows
|
||||
- [Python bindings](https://github.com/artometa/pyfilament)
|
||||
- JavaScript API
|
||||
|
||||
### Backends
|
||||
|
||||
- OpenGL 4.1+ for Linux, macOS and Windows
|
||||
- OpenGL ES 3.0+ for Android
|
||||
- Vulkan 1.0 for Android, Linux, macOS (with MoltenVk) and Windows
|
||||
- OpenGL ES 3.0+ for Android and iOS
|
||||
- Vulkan 1.0 for Android, Linux, macOS and iOS (with MoltenVk), and Windows
|
||||
- WebGL 2.0 for all platforms
|
||||
|
||||
### Rendering
|
||||
|
||||
@@ -108,6 +110,7 @@ Many other features have been either prototyped or planned:
|
||||
- `math`: Mathematica notebooks used to explore BRDFs, equations, etc.
|
||||
- `filament`: Filament engine
|
||||
- `ide`: Configuration files for IDEs (CLion, etc.)
|
||||
- `ios`: Sample projects for iOS
|
||||
- `java`: Java bindings for Filament libraries
|
||||
- `libs`: Libraries
|
||||
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
|
||||
@@ -116,6 +119,7 @@ Many other features have been either prototyped or planned:
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
- `filamat`: Material generation library
|
||||
- `filameshio`: Tiny mesh parsing library (see also `tools/filamesh`)
|
||||
- `image`: Image filtering and simple transforms
|
||||
- `imageio`: Image file reading / writing, only intended for internal use
|
||||
- `math`: Math library
|
||||
@@ -132,7 +136,7 @@ Many other features have been either prototyped or planned:
|
||||
- `matinfo` Displays information about materials compiled with `matc`
|
||||
- `mipgen` Generates a series of miplevels from a source image.
|
||||
- `normal-blending`: Tool to blend normal maps
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `roughness-prefilter`: Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`: Physically-based sky environment texture generator
|
||||
- `specular-color`: Computes the specular color of conductors based on spectral data
|
||||
|
||||
@@ -299,6 +303,17 @@ $ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/fi
|
||||
$ ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
The following instructions have been tested on a machine running Windows 10. They should take you
|
||||
@@ -700,18 +715,24 @@ export EMSDK=<your chosen home for the emscripten SDK>
|
||||
```
|
||||
|
||||
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
|
||||
creates a `public` folder that can be used as the root of a simple static web server. Note that you
|
||||
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
|
||||
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
|
||||
use Python to create a quick localhost server:
|
||||
|
||||
```
|
||||
cd out/cmake-web-release/samples/web/public
|
||||
cd out/cmake-webgl-release/web/samples
|
||||
python3 -m http.server # Python 3
|
||||
python -m SimpleHTTPServer # Python 2.7
|
||||
```
|
||||
|
||||
Each sample app has its own handwritten html file, wasm file, and js loader. Additionally the public
|
||||
folder contains meshes, textures, and the tiny `filaweb.js` library.
|
||||
You can then open http://localhost:8000/suzanne.html in your web browser.
|
||||
|
||||
Alternatively, if you have node installed you can use the
|
||||
[live-server](https://www.npmjs.com/package/live-server) package, which automatically refreshes the
|
||||
web page when it detects a change.
|
||||
|
||||
Each sample app has its own handwritten html file. Additionally the server folder contains assets
|
||||
such as meshes, textures, and materials.
|
||||
|
||||
## Running the native samples
|
||||
|
||||
@@ -730,7 +751,7 @@ in your build directory). These sample apps expect a path to a directory contain
|
||||
for the IBL. To generate an IBL simply use this command:
|
||||
|
||||
```
|
||||
cmgen -x ./ibls/ my_ibl.exr
|
||||
cmgen -x ./ibls/ my_ibl.exr
|
||||
```
|
||||
|
||||
The source environment map can be a PNG (8 or 16 bit), a PSD (16 or 32 bit), an HDR or an OpenEXR
|
||||
@@ -840,6 +861,14 @@ package `com.google.android.filament.android`. All you need to do is set a rende
|
||||
helper and attach your `SurfaceView` or `TextureView` to it. You are still responsible for
|
||||
creating the swap chain in the `onNativeWindowChanged()` callback.
|
||||
|
||||
### iOS
|
||||
|
||||
See `ios/samples` for examples of using Filament on iOS.
|
||||
|
||||
Filament on iOS is largely the same as native rendering with C++. A `CAEAGLLayer` or `CAMetalLayer`
|
||||
is passed to the `createSwapChain` method. Filament for iOS supports both OpenGL ES and Vulkan via
|
||||
MoltenVK.
|
||||
|
||||
## Generating C++ documentation
|
||||
|
||||
To generate the documentation you must first install `doxygen`, then run the following commands:
|
||||
@@ -870,7 +899,7 @@ Host tools (such as `matc` or `cmgen`) can use external dependencies freely.
|
||||
## How to make contributions
|
||||
|
||||
Please read and follow the steps in [CONTRIBUTING.md](/CONTRIBUTING.md). Make sure you are
|
||||
familiar with the [code style](/CODE_STYLE.md).
|
||||
familiar with the [code style](/CODE_STYLE.md).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ target_link_libraries(filament-jni
|
||||
GLESv3
|
||||
EGL
|
||||
android
|
||||
jnigraphics
|
||||
)
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
|
||||
@@ -13,7 +13,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ JniCallback::~JniCallback() {
|
||||
|
||||
void JniCallback::invoke(void*, size_t, void* user) {
|
||||
JniCallback* data = reinterpret_cast<JniCallback*>(user);
|
||||
delete data;
|
||||
// don't call delete here, because we don't own the storage
|
||||
data->~JniCallback();
|
||||
}
|
||||
|
||||
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <filament/driver/PixelBufferDescriptor.h>
|
||||
|
||||
#include "CallbackUtils.h"
|
||||
@@ -49,6 +50,19 @@ Java_com_google_android_filament_Renderer_nRender(JNIEnv *, jclass, jlong native
|
||||
renderer->render(view);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Renderer_nMirrorFrame(JNIEnv *, jclass, jlong nativeRenderer,
|
||||
jlong nativeDstSwapChain,
|
||||
jint dstLeft, jint dstBottom, jint dstWidth, jint dstHeight,
|
||||
jint srcLeft, jint srcBottom, jint srcWidth, jint srcHeight,
|
||||
jint flags) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
SwapChain *dstSwapChain = (SwapChain *) nativeDstSwapChain;
|
||||
const Viewport dstViewport {dstLeft, dstBottom, (uint32_t) dstWidth, (uint32_t) dstHeight};
|
||||
const Viewport srcViewport {srcLeft, srcBottom, (uint32_t) srcWidth, (uint32_t) srcHeight};
|
||||
renderer->mirrorFrame(dstSwapChain, dstViewport, srcViewport, (uint32_t) flags);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
|
||||
jlong nativeRenderer, jlong nativeEngine,
|
||||
|
||||
@@ -24,8 +24,8 @@ using namespace utils;
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Scene_nSetSkybox(JNIEnv *env, jclass type, jlong nativeScene,
|
||||
jlong nativeSkybox) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
Skybox *skybox = (Skybox *) nativeSkybox;
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
Skybox* skybox = (Skybox*) nativeSkybox;
|
||||
scene->setSkybox(skybox);
|
||||
}
|
||||
|
||||
@@ -33,33 +33,33 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Scene_nSetIndirectLight(JNIEnv *env, jclass type,
|
||||
jlong nativeScene, jlong nativeIndirectLight) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
|
||||
IndirectLight* indirectLight = (IndirectLight*) nativeIndirectLight;
|
||||
scene->setIndirectLight(indirectLight);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Scene_nAddEntity(JNIEnv *env, jclass type, jlong nativeScene,
|
||||
jint entity) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
scene->addEntity((Entity &) entity);
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
scene->addEntity((Entity&) entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Scene_nRemove(JNIEnv *env, jclass type, jlong nativeScene,
|
||||
jint entity) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
scene->remove((Entity &) entity);
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
scene->remove((Entity&) entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Scene_nGetRenderableCount(JNIEnv *env, jclass type,
|
||||
jlong nativeScene) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
return (jint) scene->getRenderableCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Scene_nGetLightCount(JNIEnv *env, jclass type, jlong nativeScene) {
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
return (jint) scene->getLightCount();
|
||||
}
|
||||
|
||||
@@ -154,3 +154,9 @@ Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Stream_nGetTimestamp(JNIEnv*, jclass, jlong nativeStream) {
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
return stream->getTimestamp();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/bitmap.h>
|
||||
#endif
|
||||
|
||||
#include <filament/driver/BufferDescriptor.h>
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Stream.h>
|
||||
@@ -37,7 +41,7 @@ static size_t getTextureDataSize(const Texture *texture, size_t level,
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint internalFormat) {
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jboolean) Texture::isTextureFormatSupported(*engine,
|
||||
@@ -47,61 +51,68 @@ Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv *env,
|
||||
// Texture::Builder...
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Texture_nCreateBuilder(JNIEnv *env, jclass type) {
|
||||
Java_com_google_android_filament_Texture_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new Texture::Builder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nDestroyBuilder(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderWidth(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderWidth(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint width) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->width((uint32_t) width);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderHeight(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderHeight(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint height) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->height((uint32_t) height);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderDepth(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderDepth(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint depth) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->depth((uint32_t) depth);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderLevels(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderLevels(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint levels) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->levels((uint8_t) levels);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderSampler(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderSampler(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint sampler) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->sampler((Texture::Sampler) sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderFormat(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderFormat(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint format) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->format((Texture::InternalFormat) format);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderRgbm(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enable) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->rgbm(enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
@@ -111,54 +122,60 @@ Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv *env, jclass type,
|
||||
// Texture...
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetWidth(JNIEnv *env, jclass type, jlong nativeTexture,
|
||||
Java_com_google_android_filament_Texture_nGetWidth(JNIEnv*, jclass, jlong nativeTexture,
|
||||
jint level) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getWidth((size_t) level);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetHeight(JNIEnv *env, jclass type, jlong nativeTexture,
|
||||
Java_com_google_android_filament_Texture_nGetHeight(JNIEnv*, jclass, jlong nativeTexture,
|
||||
jint level) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getHeight((size_t) level);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetDepth(JNIEnv *env, jclass type, jlong nativeTexture,
|
||||
Java_com_google_android_filament_Texture_nGetDepth(JNIEnv*, jclass, jlong nativeTexture,
|
||||
jint level) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getDepth((size_t) level);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetLevels(JNIEnv *env, jclass type, jlong nativeTexture) {
|
||||
Java_com_google_android_filament_Texture_nGetLevels(JNIEnv*, jclass, jlong nativeTexture) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getLevels();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetTarget(JNIEnv *env, jclass type, jlong nativeTexture) {
|
||||
Java_com_google_android_filament_Texture_nGetTarget(JNIEnv*, jclass, jlong nativeTexture) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getTarget();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetInternalFormat(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nGetInternalFormat(JNIEnv*, jclass,
|
||||
jlong nativeTexture) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return (jint) texture->getFormat();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Texture_nGetRgbm(JNIEnv*, jclass, jlong nativeTexture) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
return static_cast<jboolean>(texture->isRgbm());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImage(JNIEnv *env, jclass type_, jlong nativeTexture,
|
||||
Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong nativeTexture,
|
||||
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
|
||||
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
@@ -183,9 +200,9 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv *env, jclass type_, jl
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass type_, jlong nativeTexture,
|
||||
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
|
||||
jint width, jint height, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint compressedSizeInBytes, jint compressedFormat,
|
||||
jobject handler, jobject runnable) {
|
||||
@@ -214,7 +231,7 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass type_,
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment, jint stride, jint format,
|
||||
jintArray faceOffsetsInBytes_,
|
||||
@@ -249,7 +266,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass ty
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env, jclass type_,
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint compressedSizeInBytes, jint compressedFormat, jintArray faceOffsetsInBytes_,
|
||||
@@ -284,14 +301,15 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlong nativeTexture, jlong nativeEngine, jlong eglImage) {
|
||||
Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlong nativeTexture,
|
||||
jlong nativeEngine, jlong eglImage) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
texture->setExternalImage(*engine, (void*)eglImage);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
@@ -300,7 +318,7 @@ Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv *env, jclass
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nGenerateMipmaps(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_Texture_nGenerateMipmaps(JNIEnv*, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
@@ -310,9 +328,113 @@ Java_com_google_android_filament_Texture_nGenerateMipmaps(JNIEnv *env, jclass ty
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Texture_nIsStreamValidForTexture(JNIEnv*, jclass,
|
||||
jlong nativeTexture, jlong nativeStream) {
|
||||
jlong nativeTexture, jlong) {
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
return (jboolean) (texture->getTarget() == SamplerType::SAMPLER_EXTERNAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ANDROID SPECIFIC BITS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
#define BITMAP_CONFIG_ALPHA_8 0
|
||||
#define BITMAP_CONFIG_RGB_565 1
|
||||
#define BITMAP_CONFIG_RGBA_4444 2
|
||||
#define BITMAP_CONFIG_RGBA_8888 3
|
||||
#define BITMAP_CONFIG_RGBA_F16 4
|
||||
#define BITMAP_CONFIG_HARDWARE 5
|
||||
|
||||
class AutoBitmap {
|
||||
public:
|
||||
AutoBitmap(JNIEnv* env, jobject bitmap) noexcept
|
||||
: mEnv(env)
|
||||
, mBitmap(env->NewGlobalRef(bitmap))
|
||||
{
|
||||
if (mBitmap) {
|
||||
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
|
||||
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
|
||||
}
|
||||
}
|
||||
|
||||
~AutoBitmap() noexcept {
|
||||
if (mBitmap) {
|
||||
AndroidBitmap_unlockPixels(mEnv, mBitmap);
|
||||
mEnv->DeleteGlobalRef(mBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
AutoBitmap(AutoBitmap &&rhs) noexcept {
|
||||
mEnv = rhs.mEnv;
|
||||
std::swap(mData, rhs.mData);
|
||||
std::swap(mBitmap, rhs.mBitmap);
|
||||
std::swap(mInfo, rhs.mInfo);
|
||||
}
|
||||
|
||||
void* getData() const noexcept {
|
||||
return mData;
|
||||
}
|
||||
|
||||
size_t getSizeInBytes() const noexcept {
|
||||
return mInfo.height * mInfo.stride;
|
||||
}
|
||||
|
||||
PixelDataFormat getFormat(int format) const noexcept {
|
||||
// AndroidBitmapInfo does not capture the HARDWARE and RGBA_F16 formats
|
||||
// so we switch on the Bitmap.Config values directly
|
||||
switch (format) {
|
||||
case BITMAP_CONFIG_ALPHA_8: return PixelDataFormat::ALPHA;
|
||||
case BITMAP_CONFIG_RGB_565: return PixelDataFormat::RGB;
|
||||
default: return PixelDataFormat::RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
PixelDataType getType(int format) const noexcept {
|
||||
switch (format) {
|
||||
case BITMAP_CONFIG_RGBA_F16: return PixelDataType::HALF;
|
||||
default: return PixelDataType::UBYTE;
|
||||
}
|
||||
}
|
||||
|
||||
static void invoke(void* buffer, size_t n, void* user) {
|
||||
AutoBitmap* data = reinterpret_cast<AutoBitmap*>(user);
|
||||
data->~AutoBitmap();
|
||||
}
|
||||
|
||||
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap) {
|
||||
void* that = engine->streamAlloc(sizeof(AutoBitmap), alignof(AutoBitmap));
|
||||
return new (that) AutoBitmap(env, bitmap);
|
||||
}
|
||||
|
||||
private:
|
||||
JNIEnv* mEnv;
|
||||
void* mData = nullptr;
|
||||
jobject mBitmap = nullptr;
|
||||
AndroidBitmapInfo mInfo;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_android_TextureHelper_nSetBitmap(JNIEnv* env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
|
||||
jint width, jint height, jobject bitmap, jint format) {
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap);
|
||||
|
||||
Texture::PixelBufferDescriptor desc(
|
||||
autoBitmap->getData(),
|
||||
autoBitmap->getSizeInBytes(),
|
||||
autoBitmap->getFormat(format),
|
||||
autoBitmap->getType(format),
|
||||
&AutoBitmap::invoke, autoBitmap);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
(uint32_t) xoffset, (uint32_t) yoffset,
|
||||
(uint32_t) width, (uint32_t) height,
|
||||
std::move(desc));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma ide diagnostic ignored "NotReleasedValue"
|
||||
extern "C" {
|
||||
void *getNativeWindow(JNIEnv *env, jclass klass, jobject surface) {
|
||||
void *win = nullptr;
|
||||
@@ -40,7 +42,7 @@ void *getNativeWindow(JNIEnv *env, jclass klass, jobject surface) {
|
||||
view.wantsLayer = true;
|
||||
[jawldsip setLayer:view.layer];
|
||||
|
||||
win = (void*)view;
|
||||
win = (void*) view;
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
return win;
|
||||
}
|
||||
@@ -48,7 +50,7 @@ void *getNativeWindow(JNIEnv *env, jclass klass, jobject surface) {
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, width, height)];
|
||||
view.wantsLayer = true;
|
||||
return (jlong)view;
|
||||
return (jlong) view;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
@@ -57,3 +59,4 @@ void destroyNativeSurface(jlong surface) {
|
||||
}
|
||||
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
@@ -25,65 +25,83 @@ static std::vector<int> jawtVersions = {
|
||||
0x00010009,
|
||||
};
|
||||
|
||||
bool acquireDrawingSurface(JNIEnv *env, jobject surface, JAWT_DrawingSurface** ods,
|
||||
JAWT_DrawingSurfaceInfo** odsi) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wuninitialized"
|
||||
bool acquireDrawingSurface(JNIEnv* env, jobject surface,
|
||||
JAWT_DrawingSurface** ods, JAWT_DrawingSurfaceInfo** odsi) {
|
||||
|
||||
JAWT awt;
|
||||
JAWT_DrawingSurface *ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo *dsi = nullptr;
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
// Search for a valid AWT
|
||||
jboolean foundJawt = false;
|
||||
for(int jawtVersion : jawtVersions) {
|
||||
jboolean foundJawt = JNI_FALSE;
|
||||
for (int jawtVersion : jawtVersions) {
|
||||
awt.version = jawtVersion;
|
||||
foundJawt = JAWT_GetAWT(env, &awt);
|
||||
if (foundJawt == JNI_TRUE) {
|
||||
#ifndef NDEBUG
|
||||
printf("Found valid AWT v%08x.\n", jawtVersion);
|
||||
#endif
|
||||
break;
|
||||
} else {
|
||||
#ifndef NDEBUG
|
||||
printf("AWT v%08x not present.\n", jawtVersion);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (foundJawt == JNI_FALSE) {
|
||||
printf("AWT Not found\n");
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the drawing surface
|
||||
ds = awt.GetDrawingSurface(env, surface);
|
||||
if (ds == NULL) {
|
||||
if (ds == nullptr) {
|
||||
#ifndef NDEBUG
|
||||
printf("NULL drawing surface\n");
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lock the drawing
|
||||
jint lock = ds->Lock(ds);
|
||||
if ((lock & JAWT_LOCK_ERROR) != 0) {
|
||||
#ifndef NDEBUG
|
||||
printf("Error locking surface\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
awt.FreeDrawingSurface(ds);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the drawing surface info
|
||||
dsi = ds->GetDrawingSurfaceInfo(ds);
|
||||
if (dsi == NULL) {
|
||||
if (dsi == nullptr) {
|
||||
#ifndef NDEBUG
|
||||
printf("Error getting surface info\n");
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
ds->Unlock(ds);
|
||||
awt.FreeDrawingSurface(ds);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
*odsi = dsi;
|
||||
*ods = ds;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void releaseDrawingSurface(JAWT_DrawingSurface *ds, JAWT_DrawingSurfaceInfo *dsi) {
|
||||
return true;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi) {
|
||||
// Free the drawing surface info
|
||||
ds->FreeDrawingSurfaceInfo(dsi);
|
||||
// Unlock the drawing surface
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <jawt.h>
|
||||
|
||||
extern "C" {
|
||||
bool acquireDrawingSurface(JNIEnv *env, jobject obj, JAWT_DrawingSurface** ds,
|
||||
JAWT_DrawingSurfaceInfo** dsi);
|
||||
bool acquireDrawingSurface(JNIEnv* env, jobject surface, JAWT_DrawingSurface** ods,
|
||||
JAWT_DrawingSurfaceInfo** odsi);
|
||||
void releaseDrawingSurface(JAWT_DrawingSurface* ds, JAWT_DrawingSurfaceInfo* dsi);
|
||||
}
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
#include<GL/glx.h>
|
||||
|
||||
extern "C" {
|
||||
void *getNativeWindow(JNIEnv *env, jclass, jobject surface) {
|
||||
void *win = nullptr;
|
||||
JAWT_DrawingSurface *ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo *dsi = nullptr;
|
||||
void *getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
void* win = nullptr;
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return win;
|
||||
}
|
||||
JAWT_X11DrawingSurfaceInfo *dsi_x11 = (JAWT_X11DrawingSurfaceInfo *) dsi->platformInfo;
|
||||
JAWT_X11DrawingSurfaceInfo* dsi_x11 = (JAWT_X11DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
|
||||
win = (void *) dsi_x11->drawable;
|
||||
win = (void*) dsi_x11->drawable;
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
return win;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ jlong createNativeSurface(jint width, jint height) {
|
||||
XFlush(display);
|
||||
|
||||
// Camouflage the pbuffer as a window which are both XID anyway.
|
||||
return (jlong)window;
|
||||
return (jlong) window;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
@@ -88,4 +88,3 @@ void destroyNativeSurface(jlong surface) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -50,18 +50,22 @@ void chooseAndSetPixelFormat(HDC dc) {
|
||||
SetPixelFormat(dc, pixelFormat, &pfd);
|
||||
}
|
||||
|
||||
void *getNativeWindow(JNIEnv *env, jclass, jobject surface) {
|
||||
void *win = nullptr;
|
||||
JAWT_DrawingSurface *ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo *dsi = nullptr;
|
||||
void* getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
void* win = nullptr;
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return win;
|
||||
}
|
||||
JAWT_Win32DrawingSurfaceInfo *dsi_win32 = (JAWT_Win32DrawingSurfaceInfo *) dsi->platformInfo;
|
||||
|
||||
JAWT_Win32DrawingSurfaceInfo* dsi_win32 = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
HDC dc = dsi_win32->hdc;
|
||||
chooseAndSetPixelFormat(dsi_win32->hdc);
|
||||
win = (void *) dsi_win32->hdc;
|
||||
|
||||
win = (void*) dsi_win32->hdc;
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
@@ -77,13 +81,15 @@ jlong createNativeSurface(jint width, jint height) {
|
||||
|
||||
HWND window = CreateWindowA("STATIC", "dummy", 0, 0, 0, width, height, NULL, NULL, NULL, NULL);
|
||||
SetWindowLong(window, GWL_STYLE, 0); //remove all window styles
|
||||
|
||||
HDC dc = GetDC(window);
|
||||
chooseAndSetPixelFormat(dc);
|
||||
return (jlong)dc;
|
||||
|
||||
return (jlong) dc;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
HDC dc = (HDC)surface;
|
||||
HDC dc = (HDC) surface;
|
||||
HWND window = WindowFromDC(dc);
|
||||
ReleaseDC(window, dc);
|
||||
DestroyWindow(window);
|
||||
|
||||
@@ -27,6 +27,9 @@ public class Renderer {
|
||||
private final Engine mEngine;
|
||||
private long mNativeObject;
|
||||
|
||||
public static final int MIRROR_FRAME_FLAG_COMMIT = 0x1;
|
||||
public static final int MIRROR_FRAME_FLAG_SET_PRESENTATION_TIME = 0x2;
|
||||
public static final int MIRROR_FRAME_FLAG_CLEAR = 0x4;
|
||||
|
||||
Renderer(@NonNull Engine engine, long nativeRenderer) {
|
||||
mEngine = engine;
|
||||
@@ -50,6 +53,18 @@ public class Renderer {
|
||||
nRender(getNativeObject(), view.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method MUST be called before endFrame.
|
||||
*/
|
||||
public void mirrorFrame(
|
||||
@NonNull SwapChain dstSwapChain, @NonNull Viewport dstViewport,
|
||||
@NonNull Viewport srcViewport, int flags) {
|
||||
nMirrorFrame(getNativeObject(), dstSwapChain.getNativeObject(),
|
||||
dstViewport.left, dstViewport.bottom, dstViewport.width, dstViewport.height,
|
||||
srcViewport.left, srcViewport.bottom, srcViewport.width, srcViewport.height,
|
||||
flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method MUST be called before endFrame.
|
||||
*/
|
||||
@@ -88,6 +103,10 @@ public class Renderer {
|
||||
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain);
|
||||
private static native void nEndFrame(long nativeRenderer);
|
||||
private static native void nRender(long nativeRenderer, long nativeView);
|
||||
private static native void nMirrorFrame(long nativeRenderer, long nativeDstSwapChain,
|
||||
int dstLeft, int dstBottom, int dstWidth, int dstHeight,
|
||||
int srcLeft, int srcBottom, int srcWidth, int srcHeight,
|
||||
int flags);
|
||||
private static native int nReadPixels(long nativeRenderer, long nativeEngine,
|
||||
int xoffset, int yoffset, int width, int height,
|
||||
Buffer storage, int remaining,
|
||||
|
||||
@@ -16,31 +16,53 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public class Scene {
|
||||
private long mNativeObject;
|
||||
private @Nullable Skybox mSkybox;
|
||||
private @Nullable IndirectLight mIndirectLight;
|
||||
|
||||
Scene(long nativeScene) {
|
||||
mNativeObject = nativeScene;
|
||||
}
|
||||
|
||||
public void setSkybox(@NonNull Skybox skybox) {
|
||||
nSetSkybox(getNativeObject(), skybox.getNativeObject());
|
||||
@Nullable
|
||||
public Skybox getSkybox() {
|
||||
return mSkybox;
|
||||
}
|
||||
|
||||
public void setIndirectLight(@NonNull IndirectLight ibl) {
|
||||
nSetIndirectLight(getNativeObject(), ibl.getNativeObject());
|
||||
public void setSkybox(@Nullable Skybox skybox) {
|
||||
mSkybox = skybox;
|
||||
nSetSkybox(getNativeObject(), mSkybox != null ? mSkybox.getNativeObject() : 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IndirectLight getIndirectLight() {
|
||||
return mIndirectLight;
|
||||
}
|
||||
|
||||
public void setIndirectLight(@Nullable IndirectLight ibl) {
|
||||
mIndirectLight = ibl;
|
||||
nSetIndirectLight(getNativeObject(),
|
||||
mIndirectLight != null ? mIndirectLight.getNativeObject() : 0);
|
||||
}
|
||||
|
||||
public void addEntity(@Entity int entity) {
|
||||
nAddEntity(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
public void remove(@Entity int entity) {
|
||||
public void removeEntity(@Entity int entity) {
|
||||
nRemove(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated See {@link #removeEntity(int)}
|
||||
*/
|
||||
public void remove(@Entity int entity) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
|
||||
public int getRenderableCount() {
|
||||
return nGetRenderableCount(getNativeObject());
|
||||
}
|
||||
|
||||
@@ -128,6 +128,10 @@ public class Stream {
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return nGetTimestamp(getNativeObject());
|
||||
}
|
||||
|
||||
long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed Stream");
|
||||
@@ -153,6 +157,7 @@ public class Stream {
|
||||
Buffer storage, int remaining,
|
||||
int left, int top, int type, int alignment, int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
private static native long nGetTimestamp(long nativeStream);
|
||||
|
||||
private static native boolean nIsNative(long nativeStream);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ public class SwapChain {
|
||||
private long mNativeObject;
|
||||
|
||||
public static final long CONFIG_TRANSPARENT = 0x1;
|
||||
public static final long CONFIG_READABLE = 0x2;
|
||||
|
||||
SwapChain(long nativeSwapChain, @NonNull Object surface) {
|
||||
mNativeObject = nativeSwapChain;
|
||||
|
||||
@@ -59,7 +59,9 @@ public class Texture {
|
||||
R32F, R32UI, R32I,
|
||||
RG16F, RG16UI, RG16I,
|
||||
R11F_G11F_B10F,
|
||||
RGBA8, SRGB8_A8, RGBA8_SNORM, RGBM, RGB10_A2, RGBA8UI, RGBA8I,
|
||||
RGBA8, SRGB8_A8, RGBA8_SNORM,
|
||||
UNUSED, // The RGBM InternalFormat has been replaced with a flag (Texture.Builder.rgbm)
|
||||
RGB10_A2, RGBA8UI, RGBA8I,
|
||||
DEPTH32F, DEPTH24_STENCIL8, DEPTH32F_STENCIL8,
|
||||
|
||||
// 48-bits per element
|
||||
@@ -331,6 +333,12 @@ public class Texture {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder rgbm(boolean enabled) {
|
||||
nBuilderRgbm(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Texture build(@NonNull Engine engine) {
|
||||
long nativeTexture = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
@@ -484,6 +492,7 @@ public class Texture {
|
||||
private static native void nBuilderLevels(long nativeBuilder, int levels);
|
||||
private static native void nBuilderSampler(long nativeBuilder, int sampler);
|
||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||
private static native void nBuilderRgbm(long nativeBuilder, boolean enabled);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetWidth(long nativeTexture, int level);
|
||||
@@ -515,7 +524,8 @@ public class Texture {
|
||||
int alignment, int compressedSizeInBytes, int compressedFormat,
|
||||
int[] faceOffsetsInBytes, Object handler, Runnable callback);
|
||||
|
||||
private static native void nSetExternalImage(long nativeObject, long nativeObject1, long eglImage);
|
||||
private static native void nSetExternalImage(
|
||||
long nativeObject, long nativeEngine, long eglImage);
|
||||
|
||||
private static native void nSetExternalStream(long nativeTexture,
|
||||
long nativeEngine, long nativeStream);
|
||||
|
||||
@@ -57,7 +57,13 @@ public class TextureSampler {
|
||||
|
||||
int mSampler = 0; // bit field used by native
|
||||
|
||||
/**
|
||||
* Min filter: LINEAR_MIPMAP_LINEAR
|
||||
* Mag filter: LINEAR
|
||||
* Wrap mode: REPEAT
|
||||
*/
|
||||
public TextureSampler() {
|
||||
this(MinFilter.LINEAR_MIPMAP_LINEAR, MagFilter.LINEAR, WrapMode.REPEAT);
|
||||
}
|
||||
|
||||
public TextureSampler(@NonNull MagFilter minMag) {
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.android;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.support.annotation.IntRange;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class TextureHelper {
|
||||
// Keep in sync with Texture.cpp
|
||||
private static final int BITMAP_CONFIG_ALPHA_8 = 0;
|
||||
private static final int BITMAP_CONFIG_RGB_565 = 1;
|
||||
private static final int BITMAP_CONFIG_RGBA_4444 = 2;
|
||||
private static final int BITMAP_CONFIG_RGBA_8888 = 3;
|
||||
private static final int BITMAP_CONFIG_RGBA_F16 = 4;
|
||||
private static final int BITMAP_CONFIG_HARDWARE = 5;
|
||||
|
||||
private static Method sEngineGetNativeObject;
|
||||
private static Method sTextureGetNativeObject;
|
||||
|
||||
static {
|
||||
try {
|
||||
sEngineGetNativeObject = Engine.class.getDeclaredMethod("getNativeObject");
|
||||
sTextureGetNativeObject = Texture.class.getDeclaredMethod("getNativeObject");
|
||||
|
||||
sEngineGetNativeObject.setAccessible(true);
|
||||
sTextureGetNativeObject.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Cannot happen
|
||||
}
|
||||
}
|
||||
|
||||
private TextureHelper() {
|
||||
}
|
||||
|
||||
public static void setBitmap(@NonNull Engine engine,
|
||||
@NonNull Texture texture, @IntRange(from = 0) int level, @NonNull Bitmap bitmap) {
|
||||
setBitmap(engine, texture,
|
||||
level, 0, 0, texture.getWidth(level), texture.getHeight(level), bitmap);
|
||||
}
|
||||
|
||||
public static void setBitmap(@NonNull Engine engine,
|
||||
@NonNull Texture texture, @IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
|
||||
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
|
||||
@NonNull Bitmap bitmap) {
|
||||
|
||||
int format = toNativeFormat(bitmap.getConfig());
|
||||
if (format == BITMAP_CONFIG_RGBA_4444 || format == BITMAP_CONFIG_HARDWARE) {
|
||||
throw new IllegalArgumentException("Unsupported config: ARGB_4444 or HARDWARE");
|
||||
}
|
||||
|
||||
try {
|
||||
long nativeTexture = (Long) sTextureGetNativeObject.invoke(texture);
|
||||
long nativeEngine = (Long) sEngineGetNativeObject.invoke(engine);
|
||||
nSetBitmap(nativeTexture, nativeEngine, level, xoffset, yoffset, width, height,
|
||||
bitmap, format);
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
private static int toNativeFormat(Bitmap.Config config) {
|
||||
switch (config) {
|
||||
case ALPHA_8: return BITMAP_CONFIG_ALPHA_8;
|
||||
case RGB_565: return BITMAP_CONFIG_RGB_565;
|
||||
case ARGB_4444: return BITMAP_CONFIG_RGBA_4444;
|
||||
case ARGB_8888: return BITMAP_CONFIG_RGBA_8888;
|
||||
case RGBA_F16: return BITMAP_CONFIG_RGBA_F16;
|
||||
case HARDWARE: return BITMAP_CONFIG_HARDWARE;
|
||||
}
|
||||
return BITMAP_CONFIG_RGBA_8888;
|
||||
}
|
||||
|
||||
private static native void nSetBitmap(long nativeTexture, long nativeEngine,
|
||||
int level, int xoffset, int yoffset, int width, int height, Bitmap bitmap, int format);
|
||||
}
|
||||
@@ -126,11 +126,6 @@ public class UiHelper {
|
||||
// TODO: do something with policy
|
||||
}
|
||||
|
||||
public UiHelper(int sampleCount, RendererCallback renderCallback) {
|
||||
this();
|
||||
setRenderCallback(renderCallback);
|
||||
}
|
||||
|
||||
public void setRenderCallback(RendererCallback renderCallback) {
|
||||
mRenderCallback = renderCallback;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ Filament APIs:
|
||||
|
||||
- `hello-triangle`: Minimal example showing how to setup a rendering surface for Filament
|
||||
- `lit-cube`: Shows how to create a light and a mesh with the attributes required for lighting
|
||||
- `image-based-lighting`: Demonstrates how to create image-based lights and load complex meshes
|
||||
- `image-based-lighting`: Demonstrates how to create image-based lights and load complex meshes
|
||||
- `textured-object`: Demonstrates how to load and use textures for complex materials
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -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.2.70'
|
||||
ext.kotlin_version = '1.3.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -49,11 +49,11 @@ fun destroyIbl(engine: Engine, ibl: Ibl) {
|
||||
}
|
||||
|
||||
private fun peekSize(assets: AssetManager, name: String): Pair<Int, Int> {
|
||||
val input = assets.open(name)
|
||||
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
BitmapFactory.decodeStream(input, null, opts)
|
||||
input.close()
|
||||
return opts.outWidth to opts.outHeight
|
||||
assets.open(name).use { input ->
|
||||
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
BitmapFactory.decodeStream(input, null, opts)
|
||||
return opts.outWidth to opts.outHeight
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadIndirectLight(
|
||||
@@ -65,11 +65,12 @@ private fun loadIndirectLight(
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(log2(w.toFloat()).toInt() + 1)
|
||||
.format(Texture.InternalFormat.RGBM)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
(0 until texture.levels).forEach {
|
||||
repeat(texture.levels) {
|
||||
loadCubemap(texture, assets, name, engine, "m${it}_", it)
|
||||
}
|
||||
|
||||
@@ -87,7 +88,7 @@ private fun loadSphericalHarmonics(assets: AssetManager, name: String): FloatArr
|
||||
// 3 bands = 9 RGB coefficients, so 9 * 3 floats
|
||||
val sphericalHarmonics = FloatArray(9 * 3)
|
||||
BufferedReader(InputStreamReader(assets.open("$name/sh.txt"))).use { input ->
|
||||
(0 until 9).forEach { i ->
|
||||
repeat(9) { i ->
|
||||
val line = input.readLine()
|
||||
re.find(line)?.let {
|
||||
sphericalHarmonics[i * 3] = it.groups[1]?.value?.toFloat() ?: 0.0f
|
||||
@@ -105,7 +106,8 @@ private fun loadSkybox(assets: AssetManager, name: String, engine: Engine): Pair
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(1)
|
||||
.format(Texture.InternalFormat.RGBM)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
@@ -131,7 +133,7 @@ private fun loadCubemap(texture: Texture,
|
||||
// Allocate enough memory for all the cubemap faces
|
||||
val storage = ByteBuffer.allocateDirect(faceSize * 6)
|
||||
|
||||
arrayOf("px", "nx", "py", "ny", "pz", "nz").forEachIndexed { _, suffix ->
|
||||
arrayOf("px", "nx", "py", "ny", "pz", "nz").forEach { suffix ->
|
||||
assets.open("$name/$prefix$suffix.rgbm").use {
|
||||
val bitmap = BitmapFactory.decodeStream(it, null, opts)
|
||||
bitmap?.copyPixelsToBuffer(storage)
|
||||
|
||||
@@ -132,8 +132,8 @@ class MainActivity : Activity() {
|
||||
setupMaterial()
|
||||
loadImageBasedLight()
|
||||
|
||||
scene.setSkybox(ibl.skybox)
|
||||
scene.setIndirectLight(ibl.indirectLight)
|
||||
scene.skybox = ibl.skybox
|
||||
scene.indirectLight = ibl.indirectLight
|
||||
|
||||
// This map can contain named materials that will map to the material names
|
||||
// loaded from the filamesh file. The material called "DefaultMaterial" is
|
||||
|
||||
@@ -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.2.70'
|
||||
ext.kotlin_version = '1.3.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
@@ -291,7 +291,7 @@ class MainActivity : Activity() {
|
||||
// Create the indices
|
||||
val indexData = ByteBuffer.allocate(6 * 2 * 3 * shortSize)
|
||||
.order(ByteOrder.nativeOrder())
|
||||
(0..5).forEach {
|
||||
repeat(5) {
|
||||
val i = (it * 4).toShort()
|
||||
indexData
|
||||
.putShort(i).putShort((i + 1).toShort()).putShort((i + 2).toShort())
|
||||
|
||||
@@ -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.2.70'
|
||||
ext.kotlin_version = '1.3.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
||||
13
android/samples/textured-object/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/app/src/main/assets/materials/*.filamat
|
||||
/app/src/main/assets/envs
|
||||
.externalNativeBuild
|
||||
1
android/samples/textured-object/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
98
android/samples/textured-object/app/build.gradle
Normal file
@@ -0,0 +1,98 @@
|
||||
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")
|
||||
}
|
||||
|
||||
compileMesh {
|
||||
group 'Filament'
|
||||
description 'Compile mesh'
|
||||
|
||||
inputFile = file("../../../../third_party/shader_ball/shader_ball.obj")
|
||||
outputDir = file("src/main/assets/models")
|
||||
}
|
||||
|
||||
generateIbl {
|
||||
group 'Filament'
|
||||
description 'Generate IBL'
|
||||
|
||||
inputFile = file("../../../../third_party/environments/venetian_crossroads_2k.hdr")
|
||||
outputDir = file("src/main/assets/envs")
|
||||
}
|
||||
|
||||
preBuild.dependsOn compileMaterials
|
||||
preBuild.dependsOn compileMesh
|
||||
preBuild.dependsOn generateIbl
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.textured"
|
||||
minSdkVersion 26
|
||||
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/textured-object/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.textured">
|
||||
|
||||
<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="com.google.android.filament.textured.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,148 @@
|
||||
/*
|
||||
* 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.textured
|
||||
|
||||
import android.content.res.AssetManager
|
||||
import android.graphics.BitmapFactory
|
||||
|
||||
import com.google.android.filament.Engine
|
||||
import com.google.android.filament.IndirectLight
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.Texture
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
import kotlin.math.log2
|
||||
|
||||
data class Ibl(val indirectLight: IndirectLight,
|
||||
val indirectLightTexture: Texture,
|
||||
val skybox: Skybox,
|
||||
val skyboxTexture: Texture)
|
||||
|
||||
fun loadIbl(assets: AssetManager, name: String, engine: Engine): Ibl {
|
||||
val (ibl, iblTexture) = loadIndirectLight(assets, name, engine)
|
||||
val (skybox, skyboxTexture) = loadSkybox(assets, name, engine)
|
||||
return Ibl(ibl, iblTexture, skybox, skyboxTexture)
|
||||
}
|
||||
|
||||
fun destroyIbl(engine: Engine, ibl: Ibl) {
|
||||
engine.destroySkybox(ibl.skybox)
|
||||
engine.destroyTexture(ibl.skyboxTexture)
|
||||
engine.destroyIndirectLight(ibl.indirectLight)
|
||||
engine.destroyTexture(ibl.indirectLightTexture)
|
||||
}
|
||||
|
||||
private fun peekSize(assets: AssetManager, name: String): Pair<Int, Int> {
|
||||
assets.open(name).use { input ->
|
||||
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
BitmapFactory.decodeStream(input, null, opts)
|
||||
return opts.outWidth to opts.outHeight
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadIndirectLight(
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine): Pair<IndirectLight, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(log2(w.toFloat()).toInt() + 1)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
repeat(texture.levels) {
|
||||
loadCubemap(texture, assets, name, engine, "m${it}_", it)
|
||||
}
|
||||
|
||||
val sphericalHarmonics = loadSphericalHarmonics(assets, name)
|
||||
|
||||
return IndirectLight.Builder()
|
||||
.reflections(texture)
|
||||
.irradiance(3, sphericalHarmonics)
|
||||
.intensity(30_000.0f)
|
||||
.build(engine) to texture
|
||||
}
|
||||
|
||||
private fun loadSphericalHarmonics(assets: AssetManager, name: String): FloatArray {
|
||||
val re = Regex("""\(\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+)\);""")
|
||||
// 3 bands = 9 RGB coefficients, so 9 * 3 floats
|
||||
val sphericalHarmonics = FloatArray(9 * 3)
|
||||
BufferedReader(InputStreamReader(assets.open("$name/sh.txt"))).use { input ->
|
||||
repeat(9) { i ->
|
||||
val line = input.readLine()
|
||||
re.find(line)?.let {
|
||||
sphericalHarmonics[i * 3] = it.groups[1]?.value?.toFloat() ?: 0.0f
|
||||
sphericalHarmonics[i * 3 + 1] = it.groups[2]?.value?.toFloat() ?: 0.0f
|
||||
sphericalHarmonics[i * 3 + 2] = it.groups[3]?.value?.toFloat() ?: 0.0f
|
||||
}
|
||||
}
|
||||
}
|
||||
return sphericalHarmonics
|
||||
}
|
||||
|
||||
private fun loadSkybox(assets: AssetManager, name: String, engine: Engine): Pair<Skybox, Texture> {
|
||||
val (w, h) = peekSize(assets, "$name/nx.rgbm")
|
||||
val texture = Texture.Builder()
|
||||
.width(w)
|
||||
.height(h)
|
||||
.levels(1)
|
||||
.format(Texture.InternalFormat.RGBA8)
|
||||
.rgbm(true)
|
||||
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
|
||||
.build(engine)
|
||||
|
||||
loadCubemap(texture, assets, name, engine)
|
||||
|
||||
return Skybox.Builder().environment(texture).build(engine) to texture
|
||||
}
|
||||
|
||||
private fun loadCubemap(texture: Texture,
|
||||
assets: AssetManager,
|
||||
name: String,
|
||||
engine: Engine,
|
||||
prefix: String = "",
|
||||
level: Int = 0) {
|
||||
// This is important, in the RGBM format the alpha channel does not encode
|
||||
// opacity but a scale factor (to represent HDR data). We must tell Android
|
||||
// to not premultiply the RGB channels by the alpha channel
|
||||
val opts = BitmapFactory.Options().apply { inPremultiplied = false }
|
||||
|
||||
// RGBM is always 4 bytes per pixel
|
||||
val faceSize = texture.getWidth(level) * texture.getHeight(level) * 4
|
||||
val offsets = IntArray(6) { it * faceSize }
|
||||
// Allocate enough memory for all the cubemap faces
|
||||
val storage = ByteBuffer.allocateDirect(faceSize * 6)
|
||||
|
||||
arrayOf("px", "nx", "py", "ny", "pz", "nz").forEach { suffix ->
|
||||
assets.open("$name/$prefix$suffix.rgbm").use {
|
||||
val bitmap = BitmapFactory.decodeStream(it, null, opts)
|
||||
bitmap?.copyPixelsToBuffer(storage)
|
||||
}
|
||||
}
|
||||
|
||||
// Rewind the texture buffer
|
||||
storage.flip()
|
||||
|
||||
val buffer = Texture.PixelBufferDescriptor(storage, Texture.Format.RGBM, Texture.Type.UBYTE)
|
||||
texture.setImage(engine, level, buffer, offsets)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.textured
|
||||
|
||||
import java.io.InputStream
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
|
||||
fun readIntLE(input: InputStream): Int {
|
||||
return input.read() and 0xff or (
|
||||
input.read() and 0xff shl 8) or (
|
||||
input.read() and 0xff shl 16) or (
|
||||
input.read() and 0xff shl 24)
|
||||
}
|
||||
|
||||
fun readFloat32LE(input: InputStream): Float {
|
||||
val bytes = ByteArray(4)
|
||||
input.read(bytes, 0, 4)
|
||||
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).float
|
||||
}
|
||||
|
||||
fun readUIntLE(input: InputStream): Long {
|
||||
return readIntLE(input).toLong() and 0xFFFFFFFFL
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* 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.textured
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
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.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
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 surfaceView: SurfaceView
|
||||
// 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 materialInstance: MaterialInstance
|
||||
|
||||
private lateinit var baseColor: Texture
|
||||
private lateinit var normal: Texture
|
||||
private lateinit var aoRoughnessMetallic: Texture
|
||||
|
||||
private lateinit var mesh: Mesh
|
||||
private lateinit var ibl: Ibl
|
||||
|
||||
// Filament entity representing a renderable object
|
||||
@Entity private var light = 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, (2.0 * PI).toFloat())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
surfaceView = SurfaceView(this)
|
||||
setContentView(surfaceView)
|
||||
|
||||
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(surfaceView)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// Enable dynamic resolution with a default target frame rate of 60fps
|
||||
val options = View.DynamicResolutionOptions()
|
||||
options.enabled = true
|
||||
|
||||
view.dynamicResolutionOptions = options
|
||||
}
|
||||
|
||||
private fun setupScene() {
|
||||
loadMaterial()
|
||||
setupMaterial()
|
||||
loadImageBasedLight()
|
||||
|
||||
scene.skybox = ibl.skybox
|
||||
scene.indirectLight = ibl.indirectLight
|
||||
|
||||
// This map can contain named materials that will map to the material names
|
||||
// loaded from the filamesh file. The material called "DefaultMaterial" is
|
||||
// applied when no named material can be found
|
||||
val materials = mapOf("DefaultMaterial" to materialInstance)
|
||||
|
||||
// Load the mesh in the filamesh format (see filamesh tool)
|
||||
mesh = loadMesh(assets, "models/shader_ball.filamesh", materials, engine)
|
||||
|
||||
// Move the mesh down
|
||||
// Filament uses column-major matrices
|
||||
engine.transformManager.setTransform(engine.transformManager.getInstance(mesh.renderable),
|
||||
floatArrayOf(
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, -1.2f, 0.0f, 1.0f
|
||||
))
|
||||
|
||||
// Add the entity to the scene to render it
|
||||
scene.addEntity(mesh.renderable)
|
||||
|
||||
// We now need a light, let's create a directional light
|
||||
light = EntityManager.get().create()
|
||||
|
||||
// Create a color from a temperature (D65)
|
||||
val (r, g, b) = Colors.cct(6_500.0f)
|
||||
LightManager.Builder(LightManager.Type.DIRECTIONAL)
|
||||
.color(r, g, b)
|
||||
// Intensity of the sun in lux on a clear day
|
||||
.intensity(110_000.0f)
|
||||
// The direction is normalized on our behalf
|
||||
.direction(-0.753f, -1.0f, 0.890f)
|
||||
.castShadows(true)
|
||||
.build(engine, light)
|
||||
|
||||
// Add the entity to the scene to light it
|
||||
scene.addEntity(light)
|
||||
|
||||
// Set the exposure on the camera, this exposure follows the sunny f/16 rule
|
||||
// Since we've defined a light that has the same intensity as the sun, it
|
||||
// guarantees a proper exposure
|
||||
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
|
||||
|
||||
startAnimation()
|
||||
}
|
||||
|
||||
private fun loadMaterial() {
|
||||
readUncompressedAsset("materials/textured_pbr.filamat").let {
|
||||
material = Material.Builder().payload(it, it.remaining()).build(engine)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupMaterial() {
|
||||
// Create an instance of the material to set different parameters on it
|
||||
materialInstance = material.createInstance()
|
||||
|
||||
// Note that the textures are stored in drawable-nodpi to prevent the system
|
||||
// from automatically resizing them based on the display's density
|
||||
baseColor = loadTexture(engine, resources, R.drawable.floor_basecolor, TextureType.COLOR)
|
||||
normal = loadTexture(engine, resources, R.drawable.floor_normal, TextureType.NORMAL)
|
||||
aoRoughnessMetallic = loadTexture(engine, resources,
|
||||
R.drawable.floor_ao_roughness_metallic, TextureType.DATA)
|
||||
|
||||
// A texture sampler does not need to be kept around or destroyed
|
||||
val sampler = TextureSampler()
|
||||
sampler.anisotropy = 8.0f
|
||||
|
||||
materialInstance.setParameter("baseColor", baseColor, sampler)
|
||||
materialInstance.setParameter("normal", normal, sampler)
|
||||
materialInstance.setParameter("aoRoughnessMetallic", aoRoughnessMetallic, sampler)
|
||||
}
|
||||
|
||||
private fun loadImageBasedLight() {
|
||||
ibl = loadIbl(assets, "envs/venetian_crossroads_2k", engine)
|
||||
ibl.indirectLight.intensity = 40_000.0f
|
||||
}
|
||||
|
||||
private fun startAnimation() {
|
||||
// Animate the triangle
|
||||
animator.interpolator = LinearInterpolator()
|
||||
animator.duration = 18_000
|
||||
animator.repeatMode = ValueAnimator.RESTART
|
||||
animator.repeatCount = ValueAnimator.INFINITE
|
||||
animator.addUpdateListener { a ->
|
||||
val v = (a.animatedValue as Float)
|
||||
camera.lookAt(cos(v) * 4.5, 1.5, sin(v) * 4.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
|
||||
}
|
||||
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
|
||||
destroyMesh(engine, mesh)
|
||||
destroyIbl(engine, ibl)
|
||||
engine.destroyTexture(baseColor)
|
||||
engine.destroyTexture(normal)
|
||||
engine.destroyTexture(aoRoughnessMetallic)
|
||||
engine.destroyEntity(light)
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyMaterialInstance(materialInstance)
|
||||
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(light)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
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 aspect = width.toDouble() / height.toDouble()
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
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,248 @@
|
||||
/*
|
||||
* 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.textured
|
||||
|
||||
import android.content.res.AssetManager
|
||||
import android.util.Log
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.VertexBuffer.AttributeType.*
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute.*
|
||||
|
||||
import java.io.InputStream
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.nio.channels.Channels
|
||||
import java.nio.channels.ReadableByteChannel
|
||||
|
||||
data class Mesh(
|
||||
@Entity val renderable: Int,
|
||||
val indexBuffer: IndexBuffer,
|
||||
val vertexBuffer: VertexBuffer,
|
||||
val aabb: Box)
|
||||
|
||||
fun destroyMesh(engine: Engine, mesh: Mesh) {
|
||||
engine.destroyEntity(mesh.renderable)
|
||||
engine.destroyIndexBuffer(mesh.indexBuffer)
|
||||
engine.destroyVertexBuffer(mesh.vertexBuffer)
|
||||
EntityManager.get().destroy(mesh.renderable)
|
||||
}
|
||||
|
||||
fun loadMesh(assets: AssetManager, name: String,
|
||||
materials: Map<String, MaterialInstance>, engine: Engine): Mesh {
|
||||
// See tools/filamesh/README.md for a description of the filamesh file format
|
||||
assets.open(name).use { input ->
|
||||
val header = readHeader(input)
|
||||
|
||||
val channel = Channels.newChannel(input)
|
||||
val vertexBufferData = readSizedData(channel, header.verticesSizeInBytes)
|
||||
val indexBufferData = readSizedData(channel, header.indicesSizeInBytes)
|
||||
|
||||
val parts = readParts(header, input)
|
||||
val definedMaterials = readMaterials(input)
|
||||
|
||||
val indexBuffer = createIndexBuffer(engine, header, indexBufferData)
|
||||
val vertexBuffer = createVertexBuffer(engine, header, vertexBufferData)
|
||||
|
||||
val renderable = createRenderable(
|
||||
engine, header, indexBuffer, vertexBuffer, parts, definedMaterials, materials)
|
||||
|
||||
return Mesh(renderable, indexBuffer, vertexBuffer, header.aabb)
|
||||
}
|
||||
}
|
||||
|
||||
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
|
||||
private const val MAX_UINT32 = 4294967295
|
||||
|
||||
private class Header {
|
||||
var valid = false
|
||||
var versionNumber = 0L
|
||||
var parts = 0L
|
||||
var aabb = Box()
|
||||
var interleaved = 0L
|
||||
var posOffset = 0L
|
||||
var positionStride = 0L
|
||||
var tangentOffset = 0L
|
||||
var tangentStride = 0L
|
||||
var colorOffset = 0L
|
||||
var colorStride = 0L
|
||||
var uv0Offset = 0L
|
||||
var uv0Stride = 0L
|
||||
var uv1Offset = 0L
|
||||
var uv1Stride = 0L
|
||||
var totalVertices = 0L
|
||||
var verticesSizeInBytes = 0L
|
||||
var indices16Bit = 0L
|
||||
var totalIndices = 0L
|
||||
var indicesSizeInBytes = 0L
|
||||
}
|
||||
|
||||
private class Part {
|
||||
var offset = 0L
|
||||
var indexCount = 0L
|
||||
var minIndex = 0L
|
||||
var maxIndex = 0L
|
||||
var materialID = 0L
|
||||
var aabb = Box()
|
||||
}
|
||||
|
||||
private fun readMagicNumber(input: InputStream): Boolean {
|
||||
val temp = ByteArray(FILAMESH_FILE_IDENTIFIER.length)
|
||||
input.read(temp)
|
||||
val tempS = String(temp, Charset.forName("UTF-8"))
|
||||
return tempS == FILAMESH_FILE_IDENTIFIER
|
||||
}
|
||||
|
||||
private fun readHeader(input: InputStream): Header {
|
||||
val header = Header()
|
||||
|
||||
if (!readMagicNumber(input)) {
|
||||
Log.e("Filament", "Invalid filamesh file.")
|
||||
return header
|
||||
}
|
||||
|
||||
header.versionNumber = readUIntLE(input)
|
||||
header.parts = readUIntLE(input)
|
||||
header.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
header.interleaved = readUIntLE(input)
|
||||
header.posOffset = readUIntLE(input)
|
||||
header.positionStride = readUIntLE(input)
|
||||
header.tangentOffset = readUIntLE(input)
|
||||
header.tangentStride = readUIntLE(input)
|
||||
header.colorOffset = readUIntLE(input)
|
||||
header.colorStride = readUIntLE(input)
|
||||
header.uv0Offset = readUIntLE(input)
|
||||
header.uv0Stride = readUIntLE(input)
|
||||
header.uv1Offset = readUIntLE(input)
|
||||
header.uv1Stride = readUIntLE(input)
|
||||
header.totalVertices = readUIntLE(input)
|
||||
header.verticesSizeInBytes = readUIntLE(input)
|
||||
header.indices16Bit = readUIntLE(input)
|
||||
header.totalIndices = readUIntLE(input)
|
||||
header.indicesSizeInBytes = readUIntLE(input)
|
||||
|
||||
header.valid = true
|
||||
return header
|
||||
}
|
||||
|
||||
|
||||
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
|
||||
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
|
||||
buffer.order(ByteOrder.LITTLE_ENDIAN)
|
||||
channel.read(buffer)
|
||||
buffer.flip()
|
||||
return buffer
|
||||
}
|
||||
|
||||
private fun readParts(header: Header, input: InputStream): List<Part> {
|
||||
return List(header.parts.toInt()) {
|
||||
val p = Part()
|
||||
p.offset = readUIntLE(input)
|
||||
p.indexCount = readUIntLE(input)
|
||||
p.minIndex = readUIntLE(input)
|
||||
p.maxIndex = readUIntLE(input)
|
||||
p.materialID = readUIntLE(input)
|
||||
p.aabb = Box(
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
|
||||
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
private fun readMaterials(input: InputStream): List<String> {
|
||||
return List(readUIntLE(input).toInt()) {
|
||||
val data = ByteArray(readUIntLE(input).toInt())
|
||||
input.read(data)
|
||||
// Skip null terminator
|
||||
input.skip(1)
|
||||
data.toString(Charset.forName("UTF-8"))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer): IndexBuffer {
|
||||
val indexType = if (header.indices16Bit != 0L) {
|
||||
IndexBuffer.Builder.IndexType.USHORT
|
||||
} else {
|
||||
IndexBuffer.Builder.IndexType.UINT
|
||||
}
|
||||
|
||||
return IndexBuffer.Builder()
|
||||
.bufferType(indexType)
|
||||
.indexCount(header.totalIndices.toInt())
|
||||
.build(engine)
|
||||
.apply { setBuffer(engine, data) }
|
||||
}
|
||||
|
||||
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
|
||||
val vertexBufferBuilder = VertexBuffer.Builder()
|
||||
.bufferCount(1)
|
||||
.vertexCount(header.totalVertices.toInt())
|
||||
// We store colors as unsigned bytes (0..255) but the shader wants values in the 0..1
|
||||
// range so we must mark this attribute normalized
|
||||
.normalized(COLOR)
|
||||
// The same goes for the tangent frame: we store it as a signed short, but we want
|
||||
// values in 0..1 in the shader
|
||||
.normalized(TANGENTS)
|
||||
.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())
|
||||
|
||||
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
|
||||
vertexBufferBuilder
|
||||
.attribute(UV1, 0, HALF2, header.uv1Offset.toInt(), header.uv1Stride.toInt())
|
||||
}
|
||||
|
||||
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
|
||||
}
|
||||
|
||||
private fun createRenderable(
|
||||
engine: Engine,
|
||||
header: Header,
|
||||
indexBuffer: IndexBuffer,
|
||||
vertexBuffer: VertexBuffer,
|
||||
parts: List<Part>,
|
||||
definedMaterials: List<String>,
|
||||
materials: Map<String, MaterialInstance>): Int {
|
||||
|
||||
val builder = RenderableManager.Builder(header.parts.toInt()).boundingBox(header.aabb)
|
||||
|
||||
repeat(header.parts.toInt()) { i ->
|
||||
builder.geometry(i,
|
||||
RenderableManager.PrimitiveType.TRIANGLES,
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
parts[i].offset.toInt(),
|
||||
parts[i].minIndex.toInt(),
|
||||
parts[i].maxIndex.toInt(),
|
||||
parts[i].indexCount.toInt())
|
||||
|
||||
// Find a material in the supplied material map, otherwise we fall back to
|
||||
// the default material named "DefaultMaterial"
|
||||
val material = materials[definedMaterials[parts[i].materialID.toInt()]]
|
||||
material?.let {
|
||||
builder.material(i, material)
|
||||
} ?: builder.material(i, materials["DefaultMaterial"]!!)
|
||||
}
|
||||
|
||||
return EntityManager.get().create().apply { builder.build(engine, this) }
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.textured
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import com.google.android.filament.Engine
|
||||
import com.google.android.filament.Texture
|
||||
import com.google.android.filament.android.TextureHelper
|
||||
import java.lang.IllegalArgumentException
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
const val SKIP_BITMAP_COPY = true
|
||||
|
||||
enum class TextureType {
|
||||
COLOR,
|
||||
NORMAL,
|
||||
DATA
|
||||
}
|
||||
|
||||
fun loadTexture(engine: Engine, resources: Resources, resourceId: Int, type: TextureType): Texture {
|
||||
val options = BitmapFactory.Options()
|
||||
// Color is the only type of texture we want to pre-multiply with the alpha channel
|
||||
// Pre-multiplication is the default behavior, so we need to turn it off here
|
||||
options.inPremultiplied = type == TextureType.COLOR
|
||||
|
||||
val bitmap = BitmapFactory.decodeResource(resources, resourceId, options)
|
||||
|
||||
val texture = Texture.Builder()
|
||||
.width(bitmap.width)
|
||||
.height(bitmap.height)
|
||||
.sampler(Texture.Sampler.SAMPLER_2D)
|
||||
.format(internalFormat(type))
|
||||
// This tells Filament to figure out the number of mip levels
|
||||
.levels(0xff)
|
||||
.build(engine)
|
||||
|
||||
// TextureHelper offers a method that skips the copy of the bitmap into a ByteBuffer
|
||||
if (SKIP_BITMAP_COPY) {
|
||||
TextureHelper.setBitmap(engine, texture, 0, bitmap)
|
||||
} else {
|
||||
val buffer = ByteBuffer.allocateDirect(bitmap.byteCount)
|
||||
bitmap.copyPixelsToBuffer(buffer)
|
||||
// Do not forget to rewind the buffer!
|
||||
buffer.flip()
|
||||
|
||||
val descriptor = Texture.PixelBufferDescriptor(
|
||||
buffer,
|
||||
format(bitmap),
|
||||
type(bitmap))
|
||||
|
||||
texture.setImage(engine, 0, descriptor)
|
||||
}
|
||||
|
||||
texture.generateMipmaps(engine)
|
||||
|
||||
return texture
|
||||
}
|
||||
|
||||
private fun internalFormat(type: TextureType) = when (type) {
|
||||
TextureType.COLOR -> Texture.InternalFormat.SRGB8_A8
|
||||
TextureType.NORMAL -> Texture.InternalFormat.RGBA8
|
||||
TextureType.DATA -> Texture.InternalFormat.RGBA8
|
||||
}
|
||||
|
||||
// Not required when SKIP_BITMAP_COPY is true
|
||||
private fun format(bitmap: Bitmap) = when (bitmap.config) {
|
||||
Bitmap.Config.ALPHA_8 -> Texture.Format.ALPHA
|
||||
Bitmap.Config.RGB_565 -> Texture.Format.RGB
|
||||
Bitmap.Config.ARGB_8888 -> Texture.Format.RGBA
|
||||
Bitmap.Config.RGBA_F16 -> Texture.Format.RGBA
|
||||
else -> throw IllegalArgumentException("Unknown bitmap configuration")
|
||||
}
|
||||
|
||||
// Not required when SKIP_BITMAP_COPY is true
|
||||
private fun type(bitmap: Bitmap) = when (bitmap.config) {
|
||||
Bitmap.Config.ALPHA_8 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.RGB_565 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.ARGB_8888 -> Texture.Type.UBYTE
|
||||
Bitmap.Config.RGBA_F16 -> Texture.Type.HALF
|
||||
else -> throw IllegalArgumentException("Unsupported bitmap configuration")
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// Textured material
|
||||
|
||||
material {
|
||||
name : textured_pbr,
|
||||
shadingModel : lit,
|
||||
parameters : [
|
||||
// Base color sRGB texture
|
||||
{
|
||||
type : sampler2d,
|
||||
name : baseColor
|
||||
},
|
||||
// Packed ambient occlusion/roughness/metallic RGB texture
|
||||
{
|
||||
type : sampler2d,
|
||||
name : aoRoughnessMetallic
|
||||
},
|
||||
// Normal map RGB texture
|
||||
{
|
||||
type : sampler2d,
|
||||
name : normal
|
||||
}
|
||||
],
|
||||
// To sample textures our material must declare that it requires
|
||||
// a set of UV coordinates from the rendered mesh
|
||||
requires: [
|
||||
uv0
|
||||
]
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
// The normal map must be set *before* calling prepareMaterial()
|
||||
material.normal = texture(materialParams_normal, getUV0()).xyz * 2.0 - 1.0;
|
||||
|
||||
prepareMaterial(material);
|
||||
|
||||
material.baseColor = texture(materialParams_baseColor, getUV0());
|
||||
|
||||
vec3 aoRoughnessMetallic = texture(materialParams_aoRoughnessMetallic, getUV0()).rgb;
|
||||
material.ambientOcclusion = aoRoughnessMetallic.r;
|
||||
material.roughness = aoRoughnessMetallic.g;
|
||||
material.metallic = aoRoughnessMetallic.b;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 678 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
@@ -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">Textured Object</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/textured-object/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.0'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.2.1'
|
||||
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/textured-object/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/textured-object/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
android/samples/textured-object/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Tue Aug 28 15:45:13 PDT 2018
|
||||
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
|
||||
172
android/samples/textured-object/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/textured-object/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/textured-object/settings.gradle
Normal file
@@ -0,0 +1,3 @@
|
||||
includeBuild '../../filament-android'
|
||||
|
||||
include ':app'
|
||||
156
build.sh
@@ -3,8 +3,9 @@ set -e
|
||||
|
||||
# NDK API level
|
||||
API_LEVEL=24
|
||||
# Host tools required by Android and WebGL builds
|
||||
# Host tools required by Android, WebGL, and iOS builds
|
||||
HOST_TOOLS="matc cmgen filamesh mipgen"
|
||||
IOS_TOOLCHAIN_URL="https://opensource.apple.com/source/clang/clang-800.0.38/src/cmake/platforms/iOS.cmake"
|
||||
|
||||
function print_help {
|
||||
local SELF_NAME=`basename $0`
|
||||
@@ -26,10 +27,10 @@ function print_help {
|
||||
echo " Do not compile desktop Java projects"
|
||||
echo " -m"
|
||||
echo " Compile with make instead of ninja."
|
||||
echo " -p [desktop|android|webgl|all]"
|
||||
echo " -p [desktop|android|ios|webgl|all]"
|
||||
echo " Platform(s) to build, defaults to desktop."
|
||||
echo " Building android will automatically generate the toolchains if needed and"
|
||||
echo " perform a partial desktop build."
|
||||
echo " Building for Android or iOS will automatically generate / download"
|
||||
echo " the toolchains if needed and perform a partial desktop build."
|
||||
echo " -r"
|
||||
echo " Restrict the number of make/ninja jobs."
|
||||
echo " -t"
|
||||
@@ -38,6 +39,8 @@ function print_help {
|
||||
echo " Run all unit tests, will trigger a debug build if needed."
|
||||
echo " -v"
|
||||
echo " Add Vulkan support to the Android build."
|
||||
echo " -s"
|
||||
echo " Add iOS simulator support to the iOS build."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -71,6 +74,7 @@ ISSUE_DEBUG_BUILD=false
|
||||
ISSUE_RELEASE_BUILD=false
|
||||
|
||||
ISSUE_ANDROID_BUILD=false
|
||||
ISSUE_IOS_BUILD=false
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
|
||||
@@ -88,6 +92,8 @@ GENERATE_TOOLCHAINS=false
|
||||
|
||||
VULKAN_ANDROID_OPTION="-DFILAMENT_SUPPORTS_VULKAN=OFF"
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
|
||||
BUILD_GENERATOR=Ninja
|
||||
BUILD_COMMAND=ninja
|
||||
BUILD_CUSTOM_TARGETS=
|
||||
@@ -213,12 +219,32 @@ function build_webgl_with_target {
|
||||
${BUILD_COMMAND} ${BUILD_TARGETS}
|
||||
fi
|
||||
|
||||
if [ -d "samples/web/public" ]; then
|
||||
if [ -d "web/filament-js" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
|
||||
which -s python3
|
||||
if [ $? == 0 ]; then
|
||||
echo "Generating JavaScript documentation..."
|
||||
local DOCS_FOLDER="web/docs"
|
||||
local DOCS_SCRIPT="../../web/docs/build.py"
|
||||
python3 ${DOCS_SCRIPT} --disable-demo \
|
||||
--output-folder ${DOCS_FOLDER} \
|
||||
--build-folder ${PWD}
|
||||
fi
|
||||
|
||||
echo "Generating out/filament-${LC_TARGET}-web.tgz..."
|
||||
cd samples/web/public
|
||||
tar -czvf ../../../../filament-${LC_TARGET}-web.tgz .
|
||||
# The web archive has the following subfolders:
|
||||
# dist...core WASM module and accompanying JS file.
|
||||
# docs...HTML tutorials for the JS API, accompanying demos, and a reference page.
|
||||
cd web
|
||||
tar -cvf ../../filament-${LC_TARGET}-web.tar -s /^filament-js/dist/ \
|
||||
filament-js/filament.js
|
||||
tar -rvf ../../filament-${LC_TARGET}-web.tar -s /^filament-js/dist/ \
|
||||
filament-js/filament.wasm
|
||||
tar -rvf ../../filament-${LC_TARGET}-web.tar docs
|
||||
cd -
|
||||
gzip -c ../filament-${LC_TARGET}-web.tar > ../filament-${LC_TARGET}-web.tgz
|
||||
rm ../filament-${LC_TARGET}-web.tar
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -346,6 +372,100 @@ function build_android {
|
||||
cd ../..
|
||||
}
|
||||
|
||||
function ensure_ios_toolchain {
|
||||
local TOOLCHAIN_PATH="build/toolchain-mac-ios.cmake"
|
||||
if [ -e ${TOOLCHAIN_PATH} ]; then
|
||||
echo "iOS toolchain file exists."
|
||||
return 0
|
||||
fi
|
||||
echo
|
||||
echo "iOS toolchain file does not exist."
|
||||
echo "It will automatically be downloaded from http://opensource.apple.com."
|
||||
read -p "Continue? (y/n) " -n 1 -r
|
||||
echo
|
||||
if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then
|
||||
echo "Toolchain file must be downloaded to continue."
|
||||
exit 1
|
||||
fi
|
||||
curl -o "${TOOLCHAIN_PATH}" "${IOS_TOOLCHAIN_URL}" || {
|
||||
echo "Error downloading iOS toolchain file."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Apple's toolchain hard-codes the PLATFORM_NAME into the toolchain file. Instead, make this a
|
||||
# CACHE variable that can be overriden on the command line.
|
||||
local FIND='SET(PLATFORM_NAME iphoneos)'
|
||||
local REPLACE='SET(PLATFORM_NAME "iphoneos" CACHE STRING "iOS platform to build for")'
|
||||
sed -i '' "s/${FIND}/${REPLACE}/g" ./${TOOLCHAIN_PATH}
|
||||
|
||||
# Append Filament-specific settings.
|
||||
cat build/toolchain-mac-ios.filament.cmake >> ${TOOLCHAIN_PATH}
|
||||
|
||||
echo "Successfully downloaded iOS toolchain file and appended Filament-specific settings."
|
||||
}
|
||||
|
||||
function build_ios_target {
|
||||
local LC_TARGET=`echo $1 | tr '[:upper:]' '[:lower:]'`
|
||||
local ARCH=$2
|
||||
local PLATFORM=$3
|
||||
|
||||
echo "Building iOS $LC_TARGET ($ARCH) for $PLATFORM..."
|
||||
mkdir -p out/cmake-ios-${LC_TARGET}-${ARCH}
|
||||
|
||||
cd out/cmake-ios-${LC_TARGET}-${ARCH}
|
||||
|
||||
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
|
||||
cmake \
|
||||
-G "$BUILD_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE=$1 \
|
||||
-DCMAKE_INSTALL_PREFIX=../ios-${LC_TARGET}/filament \
|
||||
-DIOS_ARCH=${ARCH} \
|
||||
-DPLATFORM_NAME=${PLATFORM} \
|
||||
-DIOS=1 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-mac-ios.cmake \
|
||||
../..
|
||||
fi
|
||||
|
||||
${BUILD_COMMAND} install
|
||||
|
||||
if [ -d "../ios-${LC_TARGET}/filament" ]; then
|
||||
if [ "$ISSUE_ARCHIVES" == "true" ]; then
|
||||
echo "Generating out/filament-${LC_TARGET}-ios.tgz..."
|
||||
cd ../ios-${LC_TARGET}
|
||||
tar -czvf ../filament-${LC_TARGET}-ios.tgz filament
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
}
|
||||
|
||||
function build_ios {
|
||||
# Supress intermediate desktop tools install
|
||||
OLD_INSTALL_COMMAND=${INSTALL_COMMAND}
|
||||
INSTALL_COMMAND=
|
||||
build_desktop "${HOST_TOOLS}"
|
||||
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
|
||||
|
||||
ensure_ios_toolchain
|
||||
|
||||
# In theory, we could support iPhone architectures older than arm64, but
|
||||
# only arm64 devices support OpenGL 3.0 / Metal
|
||||
|
||||
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
|
||||
build_ios_target "Debug" "arm64" "iphoneos"
|
||||
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
|
||||
build_ios_target "Debug" "x86_64" "iphonesimulator"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
|
||||
build_ios_target "Release" "arm64" "iphoneos"
|
||||
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
|
||||
build_ios_target "Release" "x86_64" "iphonesimulator"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function validate_build_command {
|
||||
set +e
|
||||
# Make sure CMake is installed
|
||||
@@ -354,7 +474,7 @@ function validate_build_command {
|
||||
echo "Error: could not find cmake, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Make sure Ninja is installed
|
||||
if [ "$BUILD_COMMAND" == "ninja" ]; then
|
||||
ninja_binary=`which ninja`
|
||||
@@ -405,7 +525,7 @@ function run_tests {
|
||||
|
||||
pushd `dirname $0` > /dev/null
|
||||
|
||||
while getopts ":hacfijmp:tuv" opt; do
|
||||
while getopts ":hacfijmp:tuvs" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -435,21 +555,31 @@ while getopts ":hacfijmp:tuv" opt; do
|
||||
case $OPTARG in
|
||||
desktop)
|
||||
ISSUE_ANDROID_BUILD=false
|
||||
ISSUE_IOS_BUILD=false
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
;;
|
||||
android)
|
||||
ISSUE_ANDROID_BUILD=true
|
||||
ISSUE_IOS_BUILD=false
|
||||
ISSUE_DESKTOP_BUILD=false
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
;;
|
||||
ios)
|
||||
ISSUE_ANDROID_BUILD=false
|
||||
ISSUE_IOS_BUILD=true
|
||||
ISSUE_DESKTOP_BUILD=false
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
;;
|
||||
webgl)
|
||||
ISSUE_ANDROID_BUILD=false
|
||||
ISSUE_IOS_BUILD=false
|
||||
ISSUE_DESKTOP_BUILD=false
|
||||
ISSUE_WEBGL_BUILD=true
|
||||
;;
|
||||
all)
|
||||
ISSUE_ANDROID_BUILD=true
|
||||
ISSUE_IOS_BUILD=true
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
;;
|
||||
@@ -472,6 +602,10 @@ while getopts ":hacfijmp:tuv" opt; do
|
||||
echo "Also be sure to pass Backend::VULKAN to Engine::create."
|
||||
echo ""
|
||||
;;
|
||||
s)
|
||||
IOS_BUILD_SIMULATOR=true
|
||||
echo "iOS simulator support enabled."
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -$OPTARG" >&2
|
||||
echo ""
|
||||
@@ -522,6 +656,10 @@ if [ "$ISSUE_ANDROID_BUILD" == "true" ]; then
|
||||
build_android
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_IOS_BUILD" == "true" ]; then
|
||||
build_ios
|
||||
fi
|
||||
|
||||
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
|
||||
build_webgl
|
||||
fi
|
||||
|
||||
2
build/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# File is generated by ../build.sh and should not be tracked
|
||||
toolchain-mac-ios.cmake
|
||||
22
build/ios/build.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
set -e
|
||||
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 prompts the user to download Apple's iOS toolchain
|
||||
yes | ./build.sh -p ios -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
6
build/ios/ci-common.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
10
build/ios/common.cfg
Normal file
@@ -0,0 +1,10 @@
|
||||
# Format: //devtools/kokoro/config/proto/build.proto
|
||||
|
||||
action {
|
||||
define_artifacts {
|
||||
regex: "github/filament/out/*.tgz"
|
||||
regex: "github/filament/out/*.aar"
|
||||
strip_prefix: "github/filament/out"
|
||||
regex: "**/*sponge_log.xml"
|
||||
}
|
||||
}
|
||||
3
build/ios/continuous.cfg
Normal file
@@ -0,0 +1,3 @@
|
||||
# Format: //devtools/kokoro/config/proto/build.proto
|
||||
|
||||
build_file: "filament/build/ios/build.sh"
|
||||
3
build/ios/presubmit.cfg
Normal file
@@ -0,0 +1,3 @@
|
||||
# Format: //devtools/kokoro/config/proto/build.proto
|
||||
|
||||
build_file: "filament/build/ios/build.sh"
|
||||
3
build/ios/release.cfg
Normal file
@@ -0,0 +1,3 @@
|
||||
# Format: //devtools/kokoro/config/proto/build.proto
|
||||
|
||||
build_file: "filament/build/ios/build.sh"
|
||||
15
build/toolchain-mac-ios.filament.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
# ==================================================================================================
|
||||
# Filament-specific settings
|
||||
# The rest of the toolchain is downloaded from Apple Open Source and appended.
|
||||
# ==================================================================================================
|
||||
|
||||
set(CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
|
||||
|
||||
# Necessary for correct install location
|
||||
set(DIST_ARCH ${IOS_ARCH})
|
||||
|
||||
add_definitions(-DIOS)
|
||||
|
||||
# ==================================================================================================
|
||||
# End Filament-specific settings
|
||||
# ==================================================================================================
|
||||
@@ -5,6 +5,11 @@ unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
# The Kokoro machines have Python 3.6.3 installed. Let's verify that here, and install the
|
||||
# distributions required for web/docs.
|
||||
python3 --version
|
||||
pip3 install mistletoe pygments jsbeautifier
|
||||
|
||||
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
|
||||
unzip emsdk.zip
|
||||
mv emsdk-* emsdk
|
||||
|
||||
@@ -23,6 +23,9 @@ mkdir out\cmake-release
|
||||
cd out\cmake-release
|
||||
if errorlevel 1 exit /b %errorlevel%
|
||||
|
||||
:: Force Java JDK 8. Kokoro machines default to 9
|
||||
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0_152
|
||||
|
||||
cmake ..\.. -G Ninja ^
|
||||
-DCMAKE_CXX_COMPILER:PATH="clang-cl.exe" ^
|
||||
-DCMAKE_C_COMPILER:PATH="clang-cl.exe" ^
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
if defined KOKORO_BUILD_ID (
|
||||
choco install llvm --version 6.0.1 -y
|
||||
if errorlevel 1 exit /b %errorlevel%
|
||||
|
||||
:: retry if choco install failed
|
||||
if errorlevel 1 (
|
||||
choco install llvm --version 6.0.1 -y
|
||||
if errorlevel 1 exit /b %errorlevel%
|
||||
)
|
||||
|
||||
:: refreshenv is necessary to put LLVM on path
|
||||
refreshenv
|
||||
|
||||
@@ -3402,7 +3402,7 @@ To compute the specular color of a material we need to evaluate the complex Fres
|
||||
|
||||
We then sum (integrate) and normalize all the samples to obtain $\fNormal$ in the XYZ color space. From there, a simple color space conversion yields a linear sRGB color or a non-linear sRGB color after applying the opto-electronic transfer function (OETF, commonly known as "gamma" curve). Note that for some materials such as gold the final sRGB color might fall out of gamut. We use a simple normalization step as a cheap form of gamut remapping but it would be interesting to consider computing values in a color space with a wider gamut (for instance BT.2020).
|
||||
|
||||
To achieve the desired result we used the ICE 1931 2 degrees CMFs, from 360nm to 830nm at 1nm intervals ([source](http://cvrl.ioo.ucl.ac.uk/cmfs.htm)), and the CIE Standard Illuminant D65 relative spectral power distribution, from 300nm to 830nm, at 5nm intervals ([source](https://cielab.xyz/pdf/CIE_sel_colorimetric_tables.xls)).
|
||||
To achieve the desired result we used the ICE 1931 2 degrees CMFs, from 360nm to 830nm at 1nm intervals ([source](http://cvrl.ioo.ucl.ac.uk/cmfs.htm)), and the CIE Standard Illuminant D65 relative spectral power distribution, from 300nm to 830nm, at 5nm intervals ([source](http://files.cie.co.at/204.xls)).
|
||||
|
||||
Our implementation is presented in listing [specularColorImpl], with the actual data omitted for brevity.
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ Velvet is an interesting use case for a cloth material model. As shown in figure
|
||||
this type of fabric exhibits strong rim lighting due to forward and backward scattering. These
|
||||
scattering events are caused by fibers standing straight at the surface of the fabric. When the
|
||||
incident light comes from the direction opposite to the view direction, the fibers will forward
|
||||
scatter the light. Similarly, when the incident light from from the same direction as the view
|
||||
scatter the light. Similarly, when the incident light from the same direction as the view
|
||||
direction, the fibers will scatter the light backward.
|
||||
|
||||
![Figure [materialVelvet]: Velvet fabric showcasing forward and
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -9,7 +9,7 @@ set(PUBLIC_HDR_DIR include)
|
||||
# ==================================================================================================
|
||||
set(PUBLIC_HDRS
|
||||
include/filament/driver/BufferDescriptor.h
|
||||
include/filament/driver/ExternalContext.h
|
||||
include/filament/driver/Platform.h
|
||||
include/filament/driver/PixelBufferDescriptor.h
|
||||
include/filament/Box.h
|
||||
include/filament/Camera.h
|
||||
@@ -53,12 +53,11 @@ set(SRCS
|
||||
src/driver/CircularBuffer.cpp
|
||||
src/driver/Driver.cpp
|
||||
src/driver/DriverAPI.inc
|
||||
src/driver/ExternalContext.cpp
|
||||
src/driver/Platform.cpp
|
||||
src/driver/GPUBuffer.cpp
|
||||
src/driver/Handle.cpp
|
||||
src/driver/Program.cpp
|
||||
src/driver/SamplerBuffer.cpp
|
||||
src/driver/UniformBuffer.cpp
|
||||
src/Box.cpp
|
||||
src/Camera.cpp
|
||||
src/Color.cpp
|
||||
@@ -75,7 +74,6 @@ set(SRCS
|
||||
src/Frustum.cpp
|
||||
src/IndexBuffer.cpp
|
||||
src/IndirectLight.cpp
|
||||
src/GpuLightBuffer.cpp
|
||||
src/Material.cpp
|
||||
src/MaterialInstance.cpp
|
||||
src/PostProcessManager.cpp
|
||||
@@ -90,6 +88,7 @@ set(SRCS
|
||||
src/SwapChain.cpp
|
||||
src/Stream.cpp
|
||||
src/Texture.cpp
|
||||
src/UniformBuffer.cpp
|
||||
src/View.cpp
|
||||
src/Viewport.cpp
|
||||
)
|
||||
@@ -110,7 +109,6 @@ set(PRIVATE_HDRS
|
||||
src/details/Froxelizer.h
|
||||
src/details/IndexBuffer.h
|
||||
src/details/IndirectLight.h
|
||||
src/details/GpuLightBuffer.h
|
||||
src/details/Material.h
|
||||
src/details/MaterialInstance.h
|
||||
src/details/RenderPrimitive.h
|
||||
@@ -136,7 +134,6 @@ set(PRIVATE_HDRS
|
||||
src/driver/Handle.h
|
||||
src/driver/Program.h
|
||||
src/driver/SamplerBuffer.h
|
||||
src/driver/UniformBuffer.h
|
||||
src/FilamentAPI-impl.h
|
||||
src/FrameInfo.h
|
||||
src/Intersections.h
|
||||
@@ -144,6 +141,7 @@ set(PRIVATE_HDRS
|
||||
src/PrecompiledMaterials.h
|
||||
src/RenderPass.h
|
||||
src/RenderTargetPool.h
|
||||
src/UniformBuffer.h
|
||||
src/upcast.h)
|
||||
|
||||
set(MATERIAL_SRCS
|
||||
@@ -158,24 +156,34 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
list(APPEND SRCS src/driver/noop/NoopDriver.cpp)
|
||||
endif()
|
||||
|
||||
if(IOS AND NOT FILAMENT_SUPPORTS_VULKAN)
|
||||
message(FATAL_ERROR "Filament for iOS must be built with Vulkan support.")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# OS specific
|
||||
# ==================================================================================================
|
||||
|
||||
# Here set the architecture specific sources
|
||||
if (USE_EXTERNAL_GLES3)
|
||||
# Experimental feature; clients provide their own Context Manager.
|
||||
elseif (ANDROID)
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerEGL.cpp)
|
||||
list(APPEND SRCS src/driver/android/ExternalStreamManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/driver/android/ExternalTextureManagerAndroid.cpp)
|
||||
list(APPEND SRCS src/driver/android/VirtualMachineEnv.cpp)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformEGL.cpp)
|
||||
elseif (IOS)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformCocoaTouchGL.mm)
|
||||
elseif (APPLE)
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerCocoa.mm)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformCocoaGL.mm)
|
||||
elseif (WEBGL)
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerWebGL.cpp)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformWebGL.cpp)
|
||||
elseif (LINUX)
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerGLX.cpp)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformGLX.cpp)
|
||||
elseif (WIN32)
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerWGL.cpp)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformWGL.cpp)
|
||||
else()
|
||||
list(APPEND SRCS src/driver/opengl/ContextManagerDummy.cpp)
|
||||
list(APPEND SRCS src/driver/opengl/PlatformDummyGL.cpp)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
@@ -184,8 +192,6 @@ endif()
|
||||
# "2" corresponds to SYSTRACE_TAG_FILEMENT (See: utils/Systrace.h)
|
||||
add_definitions(-DSYSTRACE_TAG=2 )
|
||||
|
||||
add_definitions(-DFILAMENT_DRIVER_SUPPORTS_OPENGL)
|
||||
|
||||
# ==================================================================================================
|
||||
# Vulkan Sources
|
||||
# ==================================================================================================
|
||||
@@ -203,13 +209,15 @@ if (FILAMENT_SUPPORTS_VULKAN)
|
||||
src/driver/vulkan/VulkanStagePool.cpp
|
||||
)
|
||||
if (LINUX)
|
||||
list(APPEND SRCS src/driver/vulkan/ContextManagerVkLinux.cpp)
|
||||
elseif (APPLE)
|
||||
list(APPEND SRCS src/driver/vulkan/ContextManagerVkCocoa.mm)
|
||||
list(APPEND SRCS src/driver/vulkan/PlatformVkLinux.cpp)
|
||||
elseif (APPLE AND NOT IOS)
|
||||
list(APPEND SRCS src/driver/vulkan/PlatformVkCocoa.mm)
|
||||
elseif (IOS)
|
||||
list(APPEND SRCS src/driver/vulkan/PlatformVkCocoaTouch.mm)
|
||||
elseif (ANDROID)
|
||||
list(APPEND SRCS src/driver/vulkan/ContextManagerVkAndroid.cpp)
|
||||
list(APPEND SRCS src/driver/vulkan/PlatformVkAndroid.cpp)
|
||||
elseif (WIN32)
|
||||
list(APPEND SRCS src/driver/vulkan/ContextManagerVkWindows.cpp)
|
||||
list(APPEND SRCS src/driver/vulkan/PlatformVkWindows.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -226,7 +234,7 @@ set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR})
|
||||
file(MAKE_DIRECTORY "${GENERATION_ROOT}/generated/material/")
|
||||
|
||||
# Target system.
|
||||
if (ANDROID OR WEBGL)
|
||||
if (ANDROID OR WEBGL OR IOS)
|
||||
set(MATC_TARGET mobile)
|
||||
else()
|
||||
set(MATC_TARGET desktop)
|
||||
@@ -302,17 +310,11 @@ target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
# Dependencies
|
||||
# ==================================================================================================
|
||||
|
||||
set(DARWIN_LINK_LIBRARIES bluegl bluevk)
|
||||
set(WIN32_LINK_LIBRARIES bluegl)
|
||||
|
||||
if (ANDROID)
|
||||
target_link_libraries(${TARGET} PUBLIC GLESv3 EGL android)
|
||||
set(LINUX_LINK_LIBRARIES )
|
||||
else()
|
||||
set(LINUX_LINK_LIBRARIES bluegl)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
if (APPLE AND NOT IOS)
|
||||
target_link_libraries(${TARGET} PRIVATE "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
@@ -322,6 +324,11 @@ target_link_libraries(${TARGET} PUBLIC filaflat)
|
||||
target_link_libraries(${TARGET} PUBLIC filabridge)
|
||||
target_link_libraries(${TARGET} PUBLIC image_headers)
|
||||
|
||||
# Android and iOS link directly against platform-specific OpenGL ES libraries
|
||||
if(NOT IOS AND NOT ANDROID)
|
||||
target_link_libraries(${TARGET} PRIVATE bluegl)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
target_link_libraries(${TARGET} PUBLIC bluevk vkmemalloc)
|
||||
endif()
|
||||
@@ -330,12 +337,6 @@ if (LINUX)
|
||||
target_link_libraries(${TARGET} PRIVATE dl)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${TARGET} PRIVATE
|
||||
"$<$<PLATFORM_ID:Darwin>:${DARWIN_LINK_LIBRARIES}>"
|
||||
"$<$<PLATFORM_ID:Linux>:${LINUX_LINK_LIBRARIES}>"
|
||||
"$<$<PLATFORM_ID:Windows>:${WIN32_LINK_LIBRARIES}>"
|
||||
)
|
||||
|
||||
# ==================================================================================================
|
||||
# Compiler flags
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -11,7 +11,7 @@ Filament. Latest versions are available on the [project page](https://github.com
|
||||
- `matinfo`, Displays information about materials compiled with `matc`
|
||||
- `mipgen`, Generates a series of miplevels from a source image.
|
||||
- `normal-blending`, Tool to blend normal maps
|
||||
- `roughness-prefilter`, Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `roughness-prefilter`, Pre-filters a roughness map from a normal map to reduce aliasing
|
||||
- `skygen`, Physically-based sky environment texture generator
|
||||
- `specular-color`, Computes the specular color of conductors based on spectral data
|
||||
|
||||
@@ -29,10 +29,119 @@ Filament is distributed as a set of static libraries you must link against:
|
||||
- `utils`, Support library for Filament
|
||||
|
||||
To use Filament from Java you must use the following two libraries instead:
|
||||
- `filament-java.jar`, Contains Filament's Java classes
|
||||
- `filament-java.jar`, Contains Filament's Java classes
|
||||
- `filament-jni`, Filament's JNI bindings
|
||||
|
||||
To use the Vulkan backend on macOS you must also make the following libraries available at runtime:
|
||||
- `MoltenVK_icd.json`
|
||||
- `libMoltenVK.dylib`
|
||||
- `libMoltenVK.dylib`
|
||||
- `vulkan.1.dylib`
|
||||
|
||||
## Linking against Filament
|
||||
|
||||
This walkthrough will get you successfully compiling and linking native code
|
||||
against Filament with minimum dependencies.
|
||||
|
||||
To start, download Filament's [latest binary release](https://github.com/google/filament/releases)
|
||||
and extract into a directory of your choosing. Binary releases are suffixed
|
||||
with the platform name, for example, `filament-20181009-linux.tgz`.
|
||||
|
||||
Create a file, `main.cpp`, in the same directory with the following contents:
|
||||
|
||||
```
|
||||
#include <filament/FilamentAPI.h>
|
||||
#include <filament/Engine.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Engine *engine = Engine::create();
|
||||
engine->destroy(&engine);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
The directory should look like:
|
||||
|
||||
```
|
||||
|-- README.md
|
||||
|-- bin
|
||||
|-- docs
|
||||
|-- include
|
||||
|-- lib
|
||||
|-- main.cpp
|
||||
```
|
||||
|
||||
We'll use a platform-specific Makefile to compile and link `main.cpp` with Filament's libraries.
|
||||
Copy your platform's Makefile below into a `Makefile` inside the same directory.
|
||||
|
||||
### Linux
|
||||
|
||||
```
|
||||
FILAMENT_LIBS=-lfilament -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils
|
||||
CC=clang++
|
||||
|
||||
main: main.o
|
||||
$(CC) -Llib/x86_64/ main.o $(FILAMENT_LIBS) -lpthread -lc++ -ldl -o main
|
||||
|
||||
main.o: main.cpp
|
||||
$(CC) -Iinclude/ -std=c++14 -pthread -c main.cpp
|
||||
|
||||
clean:
|
||||
rm -f main main.o
|
||||
|
||||
.PHONY: clean
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
```
|
||||
FILAMENT_LIBS=-lfilament -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils
|
||||
CC=clang++
|
||||
|
||||
main: main.o
|
||||
$(CC) -Llib/x86_64/ main.o $(FILAMENT_LIBS) -framework Cocoa -o main
|
||||
|
||||
main.o: main.cpp
|
||||
$(CC) -Iinclude/ -std=c++14 -c main.cpp
|
||||
|
||||
clean:
|
||||
rm -f main main.o
|
||||
|
||||
.PHONY: clean
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
```
|
||||
FILAMENT_LIBS=lib/x86_64/filament.lib lib/x86_64/bluegl.lib \
|
||||
lib/x86_64/filabridge.lib lib/x86_64/filaflat.lib lib/x86_64/utils.lib
|
||||
CC=clang-cl.exe
|
||||
|
||||
main.exe: main.obj
|
||||
$(CC) main.obj $(FILAMENT_LIBS) gdi32.lib user32.lib opengl32.lib
|
||||
|
||||
main.obj: main.cpp
|
||||
$(CC) /Iinclude/ /std:c++14 /c main.cpp
|
||||
|
||||
clean:
|
||||
del main.exe main.obj
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
```
|
||||
|
||||
### Compiling
|
||||
|
||||
You should be able to invoke `make` and run the executable successfully:
|
||||
|
||||
```
|
||||
$ make
|
||||
$ ./main
|
||||
FEngine (64 bits) created at 0x106471000 (threading is enabled)
|
||||
```
|
||||
|
||||
On Windows, you'll need to open up a Visual Studio Native Tools Command Prompt
|
||||
and invoke `nmake` instead of `make`.
|
||||
|
||||
|
||||
13
filament/docs/Versioning.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## Versioning
|
||||
|
||||
Filament uses a 3-number versioning scheme that superficially resembles a [semantic
|
||||
version](https://semver.org/) but is actually more interesting because of our material system. Here
|
||||
are the guidelines:
|
||||
|
||||
- Increment the **most significant** number only when making a non-backwards compatible API change,
|
||||
or when introducing a major new API.
|
||||
- Increment the **middle number** only when making a non-backwards compatible change to the material
|
||||
system. When this number gets bumped, users need to rebuild their mat files. Reset the middle
|
||||
number to zero when the most significant number has been incremented.
|
||||
- Increment the **least significant** number each time a new release is published. Reset this number
|
||||
to zero if one of the other two numbers have been incremented.
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec3.h>
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
|
||||
// FIXME: could we get rid of <utility>
|
||||
#include <utility>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <filament/Fence.h>
|
||||
#include <filament/SwapChain.h>
|
||||
|
||||
#include <filament/driver/ExternalContext.h>
|
||||
#include <filament/driver/Platform.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/EntityManager.h>
|
||||
@@ -142,29 +142,29 @@ class TransformManager;
|
||||
*/
|
||||
class UTILS_PUBLIC Engine {
|
||||
public:
|
||||
using ExternalContext = driver::ExternalContext;
|
||||
using Platform = driver::Platform;
|
||||
using Backend = driver::Backend;
|
||||
|
||||
/**
|
||||
* Creates an instance of Engine
|
||||
*
|
||||
* @param externalContext A pointer to an object that implements ExternalContext. If this is
|
||||
* provided, then this object is used to manage the hardware context
|
||||
* (e.g. OpenGL) lifecycle for filament.
|
||||
* @param platform A pointer to an object that implements Platform. If this is
|
||||
* provided, then this object is used to create the hardware context
|
||||
* and expose platform features to it.
|
||||
*
|
||||
* If not provided (or nullptr is used), an appropriate hardware
|
||||
* context is created automatically.
|
||||
* If not provided (or nullptr is used), an appropriate Platform
|
||||
* is created automatically.
|
||||
*
|
||||
* All methods of this interface are called from filament's
|
||||
* render thread, which is different from the main thread.
|
||||
*
|
||||
* The lifetime of \p externalContext must exceed the life time of
|
||||
* The lifetime of \p platform must exceed the lifetime of
|
||||
* the Engine object.
|
||||
*
|
||||
* @param sharedGLContext A platform-dependant OpenGL context used as a shared context
|
||||
* when creating filament's internal context.
|
||||
* Setting this parameter will force filament to use the OpenGL
|
||||
* implementation (instead of Vulkaan for instance).
|
||||
* implementation (instead of Vulkan for instance).
|
||||
*
|
||||
*
|
||||
* @return A pointer to the newly created Engine, or nullptr if the Engine couldn't be created.
|
||||
@@ -180,7 +180,7 @@ public:
|
||||
* This method is thread-safe.
|
||||
*/
|
||||
static Engine* create(Backend backend = Backend::DEFAULT,
|
||||
ExternalContext* externalContext = nullptr, void* sharedGLContext = nullptr);
|
||||
Platform* platform = nullptr, void* sharedGLContext = nullptr);
|
||||
|
||||
/**
|
||||
* Destroy the Engine instance and all associated resources.
|
||||
|
||||
@@ -64,9 +64,9 @@ public:
|
||||
* @param engine Reference to the filament::Engine to associate this IndexBuffer with.
|
||||
*
|
||||
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
||||
* an error occured.
|
||||
* an error occurred.
|
||||
*
|
||||
* @exception utils::PostConditionPanic if a runtime error occured, such as running out of
|
||||
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
||||
* memory or other resources.
|
||||
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
|
||||
*/
|
||||
|
||||
@@ -190,7 +190,7 @@ public:
|
||||
* @param engine Reference to the filament::Engine to associate this IndirectLight with.
|
||||
*
|
||||
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
||||
* an error occured.
|
||||
* an error occurred.
|
||||
*
|
||||
* @exception utils::PostConditionPanic if a runtime error occured, such as running out of
|
||||
* memory or other resources.
|
||||
|
||||
@@ -421,7 +421,7 @@ public:
|
||||
* @error if exceptions are disabled and an error occurs, this function is a no-op.
|
||||
* Success can be checked by looking at the return value.
|
||||
*
|
||||
* @exception utils::PostConditionPanic if a runtime error occured, such as running out of
|
||||
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
||||
* memory or other resources.
|
||||
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
* @param engine Reference to the filament::Engine to associate this Material with.
|
||||
*
|
||||
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
||||
* an error occured.
|
||||
* an error occurred.
|
||||
*
|
||||
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
||||
* memory or other resources.
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
*
|
||||
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
|
||||
* @param type Whether the color value is encoded as Linear or sRGB/A.
|
||||
* @param color Array of read, green, blue and alpha chanels values.
|
||||
* @param color Array of read, green, blue and alpha channels values.
|
||||
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
|
||||
*/
|
||||
void setParameter(const char* name, RgbaType type, math::float4 color) noexcept;
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec3.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace filament {
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
Builder& castShadows(bool enable) noexcept; // false by default
|
||||
Builder& receiveShadows(bool enable) noexcept; // true by default
|
||||
Builder& skinning(size_t boneCount) noexcept; // 0 by default, 255 max
|
||||
Builder& skinning(size_t boneCount, Bone const* transforms) noexcept;
|
||||
Builder& skinning(size_t boneCount, Bone const* bones) noexcept;
|
||||
Builder& skinning(size_t boneCount, math::mat4f const* transforms) noexcept;
|
||||
|
||||
// Sets an ordering index for blended primitives that all live at the same Z value.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define TNT_FILAMENT_RENDERER_H
|
||||
|
||||
#include <filament/FilamentAPI.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
@@ -136,6 +137,56 @@ public:
|
||||
*/
|
||||
void render(View const* view);
|
||||
|
||||
/**
|
||||
* Flags used to configure the behavior of mirrorFrame().
|
||||
*
|
||||
* @see
|
||||
* mirrorFrame()
|
||||
*/
|
||||
using MirrorFrameFlag = uint32_t;
|
||||
|
||||
/**
|
||||
* Indicates that the dstSwapChain passed into mirrorFrame() should be
|
||||
* committed after the frame has been mirrored.
|
||||
*
|
||||
* @see
|
||||
* mirrorFrame()
|
||||
*/
|
||||
static constexpr MirrorFrameFlag COMMIT = 0x1;
|
||||
/**
|
||||
* Indicates that the presentation time should be set on the dstSwapChain
|
||||
* passed into mirrorFrame to the monotonic clock time when the frame is
|
||||
* mirrored.
|
||||
*
|
||||
* @see
|
||||
* mirrorFrame()
|
||||
*/
|
||||
static constexpr MirrorFrameFlag SET_PRESENTATION_TIME = 0x2;
|
||||
/**
|
||||
* Indicates that the dstSwapChain passed into mirrorFrame() should be
|
||||
* cleared to black before the frame is mirrored into the specified viewport.
|
||||
*
|
||||
* @see
|
||||
* mirrorFrame()
|
||||
*/
|
||||
static constexpr MirrorFrameFlag CLEAR = 0x4;
|
||||
|
||||
/**
|
||||
* Mirror the currently rendered view to the indicated swap chain, using the
|
||||
* indicated source and destination rectangle.
|
||||
*
|
||||
* @param dstSwapChain The swap chain into which the frame should be mirrored.
|
||||
* @param dstViewport The destination rectangle in which to draw the view.
|
||||
* @param srcViewport The source rectangle to be mirrored.
|
||||
* @param flags One or more MirrorFrameFlag behavior configuration flags.
|
||||
*
|
||||
* @remark
|
||||
* mirrorFrame() should be called after a frame is rendered using render()
|
||||
* but before endFrame() is called.
|
||||
*/
|
||||
void mirrorFrame(SwapChain* dstSwapChain, Viewport const& dstViewport, Viewport const& srcViewport,
|
||||
uint32_t flags=0);
|
||||
|
||||
/**
|
||||
* Read-back the content of the SwapChain associated with this Renderer.
|
||||
*
|
||||
|
||||
@@ -150,7 +150,7 @@ public:
|
||||
* +--------------------+
|
||||
* | | .stride .alignment
|
||||
* | | ----------------------->-->
|
||||
* | | O----------------------+--+ low adresses
|
||||
* | | O----------------------+--+ low addresses
|
||||
* | | | | | |
|
||||
* | w | | | .top | |
|
||||
* | <---------> | | V | |
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
* +------>| v | | +---->| | | |
|
||||
* | +.........+ | | +.........+ | |
|
||||
* | ^ | | | |
|
||||
* | y | | +----------------------+--+ high adresses
|
||||
* | y | | +----------------------+--+ high addresses
|
||||
* O------------+-------+
|
||||
*
|
||||
* Typically readPixels() will be called after Renderer.beginFrame().
|
||||
@@ -176,6 +176,15 @@ public:
|
||||
*/
|
||||
void readPixels(uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
|
||||
driver::PixelBufferDescriptor&& buffer) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the presentation time of the currently displayed frame in nanosecond.
|
||||
*
|
||||
* This value can change at any time.
|
||||
*
|
||||
* @return timestamp in nanosecond.
|
||||
*/
|
||||
int64_t getTimestamp() const noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace filament {
|
||||
* SwapChain* swapChain = engine->createSwapChain(nativeWindow);
|
||||
* \endcode
|
||||
*
|
||||
* When Engine::create() is used without specifying an ExternalContext, the `nativeWindow`
|
||||
* When Engine::create() is used without specifying a Platform, the `nativeWindow`
|
||||
* parameter above must be of type:
|
||||
*
|
||||
* Platform | nativeWindow type
|
||||
@@ -46,7 +46,7 @@ namespace filament {
|
||||
* X11 | Window
|
||||
* Windows | HWND
|
||||
*
|
||||
* Otherwise, the `nativeWindow` is defined by the concrete implementation of ExternalContext.
|
||||
* Otherwise, the `nativeWindow` is defined by the concrete implementation of Platform.
|
||||
*
|
||||
*
|
||||
* Examples:
|
||||
@@ -143,6 +143,15 @@ namespace filament {
|
||||
class UTILS_PUBLIC SwapChain : public FilamentAPI {
|
||||
public:
|
||||
static const uint64_t CONFIG_TRANSPARENT = driver::SWAP_CHAIN_CONFIG_TRANSPARENT;
|
||||
/**
|
||||
* This flag indicates that the swap chain may be used as a source surface
|
||||
* for reading back render results. This config must be set when creating
|
||||
* any swap chain that will be used as the source for a blit operation.
|
||||
*
|
||||
* @see
|
||||
* Renderer.mirrorFrame()
|
||||
*/
|
||||
static const uint64_t CONFIG_READABLE = driver::SWAP_CHAIN_CONFIG_READABLE;
|
||||
|
||||
void* getNativeWindow() const noexcept;
|
||||
};
|
||||
|
||||
@@ -159,15 +159,25 @@ public:
|
||||
*/
|
||||
Builder& usage(Usage usage) noexcept;
|
||||
|
||||
/**
|
||||
* Specifies that the alpha channel contains a color multiplier (e.g. for HDR)
|
||||
* The default value is false.
|
||||
*
|
||||
* @param enabled True if the shader should interpret alpha as a color multiplier
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
Builder& rgbm(bool enabled) noexcept;
|
||||
|
||||
/**
|
||||
* Creates the Texture object and returns a pointer to it.
|
||||
*
|
||||
* @param engine Reference to the filament::Engine to associate this Texture with.
|
||||
*
|
||||
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
||||
* an error occured.
|
||||
* an error occurred.
|
||||
*
|
||||
* @exception utils::PostConditionPanic if a runtime error occured, such as running out of
|
||||
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
||||
* memory or other resources.
|
||||
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
|
||||
*/
|
||||
@@ -224,6 +234,12 @@ public:
|
||||
*/
|
||||
InternalFormat getFormat() const noexcept;
|
||||
|
||||
/**
|
||||
* Return if this texture has RGBM data as set by Builder::rgbm().
|
||||
* @return if this texture has RGBM data as set by Builder::rgbm().
|
||||
*/
|
||||
bool isRgbm() const noexcept;
|
||||
|
||||
/**
|
||||
* Specify the image of a 2D texture for a level.
|
||||
*
|
||||
|
||||