diff --git a/android/filament-android/src/main/cpp/Renderer.cpp b/android/filament-android/src/main/cpp/Renderer.cpp index 405fddaf1c..b140b50a5d 100644 --- a/android/filament-android/src/main/cpp/Renderer.cpp +++ b/android/filament-android/src/main/cpp/Renderer.cpp @@ -163,3 +163,13 @@ Java_com_google_android_filament_Renderer_nSetFrameRateOptions(JNIEnv*, jclass, .history = (uint8_t)history, .interval = (uint8_t)interval }); } + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_Renderer_nSetClearOptions(JNIEnv *, jclass , + jlong nativeRenderer, jfloat r, jfloat g, jfloat b, jfloat a, + jboolean clear, jboolean discard) { + Renderer *renderer = (Renderer *) nativeRenderer; + renderer->setClearOptions({ .clearColor = {r, g, b, a}, + .clear = (bool) clear, + .discard = (bool) discard}); +} diff --git a/android/filament-android/src/main/cpp/SkyBox.cpp b/android/filament-android/src/main/cpp/SkyBox.cpp index 6b31d27a32..7fbd81ce32 100644 --- a/android/filament-android/src/main/cpp/SkyBox.cpp +++ b/android/filament-android/src/main/cpp/SkyBox.cpp @@ -18,6 +18,8 @@ #include +#include + using namespace filament; extern "C" JNIEXPORT jlong JNICALL @@ -54,6 +56,13 @@ Java_com_google_android_filament_Skybox_nBuilderIntensity(JNIEnv *env, jclass cl builder->intensity(intensity); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass, + jlong nativeSkyBoxBuilder, jfloat r, jfloat g, jfloat b, jfloat a) { + Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder; + builder->color({r, g, b, a}); +} + extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type, jlong nativeSkyBoxBuilder, jlong nativeEngine) { @@ -82,3 +91,10 @@ Java_com_google_android_filament_Skybox_nGetIntensity(JNIEnv *env, jclass clazz, Skybox *skybox = (Skybox *) nativeSkybox; return static_cast(skybox->getIntensity()); } + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_Skybox_nSetColor(JNIEnv *, jclass, + jlong nativeSkybox, jfloat r, jfloat g, jfloat b, jfloat a) { + Skybox *skybox = (Skybox *) nativeSkybox; + skybox->setColor({r, g, b, a}); +} diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 174433e9b3..d67c934622 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -50,32 +50,6 @@ Java_com_google_android_filament_View_nSetViewport(JNIEnv*, jclass, 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, - 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_) { - View* view = (View*) nativeView; - jfloat* out = env->GetFloatArrayElements(out_, NULL); - auto linearColor = view->getClearColor(); - out[0] = linearColor[0]; - out[1] = linearColor[1]; - out[2] = linearColor[2]; - out[3] = linearColor[3]; - env->ReleaseFloatArrayElements(out_, out, 0); -} - -extern "C" JNIEXPORT void JNICALL -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) { View* view = (View*) nativeView; @@ -90,9 +64,9 @@ Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, jlong extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetRenderTarget(JNIEnv*, jclass, - jlong nativeView, jlong nativeTarget, jint flags) { + jlong nativeView, jlong nativeTarget) { View* view = (View*) nativeView; - view->setRenderTarget((RenderTarget*) nativeTarget, (View::TargetBufferFlags) flags); + view->setRenderTarget((RenderTarget*) nativeTarget); } extern "C" JNIEXPORT void JNICALL @@ -272,3 +246,9 @@ Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong na }; view->setFogOptions(options); } + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nativeView, jint blendMode) { + View* view = (View*) nativeView; + view->setBlendMode((View::BlendMode)blendMode); +} diff --git a/android/filament-android/src/main/java/com/google/android/filament/Renderer.java b/android/filament-android/src/main/java/com/google/android/filament/Renderer.java index 59c93c52c9..a009691baf 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Renderer.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Renderer.java @@ -46,6 +46,7 @@ public class Renderer { private long mNativeObject; private DisplayInfo mDisplayInfo; private FrameRateOptions mFrameRateOptions; + private ClearOptions mClearOptions; /** * Information about the display this renderer is associated to @@ -114,6 +115,30 @@ public class Renderer { public int history = 9; } + /** + * ClearOptions are used at the beginning of a frame to clear or retain the SwapChain content. + */ + public static class ClearOptions { + /** + * Color to use to clear the SwapChain + */ + @NonNull + public float[] clearColor = { 0.0f, 0.0f, 0.0f, 0.0f }; + + /** + * Whether the SwapChain should be cleared using the clearColor. Use this if translucent + * View will be drawn, for instance. + */ + public boolean clear = false; + + /** + * Whether the SwapChain content should be discarded. clear implies discard. Set this + * to false (along with clear to false as well) if the SwapChain already has content that + * needs to be preserved + */ + public boolean discard = true; + }; + /** * Indicates that the dstSwapChain passed into {@link #copyFrame} should be * committed after the frame has been copied. @@ -188,6 +213,30 @@ public class Renderer { return mFrameRateOptions; } + /** + * Set ClearOptions which are used at the beginning of a frame to clear or retain the + * SwapChain content. + */ + public void setClearOptions(@NonNull ClearOptions options) { + mClearOptions = options; + nSetClearOptions(getNativeObject(), + options.clearColor[0], options.clearColor[1], options.clearColor[2], options.clearColor[3], + options.clear, options.discard); + } + + /** + * Returns the ClearOptions object set in {@link #setClearOptions} or a new instance + * otherwise. + * @return a ClearOptions instance + */ + @NonNull + public ClearOptions getClearOptions() { + if (mClearOptions == null) { + mClearOptions = new ClearOptions(); + } + return mClearOptions; + } + /** * Gets the {@link Engine} that created this Renderer. * @@ -604,4 +653,6 @@ public class Renderer { float refreshRate, long presentationDeadlineNanos, long vsyncOffsetNanos); private static native void nSetFrameRateOptions(long nativeRenderer, float interval, float headRoomRatio, float scaleRate, int history); + private static native void nSetClearOptions(long nativeRenderer, + float r, float g, float b, float a, boolean clear, boolean discard); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/Skybox.java b/android/filament-android/src/main/java/com/google/android/filament/Skybox.java index d2753869f0..57b07a5dbf 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Skybox.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Skybox.java @@ -18,6 +18,9 @@ package com.google.android.filament; import androidx.annotation.IntRange; import androidx.annotation.NonNull; +import androidx.annotation.Size; + +import static com.google.android.filament.Colors.LinearColor; import com.google.android.filament.proguard.UsedByReflection; @@ -126,6 +129,33 @@ public class Skybox { return this; } + /** + * Sets the Skybox to a constant color. Default is opaque black. + * + * Ignored if an environment is set. + * + * @return This Builder, for chaining calls. + */ + @NonNull + public Builder color(@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) { + nBuilderColor(mNativeBuilder, r, g, b, a); + return this; + } + + /** + * Sets the Skybox to a constant color. Default is opaque black. + * + * Ignored if an environment is set. + * + * @param color an array of 4 floats + * @return This Builder, for chaining calls. + */ + @NonNull + public Builder color(@NonNull @Size(min = 4) float[] color) { + nBuilderColor(mNativeBuilder, color[0], color[1], color[2], color[3]); + return this; + } + /** * Creates a Skybox object * @@ -159,6 +189,25 @@ public class Skybox { } } + /** + * Mutates the Skybox's constant color. + * + * Ignored if an environment is set. + */ + public void setColor(@LinearColor float r, @LinearColor float g, @LinearColor float b, float a) { + nSetColor(getNativeObject(), r, g, b, a); + } + + /** + * Mutates the Skybox's constant color. + * Ignored if an environment is set. + * + * @param color an array of 4 floats + */ + public void setColor(@NonNull @Size(min = 4) float[] color) { + nSetColor(getNativeObject(), color[0], color[1], color[2], color[3]); + } + /** * Sets bits in a visibility mask. By default, this is 0x1. *

