diff --git a/README.md b/README.md index cd0b1039d3..76e5d332e4 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,8 @@ Many other features have been either prototyped or planned: - `filament`: Filament engine and its supporting libraries and tools - `android`: Android libraries and projects + - `filament-android`: Filament library (AAR) for Android + - `samples`: Android-specific Filament samples - `art`: Source for various artworks (logos, PDF manuals, etc.) - `assets`: 3D assets to use with sample applications - `build`: CMake build scripts @@ -808,6 +810,8 @@ these methods on `FilamentCanvas` or `FilamentPanel`. ### Android +See `android/samples` for examples of how to use Filament on Android. + You must always first initialize Filament by calling `Filament.init()`. Rendering with Filament on Android is similar to rendering from native code (the APIs are largely diff --git a/android/filament-android/.gitignore b/android/filament-android/.gitignore index b7dc355ca7..58c0c92c56 100644 --- a/android/filament-android/.gitignore +++ b/android/filament-android/.gitignore @@ -3,6 +3,7 @@ /local.properties /.idea/workspace.xml /.idea/libraries +/.idea/caches /.idea/gradle.xml .DS_Store /build diff --git a/android/filament-android/.idea/misc.xml b/android/filament-android/.idea/misc.xml index 75dac50295..c0f68eddd7 100644 --- a/android/filament-android/.idea/misc.xml +++ b/android/filament-android/.idea/misc.xml @@ -5,11 +5,12 @@ diff --git a/android/filament-android/build.gradle b/android/filament-android/build.gradle index 96099bad36..2c8ce0834c 100644 --- a/android/filament-android/build.gradle +++ b/android/filament-android/build.gradle @@ -12,7 +12,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' + classpath 'com.android.tools.build:gradle:3.1.4' } } @@ -23,6 +23,9 @@ allprojects { } } +group = "com.google.android.filament" +version = "0.1" + apply plugin: 'com.android.library' def filament_path = file("../../out/android-release/filament").absolutePath @@ -83,6 +86,3 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:support-annotations:27.1.1' } - -group = "com.google.android.filament" -version = "0.1" diff --git a/android/filament-android/gradle/wrapper/gradle-wrapper.properties b/android/filament-android/gradle/wrapper/gradle-wrapper.properties index 74ec97b269..d4da7d2692 100644 --- a/android/filament-android/gradle/wrapper/gradle-wrapper.properties +++ b/android/filament-android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Aug 05 15:12:47 PDT 2018 +#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.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/android/filament-android/settings.gradle b/android/filament-android/settings.gradle index e69de29bb2..48d67cc234 100644 --- a/android/filament-android/settings.gradle +++ b/android/filament-android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'filament-android' diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 06eb9efab2..a9485a9376 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -21,8 +21,8 @@ using namespace filament; extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass, jlong nativeView, - jstring name_) { +Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass, + jlong nativeView, jstring name_) { View* view = (View*) nativeView; const char* name = env->GetStringUTFChars(name_, 0); view->setName(name); @@ -30,38 +30,39 @@ Java_com_google_android_filament_View_nSetName(JNIEnv* env, jclass, jlong native } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetScene(JNIEnv*, jclass, jlong nativeView, - jlong nativeScene) { +Java_com_google_android_filament_View_nSetScene(JNIEnv*, jclass, + jlong nativeView, jlong nativeScene) { View* view = (View*) nativeView; Scene* scene = (Scene*) nativeScene; view->setScene(scene); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetCamera(JNIEnv*, jclass, jlong nativeView, - jlong nativeCamera) { +Java_com_google_android_filament_View_nSetCamera(JNIEnv*, jclass, + jlong nativeView, jlong nativeCamera) { View* view = (View*) nativeView; Camera* camera = (Camera*) nativeCamera; view->setCamera(camera); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetViewport(JNIEnv*, jclass, jlong nativeView, - jint left, jint bottom, jint width, jint height) { +Java_com_google_android_filament_View_nSetViewport(JNIEnv*, jclass, + jlong nativeView, jint left, jint bottom, jint width, jint height) { View* view = (View*) nativeView; view->setViewport({left, bottom, (uint32_t) width, (uint32_t) height}); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetClearColor(JNIEnv*, jclass, jlong nativeView, +Java_com_google_android_filament_View_nSetClearColor(JNIEnv*, jclass, + jlong nativeView, jfloat linearR, jfloat linearG, jfloat linearB, jfloat linearA) { View* view = (View*) nativeView; view->setClearColor({linearR, linearG, linearB, linearA}); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nGetClearColor(JNIEnv* env, jclass, jlong nativeView, - jfloatArray out_) { +Java_com_google_android_filament_View_nGetClearColor(JNIEnv* env, jclass, + jlong nativeView, jfloatArray out_) { View* view = (View*) nativeView; jfloat* out = env->GetFloatArrayElements(out_, NULL); auto linearColor = view->getClearColor(); @@ -73,35 +74,36 @@ Java_com_google_android_filament_View_nGetClearColor(JNIEnv* env, jclass, jlong } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetClearTargets(JNIEnv*, jclass, jlong nativeView, - jboolean color, jboolean depth, jboolean stencil) { +Java_com_google_android_filament_View_nSetClearTargets(JNIEnv*, jclass, + jlong nativeView, jboolean color, jboolean depth, jboolean stencil) { View* view = (View*) nativeView; view->setClearTargets(color, depth, stencil); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong nativeView, - jint select, jint value) { +Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, + jlong nativeView, jint select, jint value) { View* view = (View*) nativeView; view->setVisibleLayers((uint8_t) select, (uint8_t) value); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, jlong nativeView, - jboolean enabled) { +Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, + jlong nativeView, jboolean enabled) { View* view = (View*) nativeView; view->setShadowsEnabled(enabled); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, jlong nativeView, - jint count) { +Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, + jlong nativeView, jint count) { View* view = (View*) nativeView; view->setSampleCount((uint8_t) count); } extern "C" JNIEXPORT jint JNICALL -Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, jlong nativeView) { +Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, + jlong nativeView) { View* view = (View*) nativeView; return view->getSampleCount(); } @@ -114,14 +116,15 @@ Java_com_google_android_filament_View_nSetAntiAliasing(JNIEnv*, jclass, } extern "C" JNIEXPORT jint JNICALL -Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass, jlong nativeView) { +Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass, + jlong nativeView) { View* view = (View*) nativeView; return (jint)view->getAntiAliasing(); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv *env, jclass, - jlong nativeView, jboolean enabled, jboolean homogeneousScaling, +Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, + jclass, jlong nativeView, jboolean enabled, jboolean homogeneousScaling, jfloat targetFrameTimeMilli, jfloat headRoomRatio, jfloat scaleRate, jfloat minScale, jfloat maxScale, jint history) { View* view = (View*) nativeView; @@ -150,3 +153,17 @@ Java_com_google_android_filament_View_nSetDepthPrepass(JNIEnv *env, View* view = (View*) nativeView; view->setDepthPrepass(View::DepthPrepass(value)); } + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_View_nSetPostProcessingEnabled(JNIEnv*, + jclass, jlong nativeView, jboolean enabled) { + View* view = (View*) nativeView; + view->setPostProcessingEnabled(enabled); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*, + jclass, jlong nativeView) { + View* view = (View*) nativeView; + return view->isPostProcessingEnabled(); +} diff --git a/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java b/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java index 67db8c12af..a8b1542bab 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java +++ b/android/filament-android/src/main/java/com/google/android/filament/VertexBuffer.java @@ -93,7 +93,7 @@ public class VertexBuffer { @NonNull public Builder attribute(@NonNull VertexAttribute attribute, - @IntRange(from = 1) int bufferIndex, @NonNull AttributeType attributeType, + @IntRange(from = 0) int bufferIndex, @NonNull AttributeType attributeType, @IntRange(from = 0) int byteOffset, @IntRange(from = 0) int byteStride) { nBuilderAttribute(mNativeBuilder, attribute.ordinal(), bufferIndex, attributeType.ordinal(), byteOffset, byteStride); @@ -102,7 +102,7 @@ public class VertexBuffer { @NonNull public Builder attribute(@NonNull VertexAttribute attribute, - @IntRange(from = 1) int bufferIndex, @NonNull AttributeType attributeType) { + @IntRange(from = 0) int bufferIndex, @NonNull AttributeType attributeType) { return attribute(attribute, bufferIndex, attributeType, 0, 0 ); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/View.java b/android/filament-android/src/main/java/com/google/android/filament/View.java index d450c7d778..0c8ce489ce 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/View.java +++ b/android/filament-android/src/main/java/com/google/android/filament/View.java @@ -28,7 +28,7 @@ public class View { private String mName; private Scene mScene; private Camera mCamera; - private Viewport mViewport; + private Viewport mViewport = new Viewport(0, 0, 0, 0); private DynamicResolutionOptions mDynamicResolution; private DepthPrepass mDepthPrepass = DepthPrepass.DEFAULT; @@ -100,7 +100,7 @@ public class View { mViewport.left, mViewport.bottom, mViewport.width, mViewport.height); } - @Nullable + @NonNull public Viewport getViewport() { return mViewport; } @@ -179,6 +179,14 @@ public class View { nSetDepthPrepass(getNativeObject(), depthPrepass.value); } + public boolean isPostProcessingEnabled() { + return nIsPostProcessingEnabled(getNativeObject()); + } + + public void setPostProcessingEnabled(boolean enabled) { + nSetPostProcessingEnabled(getNativeObject(), enabled); + } + public void setDynamicLightingOptions(float zLightNear, float zLightFar) { nSetDynamicLightingOptions(getNativeObject(), zLightNear, zLightFar); } @@ -222,4 +230,6 @@ public class View { float minScale, float maxScale, int history); private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar); private static native void nSetDepthPrepass(long nativeView, int value); + private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled); + private static native boolean nIsPostProcessingEnabled(long nativeView); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/android/UiHelper.java b/android/filament-android/src/main/java/com/google/android/filament/android/UiHelper.java index ff156efbe7..4124da9a22 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/android/UiHelper.java +++ b/android/filament-android/src/main/java/com/google/android/filament/android/UiHelper.java @@ -135,6 +135,10 @@ public class UiHelper { mRenderCallback = renderCallback; } + public RendererCallback getRenderCallback() { + return mRenderCallback; + } + /** * Free resources associated to the native window specified in attachTo(). */ diff --git a/android/samples/hello-triangle/.gitignore b/android/samples/hello-triangle/.gitignore new file mode 100644 index 0000000000..58c0c92c56 --- /dev/null +++ b/android/samples/hello-triangle/.gitignore @@ -0,0 +1,11 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +/.idea/caches +/.idea/gradle.xml +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/android/samples/hello-triangle/README.md b/android/samples/hello-triangle/README.md new file mode 100644 index 0000000000..ca5ee5a4f2 --- /dev/null +++ b/android/samples/hello-triangle/README.md @@ -0,0 +1,21 @@ +# Hello Triangle + +This sample shows how to build a minimal Filament application for Android. + +## Android Studio + +Due to issues with composite builds in Android Studio 3.1, it is highly recommended to use +Android Studio 3.2 to open this project. + +## Prerequisites + +Before you start, make sure to read [Filament's README](../../../README.md). You need to be able to +compile Filament's native library and Filament's AAR for this project. The easiest way to proceed +is to install all the required dependencies and to run the following command at the root of the +source tree: + +``` +$ ./build.sh -p android release +``` + +This will build all the native components and the AAR required by this sample application. diff --git a/android/samples/hello-triangle/app/.gitignore b/android/samples/hello-triangle/app/.gitignore new file mode 100644 index 0000000000..796b96d1c4 --- /dev/null +++ b/android/samples/hello-triangle/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/android/samples/hello-triangle/app/build.gradle b/android/samples/hello-triangle/app/build.gradle new file mode 100644 index 0000000000..c52f702683 --- /dev/null +++ b/android/samples/hello-triangle/app/build.gradle @@ -0,0 +1,70 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.google.android.filament.hellotriangle" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + // Filament comes with native code, the following declarations + // can be used to generate architecture specific APKs + flavorDimensions 'cpuArch' + productFlavors { + arm8 { + dimension 'cpuArch' + ndk { + abiFilters 'arm64-v8a' + } + } + arm7 { + dimension 'cpuArch' + ndk { + abiFilters 'armeabi-v7a' + } + } + x86_64 { + dimension 'cpuArch' + ndk { + abiFilters 'x86_64' + } + } + x86 { + dimension 'cpuArch' + ndk { + abiFilters 'x86' + } + } + universal { + dimension 'cpuArch' + } + } + + // We use the .filamat extension for materials compiled with matc + // Telling aapt to not compress them allows to load them efficiently + aaptOptions { + noCompress 'filamat' + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + + // Depend on Filament + implementation 'com.google.android.filament:filament-android' +} diff --git a/android/samples/hello-triangle/app/proguard-rules.pro b/android/samples/hello-triangle/app/proguard-rules.pro new file mode 100644 index 0000000000..f1b424510d --- /dev/null +++ b/android/samples/hello-triangle/app/proguard-rules.pro @@ -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 diff --git a/android/samples/hello-triangle/app/src/main/AndroidManifest.xml b/android/samples/hello-triangle/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..21e3a6bea6 --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/android/samples/hello-triangle/app/src/main/assets/baked_color.filamat b/android/samples/hello-triangle/app/src/main/assets/baked_color.filamat new file mode 100644 index 0000000000..dbb39a5681 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/assets/baked_color.filamat differ diff --git a/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt b/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt new file mode 100644 index 0000000000..693a4e9e3a --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt @@ -0,0 +1,342 @@ +/* + * 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.hellotriangle + +import android.animation.ValueAnimator +import android.app.Activity +import android.opengl.Matrix +import android.os.Bundle +import android.view.Choreographer +import android.view.Surface +import android.view.SurfaceView +import android.view.animation.LinearInterpolator + +import com.google.android.filament.* +import com.google.android.filament.RenderableManager.* +import com.google.android.filament.VertexBuffer.* +import com.google.android.filament.android.UiHelper + +import java.io.IOException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.channels.Channels + +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +class MainActivity : Activity() { + // Make sure to initialize Filament first + // This loads the JNI library needed by most API calls + companion object { + init { + Filament.init() + } + } + + // The View we want to render into + private lateinit var 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 vertexBuffer: VertexBuffer + private lateinit var indexBuffer: IndexBuffer + + // Filament entity representing a renderable object + @Entity private var renderable = 0 + + // A swap chain is Filament's representation of a surface + private var swapChain: SwapChain? = null + + // Performs the rendering and schedules new frames + private val frameScheduler = FrameCallback() + + private val animator = ValueAnimator.ofFloat(0.0f, 360.0f) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + 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 + } + + private fun setupScene() { + loadMaterial() + createMesh() + + // To create a renderable we first create a generic entity + renderable = EntityManager.get().create() + + // We then create a renderable component on that entity + // A renderable is made of several primitives; in this case we declare only 1 + RenderableManager.Builder(1) + // Overall bounding box of the renderable + .boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.01f)) + // Sets the mesh data of the first primitive + .geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 3) + // Sets the material of the first primitive + .material(0, material.defaultInstance) + .build(engine, renderable) + + // Add the entity to the scene to render it + scene.addEntity(renderable) + + // Animate the triangle + animator.interpolator = LinearInterpolator() + animator.duration = 4000 + animator.repeatMode = ValueAnimator.RESTART + animator.repeatCount = ValueAnimator.INFINITE + animator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener { + val transformMatrix = FloatArray(16) + override fun onAnimationUpdate(a: ValueAnimator) { + Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f) + val tcm = engine.transformManager + tcm.setTransform(tcm.getInstance(renderable), transformMatrix) + } + }) + animator.start() + } + + private fun loadMaterial() { + readAsset("baked_color.filamat")?.let { + material = Material.Builder().payload(it, it.remaining()).build(engine) + } + } + + private fun createMesh() { + val intSize = 4 + val floatSize = 4 + val shortSize = 2 + // A vertex is a position + a color: + // 3 floats for XYZ position, 1 integer for color + val vertexSize = 3 * floatSize + intSize + + // Define a vertex and a function to put a vertex in a ByteBuffer + data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int) + fun ByteBuffer.put(v: Vertex): ByteBuffer { + putFloat(v.x) + putFloat(v.y) + putFloat(v.z) + putInt(v.color) + return this + } + + // We are going to generate a single triangle + val vertexCount = 3 + val a1 = PI * 2.0 / 3.0 + val a2 = PI * 4.0 / 3.0 + + val vertexData = ByteBuffer.allocate(vertexCount * vertexSize) + // It is important to respect the native byte order + .order(ByteOrder.nativeOrder()) + .put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt())) + .put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt())) + .put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt())) + // Make sure the cursor is pointing in the right place in the byte buffer + .flip() + + // Declare the layout of our mesh + vertexBuffer = VertexBuffer.Builder() + .bufferCount(1) + .vertexCount(vertexCount) + // Because we interleave position and color data we must specify offset and stride + // We could use de-interleaved data by declaring two buffers and giving each + // attribute a different buffer index + .attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize) + .attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize) + // We store colors as unsigned bytes but since we want values between 0 and 1 + // in the material (shaders), we must mark the attribute as normalized + .normalized(VertexAttribute.COLOR) + .build(engine) + + // Feed the vertex data to the mesh + // We only set 1 buffer because the data is interleaved + vertexBuffer.setBufferAt(engine, 0, vertexData) + + // Create the indices + val indexData = ByteBuffer.allocate(vertexCount * shortSize) + .order(ByteOrder.nativeOrder()) + .putShort(0) + .putShort(1) + .putShort(2) + .flip() + + indexBuffer = IndexBuffer.Builder() + .indexCount(3) + .bufferType(IndexBuffer.Builder.IndexType.USHORT) + .build(engine) + indexBuffer.setBuffer(engine, indexData) + } + + override fun onResume() { + super.onResume() + choreographer.postFrameCallback(frameScheduler) + animator.start() + } + + override fun onPause() { + super.onPause() + choreographer.removeFrameCallback(frameScheduler) + animator.cancel() + } + + override fun onDestroy() { + super.onDestroy() + // Always detach the surface before destroying the engine + uiHelper.detach() + + // This ensures that all the commands we've sent to Filament have + // been processed before we attempt to destroy anything + Fence.waitAndDestroy(engine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH) + + // Cleanup all resources + engine.renderableManager.destroy(renderable) + engine.destroyRenderer(renderer) + engine.destroyVertexBuffer(vertexBuffer) + engine.destroyIndexBuffer(indexBuffer) + engine.destroyMaterial(material) + engine.destroyView(view) + engine.destroyScene(scene) + engine.destroyCamera(camera) + + // 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 zoom = 1.5 + val aspect = width.toDouble() / height.toDouble() + camera.setProjection(Camera.Projection.ORTHO, + -aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0) + + view.viewport = Viewport(0, 0, width, height) + } + } + + private fun readAsset(assetName: String): ByteBuffer? { + var dst: ByteBuffer? = null + try { + assets.openFd(assetName).use { fd -> + val input = fd.createInputStream() + + dst = ByteBuffer.allocate(fd.length.toInt()) + + val src = Channels.newChannel(input) + + src.read(dst) + src.close() + dst!!.rewind() + } + } catch (e: IOException) { + e.printStackTrace() + } + + return dst + } +} diff --git a/android/samples/hello-triangle/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/samples/hello-triangle/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..b1517edf49 --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/android/samples/hello-triangle/app/src/main/res/drawable/ic_launcher_background.xml b/android/samples/hello-triangle/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..88e31872fe --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..6d5e5d094c --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..6d5e5d094c --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000..a2f5908281 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000..1b52399808 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000..ff10afd6e1 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000..115a4c768a Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..dcd3cd8083 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..459ca609d3 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000..8ca12fe024 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..8e19b410a1 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000..b824ebdd48 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..4c19a13c23 Binary files /dev/null and b/android/samples/hello-triangle/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/samples/hello-triangle/app/src/main/res/values/colors.xml b/android/samples/hello-triangle/app/src/main/res/values/colors.xml new file mode 100644 index 0000000000..5a077b3a78 --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #3F51B5 + #303F9F + #FF4081 + diff --git a/android/samples/hello-triangle/app/src/main/res/values/strings.xml b/android/samples/hello-triangle/app/src/main/res/values/strings.xml new file mode 100644 index 0000000000..f1785e74e8 --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Hello Triangle + diff --git a/android/samples/hello-triangle/app/src/main/res/values/styles.xml b/android/samples/hello-triangle/app/src/main/res/values/styles.xml new file mode 100644 index 0000000000..a7a06158ff --- /dev/null +++ b/android/samples/hello-triangle/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/android/samples/hello-triangle/app/src/materials/baked_color.mat b/android/samples/hello-triangle/app/src/materials/baked_color.mat new file mode 100644 index 0000000000..b2aa6a704c --- /dev/null +++ b/android/samples/hello-triangle/app/src/materials/baked_color.mat @@ -0,0 +1,36 @@ +// Simple unlit material that uses the colors associated with each vertex. +// +// This source material must be compiled to a binary material using the matc tool. +// The command used to compile this material is: +// matc -p mobile -a opengl -O -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat +// +// When Filament is updated all compiled materials should be regenerated. It is highly recommended +// to integrate matc with your build system. +// Please refer to the documentation for more information about matc and the materials system. + +material { + name : baked_color, + + // Lists the required vertex attributes + // Here we only need a color (RGBA) + requires : [ + color + ], + + // This material disables all lighting + shadingModel : unlit, + + // Both faces of the model's triangles are visible + culling : none, +} + +fragment { + void material(inout MaterialInputs material) { + // You must always call the prepareMaterial() function + prepareMaterial(material); + + // We set the material's color to the color interpolated from + // the model's vertices + material.baseColor = getColor(); + } +} diff --git a/android/samples/hello-triangle/build.gradle b/android/samples/hello-triangle/build.gradle new file mode 100644 index 0000000000..51001877c4 --- /dev/null +++ b/android/samples/hello-triangle/build.gradle @@ -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.2.60' + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.1.4' + 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 +} diff --git a/android/samples/hello-triangle/gradle.properties b/android/samples/hello-triangle/gradle.properties new file mode 100644 index 0000000000..743d692ce1 --- /dev/null +++ b/android/samples/hello-triangle/gradle.properties @@ -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 diff --git a/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.jar b/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000..7a3265ee94 Binary files /dev/null and b/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.properties b/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..d4da7d2692 --- /dev/null +++ b/android/samples/hello-triangle/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/android/samples/hello-triangle/gradlew b/android/samples/hello-triangle/gradlew new file mode 100755 index 0000000000..cccdd3d517 --- /dev/null +++ b/android/samples/hello-triangle/gradlew @@ -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" "$@" diff --git a/android/samples/hello-triangle/gradlew.bat b/android/samples/hello-triangle/gradlew.bat new file mode 100644 index 0000000000..e95643d6a2 --- /dev/null +++ b/android/samples/hello-triangle/gradlew.bat @@ -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 diff --git a/android/samples/hello-triangle/settings.gradle b/android/samples/hello-triangle/settings.gradle new file mode 100644 index 0000000000..466fef9302 --- /dev/null +++ b/android/samples/hello-triangle/settings.gradle @@ -0,0 +1,3 @@ +includeBuild '../../filament-android' + +include ':app' diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 8da8314b33..498c1e9381 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -395,6 +395,7 @@ public: */ void setPostProcessingEnabled(bool enabled) noexcept; + bool isPostProcessingEnabled() const noexcept; // for debugging... diff --git a/filament/src/View.cpp b/filament/src/View.cpp index d9a29a2ad4..84dc6dc123 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -832,6 +832,10 @@ void View::setPostProcessingEnabled(bool enabled) noexcept { upcast(this)->setPostProcessingEnabled(enabled); } +bool View::isPostProcessingEnabled() const noexcept { + return upcast(this)->hasPostProcessPass(); +} + void View::setDepthPrepass(View::DepthPrepass prepass) noexcept { upcast(this)->setDepthPrepass(prepass); }