This provides a simple mechanism for hiding or showing this Skybox in a @@ -204,8 +253,10 @@ public class Skybox { private static native void nBuilderEnvironment(long nativeSkyboxBuilder, long nativeTexture); private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show); private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity); + private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a); private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine); private static native void nSetLayerMask(long nativeSkybox, int select, int value); private static native int nGetLayerMask(long nativeSkybox); private static native float nGetIntensity(long nativeSkybox); + private static native void nSetColor(long nativeSkybox, float r, float g, float b, float a); } 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 fe7d2f127d..be1f7ca734 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 @@ -68,6 +68,7 @@ public class View { private BloomOptions mBloomOptions; private FogOptions mFogOptions; private RenderTarget mRenderTarget; + private BlendMode mBlendMode; /** * Generic Quality Level @@ -79,6 +80,11 @@ public class View { ULTRA } + public enum BlendMode { + OPAQUE, + TRANSLUCENT + } + /** * Dynamic resolution can be used to either reach a desired target frame rate by lowering the * resolution of a View, or to increase the quality when the rendering is faster @@ -556,39 +562,23 @@ public class View { } /** - * Sets the color used to clear the Viewport when rendering this View. + * Sets the blending mode used to draw the view into the SwapChain. * - *

This is ignored if a {@link Skybox} is present or if clearing has been disabled - * via {@link #setClearTargets}. Defaults to black.

- * - * @see #getClearColor + * @param blendMode either {@link BlendMode#OPAQUE} or {@link BlendMode#TRANSLUCENT} + * @see #getBlendMode */ - public void setClearColor( - @LinearColor float r, @LinearColor float g, @LinearColor float b, float a) { - nSetClearColor(getNativeObject(), r, g, b, a); + public void setBlendMode(BlendMode blendMode) { + mBlendMode = blendMode; + nSetBlendMode(getNativeObject(), blendMode.ordinal()); } /** - * Returns the View clear color in a provided 4-tuple. * - * @return A reference to the passed-in array. - * - * @see #setClearColor + * @return blending mode set by setBlendMode + * @see #setBlendMode */ - @NonNull @Size(min = 4) - public float[] getClearColor(@NonNull @Size(min = 4) float[] out) { - out = Asserts.assertFloat4(out); - nGetClearColor(getNativeObject(), out); - return out; - } - - /** - * Sets which targets to clear (default: true, true, false) - * - * @see #setClearColor - */ - public void setClearTargets(boolean color, boolean depth, boolean stencil) { - nSetClearTargets(getNativeObject(), color, depth, stencil); + public BlendMode getBlendMode() { + return mBlendMode; } /** @@ -630,33 +620,12 @@ public class View { * By default, the view's associated render target is null, which corresponds to the * SwapChain associated with the engine. *

- *

- * This method discards the content of all the buffers in the render target. See - * {@link #setRenderTarget(RenderTarget, EnumSet)} if you need more precise control. - *

* * @param target render target associated with view, or null for the swap chain */ public void setRenderTarget(@Nullable RenderTarget target) { - setRenderTarget(target, TargetBufferFlags.ALL); - } - - /** - * Specifies an offscreen render target to render into. - * - *

- * By default, the view's associated render target is null, which corresponds to the - * SwapChain associated with the engine. - *

- * - * @param target render target associated with view, or null for the swap chain - * @param flags buffers that need to be discarded before rendering. - */ - public void setRenderTarget(@Nullable RenderTarget target, - @NonNull EnumSet flags) { mRenderTarget = target; - nSetRenderTarget(getNativeObject(), target != null ? target.getNativeObject() : 0, - TargetBufferFlags.flags(flags)); + nSetRenderTarget(getNativeObject(), target != null ? target.getNativeObject() : 0); } /** @@ -954,6 +923,7 @@ public class View { * Sets bloom options. * * @param options Options for bloom. + * @see #getBloomOptions */ public void setBloomOptions(@NonNull BloomOptions options) { mBloomOptions = options; @@ -963,10 +933,25 @@ public class View { options.threshold, options.enabled); } + /** + * Gets the bloom options + * @see #setBloomOptions + * + * @return bloom options currently set. + */ + @NonNull + public BloomOptions getBloomOptions() { + if (mBloomOptions == null) { + mBloomOptions = new BloomOptions(); + } + return mBloomOptions; + } + /** * Sets fog options. * * @param options Options for fog. + * @see #getFogOptions */ public void setFogOptions(@NonNull FogOptions options) { mFogOptions = options; @@ -978,18 +963,20 @@ public class View { } /** - * Gets the bloom options + * Gets the fog options * - * @return bloom options currently set. + * @return fog options currently set. + * @see #setFogOptions */ @NonNull - public BloomOptions getBloomOptions() { - if (mBloomOptions == null) { - mBloomOptions = new BloomOptions(); + public FogOptions getFogOptions() { + if (mFogOptions == null) { + mFogOptions = new FogOptions(); } - return mBloomOptions; + return mFogOptions; } + public long getNativeObject() { if (mNativeObject == 0) { throw new IllegalStateException("Calling method on destroyed View"); @@ -1005,12 +992,9 @@ public class View { private static native void nSetScene(long nativeView, long nativeScene); private static native void nSetCamera(long nativeView, long nativeCamera); private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height); - private static native void nSetClearColor(long nativeView, float r, float g, float b, float a); - private static native void nGetClearColor(long nativeView, float[] out); - private static native void nSetClearTargets(long nativeView, boolean color, boolean depth, boolean stencil); private static native void nSetVisibleLayers(long nativeView, int select, int value); private static native void nSetShadowsEnabled(long nativeView, boolean enabled); - private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget, int flags); + private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget); private static native void nSetSampleCount(long nativeView, int count); private static native int nGetSampleCount(long nativeView); private static native void nSetAntiAliasing(long nativeView, int type); @@ -1031,5 +1015,5 @@ public class View { private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality); private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled); private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled); - + private static native void nSetBlendMode(long nativeView, int blendMode); } diff --git a/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt b/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt index e36130d9b4..9cdc483313 100644 --- a/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt +++ b/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt @@ -113,7 +113,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba } private fun setupView() { - view.setClearColor(0.035f, 0.035f, 0.035f, 1.0f) + scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine) view.camera = camera view.scene = scene } diff --git a/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt b/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt index 4365c6c605..637671fc03 100644 --- a/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt +++ b/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt @@ -117,10 +117,7 @@ class MainActivity : Activity() { } 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) + scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine) // NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference // view.isPostProcessingEnabled = false diff --git a/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt b/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt index ba475b4a86..ff47f85df5 100644 --- a/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt +++ b/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt @@ -117,11 +117,6 @@ class MainActivity : Activity() { } 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) - view.ambientOcclusion = View.AmbientOcclusion.SSAO // NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference diff --git a/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt b/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt index bb7952c84a..80d4664f86 100644 --- a/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt +++ b/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt @@ -118,10 +118,7 @@ class MainActivity : Activity() { } 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) + scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine) // NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference // view.isPostProcessingEnabled = false diff --git a/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt b/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt index bb53f2953e..aeaed65353 100644 --- a/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt +++ b/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt @@ -116,11 +116,6 @@ class MainActivity : Activity() { } 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 diff --git a/android/samples/sample-multi-view/src/main/java/com/google/android/filament/multiview/MainActivity.kt b/android/samples/sample-multi-view/src/main/java/com/google/android/filament/multiview/MainActivity.kt index a7fd2d678a..a970b08065 100644 --- a/android/samples/sample-multi-view/src/main/java/com/google/android/filament/multiview/MainActivity.kt +++ b/android/samples/sample-multi-view/src/main/java/com/google/android/filament/multiview/MainActivity.kt @@ -65,6 +65,8 @@ class MainActivity : Activity() { private lateinit var view1: View private lateinit var view2: View private lateinit var view3: View + // We need skybox to set the background color + private lateinit var skybox: Skybox // Should be pretty obvious :) private lateinit var camera: Camera @@ -123,24 +125,13 @@ class MainActivity : Activity() { view2.setName("view2"); view3.setName("view3"); + skybox = Skybox.Builder().build(engine); + scene.skybox = skybox + camera = engine.createCamera() } private fun setupViews() { - // To use multi-view properly with mobile GPUs, we need to make sure to tell - // Filament to not discard buffers after the first view we render - view1.setRenderTarget(null, View.TargetBufferFlags.NONE) - view2.setRenderTarget(null, View.TargetBufferFlags.NONE) - view3.setRenderTarget(null, View.TargetBufferFlags.NONE) - - // Clears are not restricted by the scissor so we want to disable clear targets - // except for the first view we render - view1.setClearTargets(false, false, false) - view2.setClearTargets(false, false, false) - view3.setClearTargets(false, false, false) - - view0.setClearColor(0.035f, 0.035f, 0.035f, 1.0f) - view0.camera = camera view1.camera = camera view2.camera = camera @@ -382,6 +373,7 @@ class MainActivity : Activity() { engine.destroyView(view1) engine.destroyView(view2) engine.destroyView(view3) + engine.destroySkybox(skybox) engine.destroyScene(scene) engine.destroyCamera(camera) @@ -406,10 +398,18 @@ class MainActivity : Activity() { // If beginFrame() returns false you should skip the frame // This means you are sending frames too quickly to the GPU if (renderer.beginFrame(swapChain!!, frameTimeNanos)) { + skybox.setColor(0.035f, 0.035f, 0.035f, 1.0f); renderer.render(view0) + + skybox.setColor(1.0f, 0.0f, 0.0f, 1.0f); renderer.render(view1) + + skybox.setColor(0.0f, 1.0f, 0.0f, 1.0f); renderer.render(view2) + + skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f); renderer.render(view3) + renderer.endFrame() } } diff --git a/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt b/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt index 7fdd05f45e..33545b7fb7 100644 --- a/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt +++ b/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt @@ -125,7 +125,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba } private fun setupView() { - view.setClearColor(0.035f, 0.035f, 0.035f, 1.0f) + scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine) view.camera = camera view.scene = scene } diff --git a/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt b/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt index 435b134530..55db366043 100644 --- a/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt +++ b/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt @@ -117,10 +117,7 @@ class MainActivity : Activity() { } 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) + scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine) // NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference // view.isPostProcessingEnabled = false diff --git a/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt b/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt index 1dcca6a75b..5cd67e350f 100644 --- a/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt +++ b/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt @@ -121,11 +121,6 @@ class MainActivity : Activity() { } 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 diff --git a/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt b/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt index 8ff038ae13..8ab5da530d 100644 --- a/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt +++ b/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt @@ -137,12 +137,14 @@ class MainActivity : Activity() { scene = engine.createScene() view = engine.createView() camera = engine.createCamera() + + // clear the swapchain with transparent pixels + val options = renderer.clearOptions + options.clear = true + renderer.clearOptions = options } private fun setupView() { - // Make sure to clear to a fully transparent color - view.setClearColor(0.0f, 0.0f, 0.0f, 0.0f) - // Tell the view which camera we want to use view.camera = camera diff --git a/filament/include/filament/Renderer.h b/filament/include/filament/Renderer.h index fd405d4ef6..7a6d2bee1e 100644 --- a/filament/include/filament/Renderer.h +++ b/filament/include/filament/Renderer.h @@ -69,6 +69,10 @@ class PixelBufferDescriptor; class UTILS_PUBLIC Renderer : public FilamentAPI { public: + /** + * Use DisplayInfo to set important Display properties. This is used to achieve correct + * frame pacing and dynamic resolution scaling. + */ struct DisplayInfo { // refresh-rate of the display in Hz. set to 0 for offscreen or turn off frame-pacing. float refreshRate = 60.0f; @@ -109,6 +113,25 @@ public: uint8_t interval = 1; //!< desired frame interval in unit of 1.0 / DisplayInfo::refreshRate }; + /** + * ClearOptions are used at the beginning of a frame to clear or retain the SwapChain content. + */ + struct ClearOptions { + /** Color to use to clear the SwapChain */ + math::float4 clearColor = {}; + /** + * Whether the SwapChain should be cleared using the clearColor. Use this if translucent + * View will be drawn, for instance. + */ + bool clear = false; + /** + * Whether the SwapChain content should be discarded. clear implies discard. Set this + * to false (along with clear to false as well) if the SwapChain already has content that + * needs to be preserved + */ + bool discard = true; + }; + /** * Information about the display this Renderer is associated to. This information is needed * to accurately compute dynamic-resolution scaling and for frame-pacing. @@ -124,6 +147,14 @@ public: */ void setFrameRateOptions(FrameRateOptions const& options) noexcept; + /** + * Set ClearOptions which are used at the beginning of a frame to clear or retain the + * SwapChain content. + * + * @param options + */ + void setClearOptions(const ClearOptions& options); + /** * Get the Engine that created this Renderer. * diff --git a/filament/include/filament/Scene.h b/filament/include/filament/Scene.h index 6dca2229fc..2ce7d0bce8 100644 --- a/filament/include/filament/Scene.h +++ b/filament/include/filament/Scene.h @@ -72,7 +72,7 @@ public: * * @param skybox The Skybox to use to fill untouched pixels, or nullptr to unset the Skybox. */ - void setSkybox(Skybox const* skybox) noexcept; + void setSkybox(Skybox* skybox) noexcept; /** * Set the IndirectLight to use when rendering the Scene. diff --git a/filament/include/filament/Skybox.h b/filament/include/filament/Skybox.h index d453e6779a..6081f8f2d3 100644 --- a/filament/include/filament/Skybox.h +++ b/filament/include/filament/Skybox.h @@ -24,6 +24,7 @@ #include #include +#include namespace filament { @@ -121,6 +122,17 @@ public: */ Builder& intensity(float envIntensity) noexcept; + /** + * Sets the skybox to a constant color. Default is opaque black. + * + * Ignored if an environment is set. + * + * @param color + * + * @return This Builder, for chaining calls. + */ + Builder& color(math::float4 color) noexcept; + /** * Creates the Skybox object and returns a pointer to it. * @@ -134,6 +146,8 @@ public: friend class details::FSkybox; }; + void setColor(math::float4 color) noexcept; + /** * Sets bits in a visibility mask. By default, this is 0x1. * diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 3e881714e7..b6c7ffc9d9 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -62,13 +62,18 @@ class UTILS_PUBLIC View : public FilamentAPI { public: using TargetBufferFlags = backend::TargetBufferFlags; - enum class QualityLevel : int8_t { + enum class QualityLevel : uint8_t { LOW, MEDIUM, HIGH, ULTRA }; + enum class BlendMode : uint8_t { + OPAQUE, + TRANSLUCENT + }; + /** * Dynamic resolution can be used to either reach a desired target frame rate * by lowering the resolution of a View, or to increase the quality when the @@ -345,37 +350,19 @@ public: Viewport const& getViewport() const noexcept; /** - * Sets the color used to clear the Viewport when rendering this View. - * Defaults to black. + * Sets the blending mode used to draw the view into the SwapChain. * - * @param clearColor The color to use to clear the Viewport. - * @see setClearTargets + * @param blendMode either BlendMode::OPAQUE or BlendMode::TRANSLUCENT + * @see getBlendMode */ - void setClearColor(LinearColorA const& clearColor) noexcept; + void setBlendMode(BlendMode blendMode) noexcept; - /** - * Returns the View clear color. - * @return A constant reference to the View's clear color. - */ - LinearColorA const& getClearColor() const noexcept; - - /** - * Sets which targets to clear (default: true, true, false) - * @param color Clear the color buffer. The color buffer is cleared with the color set in - * setClearColor(). - * @param depth Clear the depth buffer. The depth buffer is cleared with an implementation - * defined value representing the farthest depth. - * - * @note - * Generally the depth clear value is 1.0, but you shouldn't rely on this - * because filament may use "inverted depth" in some situations. - * - * - * @param stencil Clear the stencil buffer. The stencil buffer is cleared with 0. - * - * @see setClearColor - */ - void setClearTargets(bool color, bool depth, bool stencil) noexcept; + /** + * + * @return blending mode set by setBlendMode + * @see setBlendMode + */ + BlendMode getBlendMode() const noexcept; /** * Sets which layers are visible. @@ -414,13 +401,8 @@ public: * SwapChain associated with the engine. * * @param renderTarget Render target associated with view, or nullptr for the swap chain. - * @param discard Buffers that need to be discarded before rendering. */ - void setRenderTarget(RenderTarget* renderTarget, - TargetBufferFlags discard = TargetBufferFlags::ALL) noexcept; - - //! @deprecated Please use the other overload and pass nullptr for the renderTarget. - void setRenderTarget(TargetBufferFlags discard = TargetBufferFlags::ALL) noexcept; + void setRenderTarget(RenderTarget* renderTarget) noexcept; /** * Gets the offscreen render target associated with this view. diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 2a729b65b6..fc7b028571 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -258,44 +258,48 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { FrameGraph fg(engine.getResourceAllocator()); - const TargetBufferFlags discardedFlags = view.getDiscardedTargetBuffers(); + const TargetBufferFlags discardedFlags = mDiscardedFlags; + const TargetBufferFlags clearFlags = mClearFlags; + const float4 clearColor = mClearOptions.clearColor; - TargetBufferFlags clearFlags = (view.getClearFlags() & TargetBufferFlags::COLOR); - - // if the depth-buffer is discarded, then we clear it -- the corollary is that if the user - // doesn't ask for the depth buffer to be discarded, then we keep it. This is needed if - // the user wants to keep the depth buffer between two calls to render(). This of course - // only works when post-processing is disabled. - if (any(discardedFlags & TargetBufferFlags::DEPTH)) { - clearFlags |= TargetBufferFlags::DEPTH; - } - - const float4 clearColor = view.getClearColor(); - - // Figure out if we need to blend this view into the framebuffer. Maybe this should be - // explicit, but since we don't have an API right now, we use heuristics: - // - we are keeping the color buffer before rendering, and - // - we are not clearing or clearing with alpha - // FIXME: make this an explicit API - const bool blending = !(discardedFlags & TargetBufferFlags::COLOR) - && (!(clearFlags & TargetBufferFlags::COLOR) || clearColor.a < 1.0); - - // If the swapchain is transparent or if we blend into it, we need to allocate our intermediate - // buffers with an alpha channel. - // FIXME: this doesn't work when the target is a user provided rendertarget - const bool translucent = mSwapChain->isTransparent() || blending; - - const TextureFormat hdrFormat = getHdrFormat(view, translucent); + // Renderer's ClearOptions apply once at the beginning of the frame (not for each View), + // however, it's implemented as part of executing a render pass on the current render target, + // and that happens for each View. So we need to disable clearing after the 1st View has + // been processed. + mDiscardedFlags &= ~TargetBufferFlags::COLOR; + mClearFlags &= ~TargetBufferFlags::COLOR; const Handle viewRenderTarget = getRenderTarget(view); FrameGraphRenderTargetHandle fgViewRenderTarget = fg.import( "viewRenderTarget", { - .viewport = DEBUG_DYNAMIC_SCALING ? svp : vp, .clearFlags = clearFlags }, { + .viewport = DEBUG_DYNAMIC_SCALING ? svp : vp, + .clearColor = clearColor, + .clearFlags = clearFlags + }, { .target = viewRenderTarget, .params = { .flags = { .discardStart = discardedFlags }, }}); + + const bool blending = view.getBlendMode() == View::BlendMode::TRANSLUCENT; + // If the swapchain is transparent or if we blend into it, we need to allocate our intermediate + // buffers with an alpha channel. + // FIXME: this doesn't work when the target is a user provided rendertarget + const bool translucent = mSwapChain->isTransparent() || blending; + const TextureFormat hdrFormat = getHdrFormat(view, translucent); + + const ColorPassConfig config { + .vp = vp, + .svp = svp, + .scale = scale, + .hdrFormat = hdrFormat, + .msaa = msaa, + .clearFlags = clearFlags, + .clearColor = clearColor, + .hasContactShadows = scene.hasContactShadows() + }; + /* * Depth + Color passes */ @@ -338,17 +342,6 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { pass.appendCommands(RenderPass::COLOR); pass.sortCommands(); - const ColorPassConfig config { - .vp = vp, - .svp = svp, - .scale = scale, - .hdrFormat = hdrFormat, - .msaa = msaa, - .clearFlags = clearFlags, - .clearColor = clearColor, - .hasContactShadows = scene.hasContactShadows() - }; - // We use a framegraph pass to wait for froxelization to finish (so it can be done // in parallel with .compile() fg.addTrivialSideEffectPass("Prepare Color Passes", [=, &js, &view](DriverApi& driver) { @@ -394,7 +387,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { if (UTILS_LIKELY(!blending && upscalingQuality == View::QualityLevel::LOW)) { input = ppm.opaqueBlit(fg, input, { .format = ldrFormat }); } else { - input = ppm.blendBlit(fg, true, upscalingQuality, input, { .format = ldrFormat }); + input = ppm.blendBlit(fg, true, upscalingQuality, input, + { .format = ldrFormat }); } } } @@ -414,7 +408,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { if (UTILS_LIKELY(!blending && upscalingQuality == View::QualityLevel::LOW)) { input = ppm.opaqueBlit(fg, input, { .format = ldrFormat }); } else { - input = ppm.blendBlit(fg, true, upscalingQuality, input, { .format = ldrFormat }); + input = ppm.blendBlit(fg, true, upscalingQuality, input, + { .format = ldrFormat }); } } @@ -588,10 +583,8 @@ FrameGraphId FRenderer::colorPass(FrameGraph& fg, const char* } if (!data.color.isValid()) { - clearColorFlags = TargetBufferFlags::COLOR; - if (!(config.clearFlags & TargetBufferFlags::COLOR)) { - // the View doesn't ask for a clear, but we're creating a new color - // intermediate buffer, so it must be cleared with transparent pixels. + if (!mClearOptions.clear && !view.isSkyboxVisible()) { + clearColorFlags = TargetBufferFlags::COLOR; data.clearColor = {}; } data.color = builder.createTexture("Color Buffer", colorBufferDesc); @@ -780,6 +773,19 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN float l = float(time.count() - h); mShaderUserTime = { h, l, 0, 0 }; + + // We always discard and clear the depth+stencil buffers -- we don't allow sharing these + // across views (clear implies discard) + + mDiscardedFlags = ((mClearOptions.discard || mClearOptions.clear) ? + TargetBufferFlags::COLOR : TargetBufferFlags::NONE) + | TargetBufferFlags::DEPTH_AND_STENCIL; + + mClearFlags = (mClearOptions.clear ? + TargetBufferFlags::COLOR : TargetBufferFlags::NONE) + | TargetBufferFlags::DEPTH_AND_STENCIL; + + // ask the engine to do what it needs to (e.g. updates light buffer, materials...) engine.prepare(); @@ -934,4 +940,8 @@ void Renderer::setFrameRateOptions(FrameRateOptions const& options) noexcept { upcast(this)->setFrameRateOptions(options); } +void Renderer::setClearOptions(const ClearOptions& options) { + upcast(this)->setClearOptions(options); +} + } // namespace filament diff --git a/filament/src/Scene.cpp b/filament/src/Scene.cpp index e0a8ba4d76..17e96707bd 100644 --- a/filament/src/Scene.cpp +++ b/filament/src/Scene.cpp @@ -230,6 +230,10 @@ void FScene::updateUBOs(utils::Range visibleRenderables, backend::Hand mHasContactShadows = hasContactShadows; mRenderableViewUbh = renderableUbh; driver.loadUniformBuffer(renderableUbh, { buffer, size }); + + if (mSkybox) { + mSkybox->commit(driver); + } } void FScene::terminate(FEngine& engine) { @@ -388,7 +392,7 @@ bool FScene::hasEntity(Entity entity) const noexcept { return mEntities.find(entity) != mEntities.end(); } -void FScene::setSkybox(FSkybox const* skybox) noexcept { +void FScene::setSkybox(FSkybox* skybox) noexcept { std::swap(mSkybox, skybox); if (skybox) { remove(skybox->getEntity()); @@ -417,7 +421,7 @@ bool FScene::hasContactShadows() const noexcept { using namespace details; -void Scene::setSkybox(Skybox const* skybox) noexcept { +void Scene::setSkybox(Skybox* skybox) noexcept { upcast(this)->setSkybox(upcast(skybox)); } diff --git a/filament/src/Skybox.cpp b/filament/src/Skybox.cpp index 6d8112eb32..31fc578d98 100644 --- a/filament/src/Skybox.cpp +++ b/filament/src/Skybox.cpp @@ -31,6 +31,8 @@ #include #include +#include + #include "generated/resources/materials.h" @@ -41,6 +43,7 @@ using namespace details; struct Skybox::BuilderDetails { Texture* mEnvironmentMap = nullptr; + float4 mColor{0, 0, 0, 1}; float mIntensity = FIndirectLight::DEFAULT_INTENSITY; bool mShowSun = false; }; @@ -64,6 +67,11 @@ Skybox::Builder& Skybox::Builder::intensity(float envIntensity) noexcept { return *this; } +Skybox::Builder& Skybox::Builder::color(math::float4 color) noexcept { + mImpl->mColor = color; + return *this; +} + Skybox::Builder& Skybox::Builder::showSun(bool show) noexcept { mImpl->mShowSun = show; return *this; @@ -73,11 +81,8 @@ Skybox* Skybox::Builder::build(Engine& engine) { FEngine::assertValid(engine, __PRETTY_FUNCTION__); FTexture* cubemap = upcast(mImpl->mEnvironmentMap); - if (!ASSERT_PRECONDITION_NON_FATAL(cubemap, "environment texture not set")) { - return nullptr; - } - - if (!ASSERT_PRECONDITION_NON_FATAL(cubemap->isCubemap(), "environment maps must be a cubemap")) { + if (!ASSERT_PRECONDITION_NON_FATAL(!cubemap || cubemap->isCubemap(), + "environment maps must be a cubemap")) { return nullptr; } @@ -97,8 +102,13 @@ FSkybox::FSkybox(FEngine& engine, const Builder& builder) noexcept mSkyboxMaterialInstance = material->createInstance(); TextureSampler sampler(TextureSampler::MagFilter::LINEAR, TextureSampler::WrapMode::REPEAT); - static_cast(mSkyboxMaterialInstance)->setParameter("skybox", mSkyboxTexture, sampler); - static_cast(mSkyboxMaterialInstance)->setParameter("showSun", builder->mShowSun); + auto pInstance = static_cast(mSkyboxMaterialInstance); + if (mSkyboxTexture != nullptr) { + pInstance->setParameter("skybox", mSkyboxTexture, sampler); + } + pInstance->setParameter("showSun", builder->mShowSun); + pInstance->setParameter("constantColor", mSkyboxTexture == nullptr); + pInstance->setParameter("color", builder->mColor); mSkybox = engine.getEntityManager().create(); @@ -139,6 +149,14 @@ void FSkybox::setLayerMask(uint8_t select, uint8_t values) noexcept { mLayerMask = (mLayerMask & ~select) | (values & select); } +void FSkybox::setColor(math::float4 color) noexcept { + mSkyboxMaterialInstance->setParameter("color", color); +} + +void FSkybox::commit(backend::DriverApi& driver) noexcept { + mSkyboxMaterialInstance->commit(driver); +} + } // namespace details // ------------------------------------------------------------------------------------------------ @@ -159,4 +177,9 @@ float Skybox::getIntensity() const noexcept { return upcast(this)->getIntensity(); } +void Skybox::setColor(math::float4 color) noexcept { + upcast(this)->setColor(color); + +} + } // namespace filament diff --git a/filament/src/View.cpp b/filament/src/View.cpp index ebc049fe9e..1a9966827a 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -42,6 +42,7 @@ #include #include +#include using namespace filament::math; @@ -199,16 +200,6 @@ float2 FView::updateScale(FrameInfo const& info) noexcept { return mScale; } -void FView::setClearColor(float4 const& clearColor) noexcept { - mClearColor = clearColor; -} - -void FView::setClearTargets(bool color, bool depth, bool stencil) noexcept { - mClearTargetColor = color; - mClearTargetDepth = depth; - mClearTargetStencil = stencil; -} - void FView::setVisibleLayers(uint8_t select, uint8_t values) noexcept { mVisibleLayers = (mVisibleLayers & ~select) | (values & select); } @@ -854,19 +845,6 @@ filament::Viewport const& View::getViewport() const noexcept { return upcast(this)->getViewport(); } - -void View::setClearColor(float4 const& clearColor) noexcept { - upcast(this)->setClearColor(clearColor); -} - -float4 const& View::getClearColor() const noexcept { - return upcast(this)->getClearColor(); -} - -void View::setClearTargets(bool color, bool depth, bool stencil) noexcept { - return upcast(this)->setClearTargets(color, depth, stencil); -} - void View::setFrustumCullingEnabled(bool culling) noexcept { upcast(this)->setFrustumCullingEnabled(culling); } @@ -899,12 +877,8 @@ void View::setShadowsEnabled(bool enabled) noexcept { upcast(this)->setShadowsEnabled(enabled); } -void View::setRenderTarget(RenderTarget* renderTarget, TargetBufferFlags discard) noexcept { - upcast(this)->setRenderTarget(upcast(renderTarget), discard); -} - -void View::setRenderTarget(TargetBufferFlags discard) noexcept { - upcast(this)->setRenderTarget(discard); +void View::setRenderTarget(RenderTarget* renderTarget) noexcept { + upcast(this)->setRenderTarget(upcast(renderTarget)); } RenderTarget* View::getRenderTarget() const noexcept { @@ -1007,5 +981,13 @@ View::BloomOptions View::getBloomOptions() const noexcept { return upcast(this)->getBloomOptions(); } +void View::setBlendMode(BlendMode blendMode) noexcept { + upcast(this)->setBlendMode(blendMode); +} + +View::BlendMode View::getBlendMode() const noexcept { + return upcast(this)->getBlendMode(); +} + } // namespace filament diff --git a/filament/src/details/Renderer.h b/filament/src/details/Renderer.h index d80f8d82cf..c4a3524dfd 100644 --- a/filament/src/details/Renderer.h +++ b/filament/src/details/Renderer.h @@ -115,6 +115,10 @@ public: frameRateOptions.headRoomRatio = std::max(frameRateOptions.headRoomRatio, 0.0f); } + void setClearOptions(const ClearOptions& options) { + mClearOptions = options; + } + private: friend class Renderer; using Command = RenderPass::Command; @@ -180,6 +184,9 @@ private: math::float4 mShaderUserTime{}; DisplayInfo mDisplayInfo; FrameRateOptions mFrameRateOptions; + ClearOptions mClearOptions; + backend::TargetBufferFlags mDiscardedFlags; + backend::TargetBufferFlags mClearFlags; // per-frame arena for this Renderer LinearAllocatorArena& mPerRenderPassArena; diff --git a/filament/src/details/Scene.h b/filament/src/details/Scene.h index f7d516fa91..d036582158 100644 --- a/filament/src/details/Scene.h +++ b/filament/src/details/Scene.h @@ -55,8 +55,9 @@ public: * User Public API */ - void setSkybox(FSkybox const* skybox) noexcept; + void setSkybox(FSkybox* skybox) noexcept; FSkybox const* getSkybox() const noexcept { return mSkybox; } + FSkybox* getSkybox() noexcept { return mSkybox; } void setIndirectLight(FIndirectLight const* ibl) noexcept { mIndirectLight = ibl; } FIndirectLight const* getIndirectLight() const noexcept { return mIndirectLight; } @@ -204,7 +205,7 @@ private: const CameraInfo& camera, const math::float4* spheres, size_t count) noexcept; FEngine& mEngine; - FSkybox const* mSkybox = nullptr; + FSkybox* mSkybox = nullptr; FIndirectLight const* mIndirectLight = nullptr; /* diff --git a/filament/src/details/Skybox.h b/filament/src/details/Skybox.h index ae02e7695d..06f2a1330a 100644 --- a/filament/src/details/Skybox.h +++ b/filament/src/details/Skybox.h @@ -18,6 +18,8 @@ #include +#include + #include #include @@ -44,11 +46,15 @@ public: utils::Entity getEntity() const noexcept { return mSkybox; } void setLayerMask(uint8_t select, uint8_t values) noexcept; - uint8_t getLayerMask() const noexcept { return mLayerMask; } float getIntensity() const noexcept { return mIntensity; } + void setColor(math::float4 color) noexcept; + + // commits UBOs + void commit(backend::DriverApi& driver) noexcept; + private: // we don't own these FTexture const* mSkyboxTexture = nullptr; diff --git a/filament/src/details/View.h b/filament/src/details/View.h index 5d565ca48b..beb2a06eb5 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -119,21 +119,9 @@ public: return mViewport; } - void setClearColor(LinearColorA const& clearColor) noexcept; - LinearColorA const& getClearColor() const noexcept { - return mClearColor; - } - - void setClearTargets(bool color, bool depth, bool stencil) noexcept; bool getClearTargetColor() const noexcept { // don't clear the color buffer if we have a skybox - return mClearTargetColor && !isSkyboxVisible(); - } - bool getClearTargetDepth() const noexcept { - return mClearTargetDepth; - } - bool getClearTargetStencil() const noexcept { - return mClearTargetStencil; + return !isSkyboxVisible(); } bool isSkyboxVisible() const noexcept; @@ -188,13 +176,8 @@ public: return &mDirectionalShadowMap.getDebugCamera(); } - void setRenderTarget(FRenderTarget* renderTarget, TargetBufferFlags discard) noexcept { + void setRenderTarget(FRenderTarget* renderTarget) noexcept { mRenderTarget = renderTarget; - mDiscardedTargetBuffers = discard; - } - - void setRenderTarget(TargetBufferFlags discard) noexcept { - mDiscardedTargetBuffers = discard; } FRenderTarget* getRenderTarget() const noexcept { @@ -233,8 +216,6 @@ public: return mDithering; } - TargetBufferFlags getDiscardedTargetBuffers() const noexcept { return mDiscardedTargetBuffers; } - bool hasPostProcessPass() const noexcept { return mHasPostProcessPass; } @@ -302,6 +283,14 @@ public: return mBloomOptions; } + void setBlendMode(BlendMode blendMode) noexcept { + mBlendMode = blendMode; + } + + BlendMode getBlendMode() const noexcept { + return mBlendMode; + } + Range const& getVisibleRenderables() const noexcept { return mVisibleRenderables; } @@ -314,14 +303,6 @@ public: return mSpotLightShadowCasters; } - TargetBufferFlags getClearFlags() const noexcept { - TargetBufferFlags clearFlags = {}; - if (getClearTargetColor()) clearFlags |= TargetBufferFlags::COLOR; - if (getClearTargetDepth()) clearFlags |= TargetBufferFlags::DEPTH; - if (getClearTargetStencil()) clearFlags |= TargetBufferFlags::STENCIL; - return clearFlags; - } - FCamera const& getCameraUser() const noexcept { return *mCullingCamera; } FCamera& getCameraUser() noexcept { return *mCullingCamera; } void setCameraUser(FCamera* camera) noexcept { setCullingCamera(camera); } @@ -380,14 +361,9 @@ private: mutable Froxelizer mFroxelizer; Viewport mViewport; - LinearColorA mClearColor{}; bool mCulling = true; bool mFrontFaceWindingInverted = false; - bool mClearTargetColor = true; - bool mClearTargetDepth = true; - bool mClearTargetStencil = false; - TargetBufferFlags mDiscardedTargetBuffers = TargetBufferFlags::ALL; FRenderTarget* mRenderTarget = nullptr; uint8_t mVisibleLayers = 0x1; @@ -401,6 +377,7 @@ private: AmbientOcclusionOptions mAmbientOcclusionOptions{}; BloomOptions mBloomOptions; FogOptions mFogOptions; + BlendMode mBlendMode = BlendMode::OPAQUE; DynamicResolutionOptions mDynamicResolution; math::float2 mScale = 1.0f; diff --git a/filament/src/fg/FrameGraphHandle.h b/filament/src/fg/FrameGraphHandle.h index 88c12b16d2..8c44ef4c6f 100644 --- a/filament/src/fg/FrameGraphHandle.h +++ b/filament/src/fg/FrameGraphHandle.h @@ -166,8 +166,9 @@ struct FrameGraphRenderTarget { struct Descriptor { Attachments attachments; Viewport viewport; + math::float4 clearColor{}; uint8_t samples = 0; // # of samples (0 = unset, default) - backend::TargetBufferFlags clearFlags = {}; + backend::TargetBufferFlags clearFlags{}; }; backend::Handle target; diff --git a/filament/src/fg/fg/RenderTargetResourceEntry.cpp b/filament/src/fg/fg/RenderTargetResourceEntry.cpp index 73e97eb57f..7651db3910 100644 --- a/filament/src/fg/fg/RenderTargetResourceEntry.cpp +++ b/filament/src/fg/fg/RenderTargetResourceEntry.cpp @@ -112,12 +112,12 @@ void RenderTargetResourceEntry::resolve(FrameGraph& fg) noexcept { resource.params.viewport.width = width; resource.params.viewport.height = height; } - resource.params.flags.clear = descriptor.clearFlags; } else { // this can happen with imported targets resource.params.viewport = descriptor.viewport; - resource.params.flags.clear = descriptor.clearFlags; } + resource.params.clearColor = descriptor.clearColor; + resource.params.flags.clear = descriptor.clearFlags; } void RenderTargetResourceEntry::update(FrameGraph& fg, PassNode const& pass) noexcept { diff --git a/filament/src/materials/skybox.mat b/filament/src/materials/skybox.mat index f44f024fa3..28277ed35d 100644 --- a/filament/src/materials/skybox.mat +++ b/filament/src/materials/skybox.mat @@ -5,9 +5,17 @@ material { type : bool, name : showSun }, + { + type : bool, + name : constantColor + }, { type : samplerCubemap, name : skybox + }, + { + type : float4, + name : color } ], variables : [ @@ -23,8 +31,13 @@ material { fragment { void material(inout MaterialInputs material) { prepareMaterial(material); - vec3 sky = texture(materialParams_skybox, variable_eyeDirection.xyz).rgb; - sky *= frameUniforms.iblLuminance; + vec4 sky; + if (materialParams.constantColor) { + sky = materialParams.color; + } else { + sky = vec4(texture(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0); + sky.rgb *= frameUniforms.iblLuminance; + } if (materialParams.showSun && frameUniforms.sun.w >= 0.0f) { vec3 direction = normalize(variable_eyeDirection.xyz); // Assume the sun is a sphere @@ -33,9 +46,9 @@ fragment { float cosAngle = dot(direction, frameUniforms.lightDirection); float x = (cosAngle - frameUniforms.sun.x) * frameUniforms.sun.z; float gradient = pow(1.0 - saturate(x), frameUniforms.sun.w); - sky = sky + gradient * sun; + sky.rgb = sky.rgb + gradient * sun; } - material.baseColor = vec4(sky, 1.0); + material.baseColor = sky; } } diff --git a/filament/test/filament_rendering_test.cpp b/filament/test/filament_rendering_test.cpp index 645e628ef4..a7c8e90a84 100644 --- a/filament/test/filament_rendering_test.cpp +++ b/filament/test/filament_rendering_test.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include @@ -32,6 +34,7 @@ protected: SwapChain* mSurface = nullptr; Renderer* mRenderer = nullptr; View* mView = nullptr; + Skybox* mSkybox = nullptr; Scene* mScene = nullptr; Camera* mCamera = nullptr; @@ -49,12 +52,16 @@ protected: mView->setViewport({0, 0, 16, 16}); mView->setScene(mScene); mView->setCamera(mCamera); + + mSkybox = Skybox::Builder().build(*mEngine); + mScene->setSkybox(mSkybox); } void TearDown() override { mEngine->destroy(mCamera); mEngine->destroy(mScene); mEngine->destroy(mView); + mEngine->destroy(mSkybox); mEngine->destroy(mRenderer); mEngine->destroy(mSurface); Engine::destroy(&mEngine); @@ -91,7 +98,7 @@ private: }; TEST_F(RenderingTest, ClearRed) { - mView->setClearColor(LinearColorA{1, 0, 0, 1}); + mSkybox->setColor(LinearColorA{1, 0, 0, 1}); mView->setToneMapping(View::ToneMapping::LINEAR); mView->setDithering(View::Dithering::NONE); runTest([this](uint8_t const* rgba, uint32_t width, uint32_t height) { @@ -103,7 +110,7 @@ TEST_F(RenderingTest, ClearRed) { } TEST_F(RenderingTest, ClearGreen) { - mView->setClearColor(LinearColorA{0, 1, 0, 1}); + mSkybox->setColor(LinearColorA{0, 1, 0, 1}); mView->setToneMapping(View::ToneMapping::LINEAR); mView->setDithering(View::Dithering::NONE); runTest([this](uint8_t const* rgba, uint32_t width, uint32_t height) { diff --git a/ios/samples/hello-triangle/hello-triangle/FilamentView.mm b/ios/samples/hello-triangle/hello-triangle/FilamentView.mm index 0759f8e209..dd222fa145 100644 --- a/ios/samples/hello-triangle/hello-triangle/FilamentView.mm +++ b/ios/samples/hello-triangle/hello-triangle/FilamentView.mm @@ -151,9 +151,9 @@ static constexpr uint8_t BAKED_COLOR_PACKAGE[] = { renderer = engine->createRenderer(); scene = engine->createScene(); camera = engine->createCamera(); + renderer->setClearOptions({.clearColor={0.1, 0.125, 0.25, 1.0}, .clear = true}); filaView = engine->createView(); - filaView->setClearColor({0.1, 0.125, 0.25, 1.0}); filaView->setPostProcessingEnabled(false); app.vb = VertexBuffer::Builder() diff --git a/ios/samples/transparent-rendering/transparent-rendering/FilamentView.mm b/ios/samples/transparent-rendering/transparent-rendering/FilamentView.mm index 60483e81d4..35d485796c 100644 --- a/ios/samples/transparent-rendering/transparent-rendering/FilamentView.mm +++ b/ios/samples/transparent-rendering/transparent-rendering/FilamentView.mm @@ -164,7 +164,7 @@ static constexpr uint8_t BAKED_COLOR_PACKAGE[] = { filaView = engine->createView(); // Set a transparent clear color. - filaView->setClearColor({0.0f, 0.0f, 0.0f, 0.0f}); + renderer->setClearOptions({.clear = true}); filaView->setPostProcessingEnabled(false); diff --git a/libs/filamentapp/src/FilamentApp.cpp b/libs/filamentapp/src/FilamentApp.cpp index 46688ed72d..a9fb0aa272 100644 --- a/libs/filamentapp/src/FilamentApp.cpp +++ b/libs/filamentapp/src/FilamentApp.cpp @@ -102,8 +102,7 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback, window->mMainView->getView()->setVisibleLayers(0x4, 0x4); - window->mUiView->getView()->setClearTargets(false, false, false); - window->mUiView->getView()->setRenderTarget(View::TargetBufferFlags::DEPTH_AND_STENCIL); + window->mUiView->getView()->setBlendMode(View::BlendMode::TRANSLUCENT); window->mUiView->getView()->setPostProcessingEnabled(false); window->mUiView->getView()->setShadowsEnabled(false); @@ -128,16 +127,9 @@ void FilamentApp::run(const Config& config, SetupCallback setupCallback, window->mOrthoView->getView()->setVisibleLayers(0x6, 0x6); // only preserve the color buffer for additional views; depth and stencil can be discarded. - window->mDepthView->getView()->setRenderTarget(View::TargetBufferFlags::DEPTH_AND_STENCIL); - window->mGodView->getView()->setRenderTarget(View::TargetBufferFlags::DEPTH_AND_STENCIL); - window->mOrthoView->getView()->setRenderTarget(View::TargetBufferFlags::DEPTH_AND_STENCIL); - window->mDepthView->getView()->setShadowsEnabled(false); window->mGodView->getView()->setShadowsEnabled(false); window->mOrthoView->getView()->setShadowsEnabled(false); - - // the depthview doesn't draw the background (ibl), so we must clear it - window->mDepthView->getView()->setClearColor({0, 0, 0, 1}); } loadDirt(config); @@ -726,7 +718,6 @@ void FilamentApp::Window::configureCamerasForWindow() { FilamentApp::CView::CView(Renderer& renderer, std::string name) : engine(*renderer.getEngine()), mName(name) { view = engine.createView(); - view->setClearColor(LinearColorA{ 0 }); view->setName(name.c_str()); } diff --git a/samples/animation.cpp b/samples/animation.cpp index c68a057912..4af6806ee7 100644 --- a/samples/animation.cpp +++ b/samples/animation.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ struct App { IndexBuffer* ib; Material* mat; Camera* cam; + Skybox* skybox; Entity renderable; }; @@ -66,7 +68,8 @@ int main(int argc, char** argv) { App app; auto setup = [&app](Engine* engine, View* view, Scene* scene) { - view->setClearColor({0.1, 0.125, 0.25, 1.0}); + app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); + scene->setSkybox(app.skybox); view->setPostProcessingEnabled(false); app.vb = VertexBuffer::Builder() .vertexCount(3).bufferCount(1) @@ -88,6 +91,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.mat); engine->destroy(app.vb); diff --git a/samples/depthtesting.cpp b/samples/depthtesting.cpp index e07734582f..cf501c2176 100644 --- a/samples/depthtesting.cpp +++ b/samples/depthtesting.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ struct App { IndexBuffer* ib; Material* mat; Camera* cam; + Skybox* skybox; Entity whiteTriangle; Entity colorTriangle; }; @@ -67,9 +69,11 @@ int main(int argc, char** argv) { App app; auto setup = [&app](Engine* engine, View* view, Scene* scene) { + app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); + scene->setSkybox(app.skybox); + app.cam = engine->createCamera(); view->setCamera(app.cam); - view->setClearColor({0.1, 0.125, 0.25, 1.0}); view->setPostProcessingEnabled(false); app.vb = VertexBuffer::Builder() .vertexCount(3) @@ -115,6 +119,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.whiteTriangle); engine->destroy(app.colorTriangle); engine->destroy(app.mat); diff --git a/samples/frame_generator.cpp b/samples/frame_generator.cpp index 3fe94f1092..8a8765e9d3 100644 --- a/samples/frame_generator.cpp +++ b/samples/frame_generator.cpp @@ -76,6 +76,7 @@ static Path g_materialPath; static Path g_paramsPath; static bool g_lightOn = false; static bool g_skyboxOn = true; +static Skybox* g_skybox = nullptr; static int g_materialVariantCount = 1; static int g_currentFrame = 0; static std::atomic_int g_savedFrames(0); @@ -228,6 +229,10 @@ static void cleanup(Engine* engine, View*, Scene*) { engine->destroy(material.second); } + if (g_skybox) { + engine->destroy(g_skybox); + } + engine->destroy(g_materialInstance); engine->destroy(g_material); @@ -329,14 +334,15 @@ static void setup(Engine* engine, View* view, Scene* scene) { if (!g_skyboxOn) { auto ibl = FilamentApp::get().getIBL(); if (ibl) ibl->getSkybox()->setLayerMask(0xff, 0x00); + } else { + g_skybox = Skybox::Builder().color({ + ((g_clearColor >> 16) & 0xFF) / 255.0f, + ((g_clearColor >> 8) & 0xFF) / 255.0f, + ((g_clearColor ) & 0xFF) / 255.0f, + 1.0f + }).build(*engine); + scene->setSkybox(g_skybox); } - - view->setClearColor(Color::toLinear({ - ((g_clearColor >> 16) & 0xFF) / 255.0f, - ((g_clearColor >> 8) & 0xFF) / 255.0f, - ((g_clearColor ) & 0xFF) / 255.0f, - 1.0f - })); } template diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp index 35b1b73fc4..a117a43829 100644 --- a/samples/gltf_viewer.cpp +++ b/samples/gltf_viewer.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -443,8 +444,9 @@ int main(int argc, char** argv) { if (ibl) { ibl->getSkybox()->setLayerMask(0xff, app.viewOptions.skyboxEnabled ? 0xff : 0x00); } - view->setClearColor( - LinearColorA{ inverseTonemapSRGB(app.viewOptions.backgroundColor), 1.0f }); + renderer->setClearOptions({ + .clearColor = { inverseTonemapSRGB(app.viewOptions.backgroundColor), 1.0f }, + .clear = !ibl || !app.viewOptions.skyboxEnabled }); }; FilamentApp& filamentApp = FilamentApp::get(); diff --git a/samples/heightfield.cpp b/samples/heightfield.cpp index e82bd493d1..855dabfc18 100644 --- a/samples/heightfield.cpp +++ b/samples/heightfield.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,7 @@ using MinFilter = TextureSampler::MinFilter; using MagFilter = TextureSampler::MagFilter; struct App { + Skybox* skybox = nullptr; VertexBuffer* vb = nullptr; IndexBuffer* ib = nullptr; Material* mat = nullptr; @@ -296,7 +298,8 @@ int main(int argc, char** argv) { TextureSampler sampler(MinFilter::LINEAR, MagFilter::LINEAR); // Set up view - view->setClearColor({0.03f, 0.04f, 0.36f, 1.0f}); + app.skybox = Skybox::Builder().color({0.03f, 0.04f, 0.36f, 1.0f}).build(*engine); + scene->setSkybox(app.skybox); view->setPostProcessingEnabled(false); // Generate heightfield vertices. @@ -380,6 +383,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.matInstance); engine->destroy(app.mat); diff --git a/samples/hellotriangle.cpp b/samples/hellotriangle.cpp index a8f24fc1e8..1d63e23dca 100644 --- a/samples/hellotriangle.cpp +++ b/samples/hellotriangle.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ struct App { IndexBuffer* ib; Material* mat; Camera* cam; + Skybox* skybox; Entity renderable; }; @@ -66,7 +68,8 @@ int main(int argc, char** argv) { App app; auto setup = [&app](Engine* engine, View* view, Scene* scene) { - view->setClearColor({0.1, 0.125, 0.25, 1.0}); + app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); + scene->setSkybox(app.skybox); view->setPostProcessingEnabled(false); static_assert(sizeof(Vertex) == 12, "Strange vertex size."); app.vb = VertexBuffer::Builder() @@ -102,6 +105,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.mat); engine->destroy(app.vb); diff --git a/samples/point_sprites.cpp b/samples/point_sprites.cpp index 54fd14ea2d..6a89f9ff7b 100644 --- a/samples/point_sprites.cpp +++ b/samples/point_sprites.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ struct App { Material* mat; MaterialInstance* matInstance; Camera* cam; + Skybox* skybox; Texture* tex; Entity renderable; }; @@ -154,10 +156,13 @@ void setup(App& app, Engine* engine, View* view, Scene* scene) { scene->addEntity(app.renderable); app.cam = engine->createCamera(); view->setCamera(app.cam); - view->setClearColor({0.1, 0.125, 0.25, 1.0}); + + app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); + scene->setSkybox(app.skybox); }; void cleanup(App& app, Engine* engine) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.matInstance); engine->destroy(app.mat); diff --git a/samples/shadowtest.cpp b/samples/shadowtest.cpp index 2b156e2e0b..d3a022e96d 100644 --- a/samples/shadowtest.cpp +++ b/samples/shadowtest.cpp @@ -46,6 +46,7 @@ struct GroundPlane { }; struct App { + Skybox* skybox; utils::Entity light; std::map materials; MeshAssimp* meshes; @@ -102,8 +103,8 @@ int main(int argc, char** argv) { scene->addEntity(app.light); // Hide skybox and add ground plane. - scene->setSkybox(nullptr); - view->setClearColor({0.5f,0.75f,1.0f,1.0f}); + app.skybox = Skybox::Builder().color({0.5f,0.75f,1.0f,1.0f}).build(*engine); + scene->setSkybox(app.skybox); app.plane = createGroundPlane(engine); scene->addEntity(app.plane.renderable); }; @@ -114,6 +115,7 @@ int main(int argc, char** argv) { engine->destroy(app.plane.vb); engine->destroy(app.plane.ib); engine->destroy(app.light); + engine->destroy(app.skybox); for (auto& item : app.materials) { engine->destroy(item.second); } diff --git a/samples/strobecolor.cpp b/samples/strobecolor.cpp index bda67b681a..aa394141c3 100644 --- a/samples/strobecolor.cpp +++ b/samples/strobecolor.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -29,21 +30,23 @@ int main(int argc, char** argv) { Config config; config.title = "strobecolor"; config.backend = Engine::Backend::VULKAN; + Skybox* skybox; - auto setup = [](Engine*, View* view, Scene*) { - view->setClearColor({0.0, 0.25, 0.5, 1.0}); + auto setup = [&skybox](Engine* engine, View* view, Scene* scene) { + skybox = Skybox::Builder().color({ 0.0, 0.25, 0.5, 1.0 }).build(*engine); + scene->setSkybox(skybox); view->setPostProcessingEnabled(false); }; auto cleanup = [](Engine*, View*, Scene*) { }; - FilamentApp::get().animate([](Engine*, View* view, double now) { + FilamentApp::get().animate([skybox](Engine*, View* view, double now) { constexpr float SPEED = 4; float r = 0.5f + 0.5f * std::sin(SPEED * now); float g = 0.5f + 0.5f * std::sin(SPEED * now + M_PI * 2 / 3); float b = 0.5f + 0.5f * std::sin(SPEED * now + M_PI * 4 / 3); - view->setClearColor({r, g, b, 1.0}); + skybox->setColor({r, g, b, 1.0}); }); FilamentApp::get().run(config, setup, cleanup); diff --git a/samples/texturedquad.cpp b/samples/texturedquad.cpp index a19d3ef1d4..bfffa3d5e2 100644 --- a/samples/texturedquad.cpp +++ b/samples/texturedquad.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ struct App { Material* mat; MaterialInstance* matInstance; Camera* cam; + Skybox* skybox; Texture* tex; Entity renderable; }; @@ -108,7 +110,9 @@ int main(int argc, char** argv) { TextureSampler sampler(MinFilter::LINEAR, MagFilter::LINEAR); // Set up view - view->setClearColor({0.1, 0.125, 0.25, 1.0}); + app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); + scene->setSkybox(app.skybox); + view->setPostProcessingEnabled(false); app.cam = engine->createCamera(); view->setCamera(app.cam); @@ -147,6 +151,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.matInstance); engine->destroy(app.mat); diff --git a/samples/viewtest.cpp b/samples/viewtest.cpp index 3c02f1a700..c9098f86d8 100644 --- a/samples/viewtest.cpp +++ b/samples/viewtest.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ struct App { VertexBuffer* vb; IndexBuffer* ib; Camera* cam; + Skybox* skybox; utils::Entity renderable; }; @@ -43,7 +45,8 @@ int main(int argc, char** argv) { App app; auto setup = [&app](Engine* engine, View* view, Scene* scene) { - view->setClearColor({0, 0, 1, 1}); + app.skybox = Skybox::Builder().color({ 0, 0, 1, 1 }).build(*engine); + scene->setSkybox(app.skybox); view->setViewport({100, 100, 512, 512}); app.vb = VertexBuffer::Builder() .vertexCount(3).bufferCount(1) @@ -66,6 +69,7 @@ int main(int argc, char** argv) { }; auto cleanup = [&app](Engine* engine, View*, Scene*) { + engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.vb); engine->destroy(app.ib); diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index 39bb064443..8a7135c7aa 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -489,7 +489,6 @@ class_("View") .function("setCamera", &View::setCamera, allow_raw_pointers()) .function("getViewport", &View::getViewport) .function("setViewport", &View::setViewport) - .function("setClearColor", &View::setClearColor) .function("setPostProcessingEnabled", &View::setPostProcessingEnabled) .function("_setAmbientOcclusionOptions", &View::setAmbientOcclusionOptions) .function("_setBloomOptions", &View::setBloomOptions)