This reverts commit 038f07cb34.
This commit is contained in:
@@ -17,7 +17,6 @@ Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
- engine: Add `Material::getFeatureLevel()`
|
||||
- engine: Add missing `Material::getReflectionMode()` method in Java
|
||||
- engine: Support basic usage of post-processing materials on feature level 0
|
||||
- engine: move `setFrontFaceWindingInverted` from `View` to `MaterialInstance` [**API CHANGE**]
|
||||
|
||||
## v1.45.1
|
||||
|
||||
|
||||
@@ -433,13 +433,6 @@ Java_com_google_android_filament_MaterialInstance_nSetStencilWriteMask(JNIEnv*,
|
||||
instance->setStencilWriteMask(writeMask, static_cast<MaterialInstance::StencilFace>(face));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetFrontFaceWindingInverted(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jboolean inverted) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setFrontFaceWindingInverted(inverted);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetName(JNIEnv* env, jclass,
|
||||
@@ -476,7 +469,7 @@ extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetMaskThreshold(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getMaskThreshold();
|
||||
}
|
||||
|
||||
@@ -484,7 +477,7 @@ extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingVariance(JNIEnv* env,
|
||||
jclass clazz, jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getSpecularAntiAliasingVariance();
|
||||
}
|
||||
|
||||
@@ -492,7 +485,7 @@ extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingThreshold(JNIEnv* env,
|
||||
jclass clazz, jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getSpecularAntiAliasingThreshold();
|
||||
}
|
||||
|
||||
@@ -500,7 +493,7 @@ extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDoubleSided(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDoubleSided();
|
||||
}
|
||||
|
||||
@@ -508,7 +501,7 @@ extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetCullingMode(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return (jint)instance->getCullingMode();
|
||||
}
|
||||
|
||||
@@ -516,7 +509,7 @@ extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsColorWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isColorWriteEnabled();
|
||||
}
|
||||
|
||||
@@ -524,7 +517,7 @@ extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDepthWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDepthWriteEnabled();
|
||||
}
|
||||
|
||||
@@ -532,7 +525,7 @@ extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsStencilWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isStencilWriteEnabled();
|
||||
}
|
||||
|
||||
@@ -540,7 +533,7 @@ extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDepthCullingEnabled();
|
||||
}
|
||||
|
||||
@@ -548,13 +541,6 @@ extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return (jint)instance->getDepthFunc();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsFrontFaceWindingInverted(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
return static_cast<jboolean>(instance->isFrontFaceWindingInverted());
|
||||
}
|
||||
|
||||
@@ -202,6 +202,20 @@ Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*,
|
||||
return static_cast<jboolean>(view->isPostProcessingEnabled());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetFrontFaceWindingInverted(JNIEnv*,
|
||||
jclass, jlong nativeView, jboolean inverted) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setFrontFaceWindingInverted(inverted);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_View_nIsFrontFaceWindingInverted(JNIEnv*,
|
||||
jclass, jlong nativeView) {
|
||||
View* view = (View*) nativeView;
|
||||
return static_cast<jboolean>(view->isFrontFaceWindingInverted());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetAmbientOcclusion(JNIEnv*, jclass, jlong nativeView, jint ordinal) {
|
||||
View* view = (View*) nativeView;
|
||||
|
||||
@@ -850,32 +850,6 @@ public class MaterialInstance {
|
||||
setStencilWriteMask(writeMask, StencilFace.FRONT_AND_BACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if front face winding order is inverted.
|
||||
*
|
||||
* @see #setFrontFaceWindingInverted
|
||||
*/
|
||||
public boolean isFrontFaceWindingInverted() {
|
||||
return nIsFrontFaceWindingInverted(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
|
||||
* winding order. When the winding order is inverted, front faces are faces with a clockwise
|
||||
* winding order.
|
||||
*
|
||||
* Changing the winding order will directly affect the culling mode in materials
|
||||
* (see Material#getCullingMode).
|
||||
*
|
||||
* Inverting the winding order of front faces is useful when rendering mirrored reflections
|
||||
* (water, mirror surfaces, front camera in AR, etc.).
|
||||
*
|
||||
* @param inverted True to invert front faces, false otherwise.
|
||||
*/
|
||||
public void setFrontFaceWindingInverted(boolean inverted) {
|
||||
nSetFrontFaceWindingInverted(getNativeObject(), inverted);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
|
||||
@@ -967,9 +941,6 @@ public class MaterialInstance {
|
||||
private static native void nSetStencilWriteMask(long nativeMaterialInstance, int writeMask,
|
||||
long face);
|
||||
|
||||
private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted);
|
||||
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
|
||||
|
||||
private static native String nGetName(long nativeMaterialInstance);
|
||||
private static native long nGetMaterial(long nativeMaterialInstance);
|
||||
|
||||
|
||||
@@ -709,6 +709,32 @@ public class View {
|
||||
nSetPostProcessingEnabled(getNativeObject(), enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if post-processing is enabled.
|
||||
*
|
||||
* @see #setPostProcessingEnabled
|
||||
*/
|
||||
public boolean isFrontFaceWindingInverted() {
|
||||
return nIsFrontFaceWindingInverted(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
|
||||
* winding order. When the winding order is inverted, front faces are faces with a clockwise
|
||||
* winding order.
|
||||
*
|
||||
* Changing the winding order will directly affect the culling mode in materials
|
||||
* (see Material#getCullingMode).
|
||||
*
|
||||
* Inverting the winding order of front faces is useful when rendering mirrored reflections
|
||||
* (water, mirror surfaces, front camera in AR, etc.).
|
||||
*
|
||||
* @param inverted True to invert front faces, false otherwise.
|
||||
*/
|
||||
public void setFrontFaceWindingInverted(boolean inverted) {
|
||||
nSetFrontFaceWindingInverted(getNativeObject(), inverted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets options relative to dynamic lighting for this view.
|
||||
*
|
||||
@@ -1185,6 +1211,8 @@ public class View {
|
||||
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
|
||||
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsPostProcessingEnabled(long nativeView);
|
||||
private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted);
|
||||
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
|
||||
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, float minHorizonAngleRad);
|
||||
|
||||
@@ -480,27 +480,6 @@ public:
|
||||
void setStencilWriteMask(uint8_t writeMask,
|
||||
StencilFace face = StencilFace::FRONT_AND_BACK) noexcept;
|
||||
|
||||
/**
|
||||
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
|
||||
* winding order. When the winding order is inverted, front faces are faces with a clockwise
|
||||
* winding order.
|
||||
*
|
||||
* Changing the winding order will directly affect the culling mode in materials
|
||||
* (see Material::getCullingMode()).
|
||||
*
|
||||
* Inverting the winding order of front faces is useful when rendering mirrored reflections
|
||||
* (water, mirror surfaces, front camera in AR, etc.).
|
||||
*
|
||||
* @param inverted True to invert front faces, false otherwise.
|
||||
*/
|
||||
void setFrontFaceWindingInverted(bool inverted) noexcept;
|
||||
|
||||
/**
|
||||
* Returns true if the winding order of front faces is inverted.
|
||||
* See setFrontFaceWindingInverted() for more information.
|
||||
*/
|
||||
bool isFrontFaceWindingInverted() const noexcept;
|
||||
|
||||
protected:
|
||||
// prevent heap allocation
|
||||
~MaterialInstance() = default;
|
||||
|
||||
@@ -629,6 +629,27 @@ public:
|
||||
//! Returns true if post-processing is enabled. See setPostProcessingEnabled() for more info.
|
||||
bool isPostProcessingEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Inverts the winding order of front faces. By default front faces use a counter-clockwise
|
||||
* winding order. When the winding order is inverted, front faces are faces with a clockwise
|
||||
* winding order.
|
||||
*
|
||||
* Changing the winding order will directly affect the culling mode in materials
|
||||
* (see Material::getCullingMode()).
|
||||
*
|
||||
* Inverting the winding order of front faces is useful when rendering mirrored reflections
|
||||
* (water, mirror surfaces, front camera in AR, etc.).
|
||||
*
|
||||
* @param inverted True to invert front faces, false otherwise.
|
||||
*/
|
||||
void setFrontFaceWindingInverted(bool inverted) noexcept;
|
||||
|
||||
/**
|
||||
* Returns true if the winding order of front faces is inverted.
|
||||
* See setFrontFaceWindingInverted() for more information.
|
||||
*/
|
||||
bool isFrontFaceWindingInverted() const noexcept;
|
||||
|
||||
/**
|
||||
* Enables use of the stencil buffer.
|
||||
*
|
||||
|
||||
@@ -340,12 +340,4 @@ bool MaterialInstance::isDepthCullingEnabled() const noexcept {
|
||||
return downcast(this)->isDepthCullingEnabled();
|
||||
}
|
||||
|
||||
void MaterialInstance::setFrontFaceWindingInverted(bool inverted) noexcept {
|
||||
downcast(this)->setFrontFaceWindingInverted(inverted);
|
||||
}
|
||||
|
||||
bool MaterialInstance::isFrontFaceWindingInverted() const noexcept {
|
||||
return downcast(this)->isFrontFaceWindingInverted();
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -323,7 +323,7 @@ void RenderPass::instanceify(FEngine& engine) noexcept {
|
||||
UTILS_ALWAYS_INLINE // this function exists only to make the code more readable. we want it inlined.
|
||||
inline // and we don't need it in the compilation unit
|
||||
void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
|
||||
FMaterialInstance const* const UTILS_RESTRICT mi, bool invertedFrontFaces) noexcept {
|
||||
FMaterialInstance const* const UTILS_RESTRICT mi, bool inverseFrontFaces) noexcept {
|
||||
|
||||
FMaterial const * const UTILS_RESTRICT ma = mi->getMaterial();
|
||||
variant = Variant::filterVariant(variant, ma->isVariantLit());
|
||||
@@ -359,7 +359,7 @@ void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
|
||||
cmdDraw.primitive.rasterState.blendFunctionDstAlpha = blendingMustBeOff ?
|
||||
BlendFunction::ZERO : cmdDraw.primitive.rasterState.blendFunctionDstAlpha;
|
||||
|
||||
cmdDraw.primitive.rasterState.inverseFrontFaces = invertedFrontFaces;
|
||||
cmdDraw.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
|
||||
cmdDraw.primitive.rasterState.culling = mi->getCullingMode();
|
||||
cmdDraw.primitive.rasterState.colorWrite = mi->isColorWriteEnabled();
|
||||
cmdDraw.primitive.rasterState.depthWrite = mi->isDepthWriteEnabled();
|
||||
@@ -458,6 +458,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
auto const* const UTILS_RESTRICT soaInstanceInfo = soa.data<FScene::INSTANCES>();
|
||||
|
||||
const bool hasShadowing = renderFlags & HAS_SHADOWING;
|
||||
const bool viewInverseFrontFaces = renderFlags & HAS_INVERSE_FRONT_FACES;
|
||||
const bool hasInstancedStereo = renderFlags & IS_STEREOSCOPIC;
|
||||
|
||||
Command cmdColor;
|
||||
@@ -512,6 +513,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
const uint32_t distanceBits = reinterpret_cast<uint32_t&>(distance);
|
||||
|
||||
// calculate the per-primitive face winding order inversion
|
||||
const bool inverseFrontFaces = viewInverseFrontFaces ^ soaVisibility[i].reversedWindingOrder;
|
||||
const bool hasMorphing = soaVisibility[i].morphing;
|
||||
const bool hasSkinningOrMorphing = soaVisibility[i].skinning || hasMorphing;
|
||||
|
||||
@@ -549,6 +551,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
soaInstanceInfo[i].count | PrimitiveInfo::USER_INSTANCE_MASK;
|
||||
cmdDepth.primitive.instanceBufferHandle = soaInstanceInfo[i].handle;
|
||||
cmdDepth.primitive.materialVariant.setSkinning(hasSkinningOrMorphing);
|
||||
cmdDepth.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
|
||||
|
||||
if (UTILS_UNLIKELY(hasInstancedStereo)) {
|
||||
cmdColor.primitive.instanceCount =
|
||||
@@ -560,9 +563,8 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
renderableVariant.setFog(soaVisibility[i].fog && Variant::isFogVariant(variant));
|
||||
}
|
||||
|
||||
bool const shadowCaster = soaVisibility[i].castShadows & hasShadowing;
|
||||
bool const writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster;
|
||||
bool const reverseWindingOrder = soaVisibility[i].reversedWindingOrder;
|
||||
const bool shadowCaster = soaVisibility[i].castShadows & hasShadowing;
|
||||
const bool writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster;
|
||||
|
||||
const Slice<FRenderPrimitive>& primitives = soaPrimitives[i];
|
||||
const FRenderableManager::SkinningBindingInfo& skinning = soaSkinning[i];
|
||||
@@ -577,11 +579,10 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
auto const& morphTargets = morphing.targets[pi];
|
||||
FMaterialInstance const* const mi = primitive.getMaterialInstance();
|
||||
FMaterial const* const ma = mi->getMaterial();
|
||||
bool const invertedFrontFaces = mi->isFrontFaceWindingInverted() ^ reverseWindingOrder;
|
||||
|
||||
if constexpr (isColorPass) {
|
||||
cmdColor.primitive.primitiveHandle = primitive.getHwHandle();
|
||||
RenderPass::setupColorCommand(cmdColor, renderableVariant, mi, invertedFrontFaces);
|
||||
RenderPass::setupColorCommand(cmdColor, renderableVariant, mi, inverseFrontFaces);
|
||||
|
||||
cmdColor.primitive.skinningHandle = skinning.handle;
|
||||
cmdColor.primitive.skinningOffset = skinning.offset;
|
||||
@@ -610,6 +611,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
cmdColor.key |= makeField(primitive.getBlendOrder(),
|
||||
BLEND_ORDER_MASK, BLEND_ORDER_SHIFT);
|
||||
|
||||
|
||||
const TransparencyMode mode = mi->getTransparencyMode();
|
||||
|
||||
// handle transparent objects, two techniques:
|
||||
@@ -687,7 +689,6 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
cmdDepth.primitive.primitiveHandle = primitive.getHwHandle();
|
||||
cmdDepth.primitive.mi = mi;
|
||||
cmdDepth.primitive.rasterState.culling = mi->getCullingMode();
|
||||
cmdDepth.primitive.rasterState.inverseFrontFaces = invertedFrontFaces;
|
||||
|
||||
cmdDepth.primitive.skinningHandle = skinning.handle;
|
||||
cmdDepth.primitive.skinningOffset = skinning.offset;
|
||||
|
||||
@@ -264,7 +264,8 @@ public:
|
||||
|
||||
using RenderFlags = uint8_t;
|
||||
static constexpr RenderFlags HAS_SHADOWING = 0x01;
|
||||
static constexpr RenderFlags IS_STEREOSCOPIC = 0x02;
|
||||
static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x02;
|
||||
static constexpr RenderFlags IS_STEREOSCOPIC = 0x04;
|
||||
|
||||
// Arena used for commands
|
||||
using Arena = utils::Arena<
|
||||
@@ -415,11 +416,11 @@ private:
|
||||
Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
|
||||
math::float3 cameraPosition, math::float3 cameraForward) noexcept;
|
||||
|
||||
static void setupColorCommand(Command& cmdDraw, Variant variant, FMaterialInstance const* mi,
|
||||
bool invertedFrontFaces) noexcept;
|
||||
static void setupColorCommand(Command& cmdDraw, Variant variant,
|
||||
FMaterialInstance const* mi, bool inverseFrontFaces) noexcept;
|
||||
|
||||
static void updateSummedPrimitiveCounts(FScene::RenderableSoa& renderableData,
|
||||
utils::Range<uint32_t> vr) noexcept;
|
||||
static void updateSummedPrimitiveCounts(
|
||||
FScene::RenderableSoa& renderableData, utils::Range<uint32_t> vr) noexcept;
|
||||
|
||||
// a reference to the Engine, mostly to get to things like JobSystem
|
||||
|
||||
|
||||
@@ -171,6 +171,14 @@ bool View::isPostProcessingEnabled() const noexcept {
|
||||
return downcast(this)->hasPostProcessPass();
|
||||
}
|
||||
|
||||
void View::setFrontFaceWindingInverted(bool inverted) noexcept {
|
||||
downcast(this)->setFrontFaceWindingInverted(inverted);
|
||||
}
|
||||
|
||||
bool View::isFrontFaceWindingInverted() const noexcept {
|
||||
return downcast(this)->isFrontFaceWindingInverted();
|
||||
}
|
||||
|
||||
void View::setDynamicLightingOptions(float zLightNear, float zLightFar) noexcept {
|
||||
downcast(this)->setDynamicLightingOptions(zLightNear, zLightFar);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ FMaterialInstance::FMaterialInstance() noexcept
|
||||
mDepthWrite(false),
|
||||
mHasScissor(false),
|
||||
mIsDoubleSided(false),
|
||||
mTransparencyMode(TransparencyMode::DEFAULT),
|
||||
mFrontFaceWindingInverted(false) {
|
||||
mTransparencyMode(TransparencyMode::DEFAULT) {
|
||||
}
|
||||
|
||||
FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
@@ -61,7 +60,6 @@ FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
mHasScissor(false),
|
||||
mIsDoubleSided(other->mIsDoubleSided),
|
||||
mScissorRect(other->mScissorRect),
|
||||
mFrontFaceWindingInverted(other->mFrontFaceWindingInverted),
|
||||
mName(name ? CString(name) : other->mName) {
|
||||
|
||||
FEngine::DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
@@ -205,14 +205,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void setFrontFaceWindingInverted(bool inverted) noexcept {
|
||||
mFrontFaceWindingInverted = inverted;
|
||||
}
|
||||
|
||||
bool isFrontFaceWindingInverted() const noexcept {
|
||||
return mFrontFaceWindingInverted;
|
||||
}
|
||||
|
||||
const char* getName() const noexcept;
|
||||
|
||||
void setParameter(std::string_view name,
|
||||
@@ -275,8 +267,6 @@ private:
|
||||
(uint32_t)std::numeric_limits<int32_t>::max()
|
||||
};
|
||||
|
||||
bool mFrontFaceWindingInverted : 1;
|
||||
|
||||
utils::CString mName;
|
||||
};
|
||||
|
||||
|
||||
@@ -626,6 +626,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
|
||||
RenderPass::RenderFlags renderFlags = 0;
|
||||
if (view.hasShadowing()) renderFlags |= RenderPass::HAS_SHADOWING;
|
||||
if (view.isFrontFaceWindingInverted()) renderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES;
|
||||
if (view.hasInstancedStereo()) renderFlags |= RenderPass::IS_STEREOSCOPIC;
|
||||
|
||||
RenderPass pass(engine, commandArena);
|
||||
|
||||
@@ -115,6 +115,10 @@ public:
|
||||
void setFrustumCullingEnabled(bool culling) noexcept { mCulling = culling; }
|
||||
bool isFrustumCullingEnabled() const noexcept { return mCulling; }
|
||||
|
||||
void setFrontFaceWindingInverted(bool inverted) noexcept { mFrontFaceWindingInverted = inverted; }
|
||||
bool isFrontFaceWindingInverted() const noexcept { return mFrontFaceWindingInverted; }
|
||||
|
||||
|
||||
void setVisibleLayers(uint8_t select, uint8_t values) noexcept;
|
||||
uint8_t getVisibleLayers() const noexcept {
|
||||
return mVisibleLayers;
|
||||
@@ -491,6 +495,7 @@ private:
|
||||
|
||||
Viewport mViewport;
|
||||
bool mCulling = true;
|
||||
bool mFrontFaceWindingInverted = false;
|
||||
|
||||
FRenderTarget* mRenderTarget = nullptr;
|
||||
|
||||
|
||||
@@ -65,14 +65,13 @@ struct App {
|
||||
View* offscreenView = nullptr;
|
||||
Scene* offscreenScene = nullptr;
|
||||
Camera* offscreenCamera = nullptr;
|
||||
MaterialInstance* invertedMeshMatInstance = nullptr;
|
||||
|
||||
enum class ReflectionMode {
|
||||
NEGATIVE_SCALE_TRANSFORM,
|
||||
MATERIAL,
|
||||
RENDERABLES,
|
||||
CAMERA,
|
||||
};
|
||||
|
||||
ReflectionMode mode = ReflectionMode::MATERIAL;
|
||||
ReflectionMode mode = ReflectionMode::CAMERA;
|
||||
Config config;
|
||||
|
||||
utils::Entity quadEntity;
|
||||
@@ -106,6 +105,22 @@ static mat4f reflectionMatrix(float4 plane) {
|
||||
return transpose(m);
|
||||
}
|
||||
|
||||
static void setReflectionMode(App& app, App::ReflectionMode mode) {
|
||||
switch (mode) {
|
||||
case App::ReflectionMode::RENDERABLES:
|
||||
app.offscreenScene->addEntity(app.reflectedMonkey);
|
||||
app.offscreenScene->remove(app.monkeyMesh.renderable);
|
||||
app.offscreenView->setFrontFaceWindingInverted(false);
|
||||
break;
|
||||
case App::ReflectionMode::CAMERA:
|
||||
app.offscreenScene->addEntity(app.monkeyMesh.renderable);
|
||||
app.offscreenScene->remove(app.reflectedMonkey);
|
||||
app.offscreenView->setFrontFaceWindingInverted(true);
|
||||
break;
|
||||
}
|
||||
app.mode = mode;
|
||||
}
|
||||
|
||||
static void printUsage(char* name) {
|
||||
std::string exec_name(utils::Path(name).getName());
|
||||
std::string usage(
|
||||
@@ -118,7 +133,7 @@ static void printUsage(char* name) {
|
||||
" --api, -a\n"
|
||||
" Specify the backend API: opengl (default), vulkan, or metal\n"
|
||||
" --mode, -m\n"
|
||||
" Specify the reflection mode: material (default), or ntransform\n\n"
|
||||
" Specify the reflection mode: camera (default), or renderables\n\n"
|
||||
);
|
||||
const std::string from("SHOWCASE");
|
||||
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
|
||||
@@ -157,12 +172,12 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) {
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (arg == "material") {
|
||||
app->mode = App::ReflectionMode::MATERIAL;
|
||||
} else if (arg == "ntransform") {
|
||||
app->mode = App::ReflectionMode::NEGATIVE_SCALE_TRANSFORM;
|
||||
if (arg == "camera") {
|
||||
app->mode = App::ReflectionMode::CAMERA;
|
||||
} else if (arg == "renderables") {
|
||||
app->mode = App::ReflectionMode::RENDERABLES;
|
||||
} else {
|
||||
std::cerr << "Unrecognized mode. Must be 'materail'|'ntransform'.\n";
|
||||
std::cerr << "Unrecognized mode. Must be 'camera'|'renderables'.\n";
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
@@ -182,11 +197,6 @@ int main(int argc, char** argv) {
|
||||
auto& em = utils::EntityManager::get();
|
||||
auto vp = view->getViewport();
|
||||
|
||||
// For Vulkan, DEPTH32F is more readily available.
|
||||
auto const depthFormat = app.config.backend == Engine::Backend::VULKAN
|
||||
? Texture::InternalFormat::DEPTH32F
|
||||
: Texture::InternalFormat::DEPTH24;
|
||||
|
||||
// Instantiate offscreen render target.
|
||||
app.offscreenView = engine->createView();
|
||||
app.offscreenScene = engine->createScene();
|
||||
@@ -199,7 +209,7 @@ int main(int argc, char** argv) {
|
||||
app.offscreenDepthTexture = Texture::Builder()
|
||||
.width(vp.width).height(vp.height).levels(1)
|
||||
.usage(Texture::Usage::DEPTH_ATTACHMENT)
|
||||
.format(depthFormat).build(*engine);
|
||||
.format(Texture::InternalFormat::DEPTH24).build(*engine);
|
||||
app.offscreenRenderTarget = RenderTarget::Builder()
|
||||
.texture(RenderTarget::AttachmentPoint::COLOR, app.offscreenColorTexture)
|
||||
.texture(RenderTarget::AttachmentPoint::DEPTH, app.offscreenDepthTexture)
|
||||
@@ -276,22 +286,19 @@ int main(int argc, char** argv) {
|
||||
rcm.setCastShadows(rcm.getInstance(app.monkeyMesh.renderable), false);
|
||||
scene->addEntity(app.monkeyMesh.renderable);
|
||||
|
||||
auto invertedMi = app.invertedMeshMatInstance = MaterialInstance::duplicate(mi);
|
||||
invertedMi->setFrontFaceWindingInverted(true);
|
||||
|
||||
// Create a reflected monkey.
|
||||
// Create a reflected monkey, which is used only for App::ReflectionMode::RENDERABLES.
|
||||
app.reflectedMonkey = em.create();
|
||||
RenderableManager::Builder(1)
|
||||
.boundingBox({{ -2, -2, -2 }, { 2, 2, 2 }})
|
||||
.material(0, app.mode == App::ReflectionMode::MATERIAL ? invertedMi : mi)
|
||||
.material(0, mi)
|
||||
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.monkeyMesh.vertexBuffer, app.monkeyMesh.indexBuffer)
|
||||
.receiveShadows(true)
|
||||
.castShadows(false)
|
||||
.build(*engine, app.reflectedMonkey);
|
||||
app.offscreenScene->addEntity(app.reflectedMonkey);
|
||||
setReflectionMode(app, app.mode);
|
||||
|
||||
// Add light source to both scenes.
|
||||
// NOTE: this is slightly wrong when the reflection mode is NEGATIVE_SCALE_TRANSFORM.
|
||||
// NOTE: this is slightly wrong when the reflection mode is RENDERABLES.
|
||||
app.lightEntity = em.create();
|
||||
LightManager::Builder(LightManager::Type::SUN)
|
||||
.color(Color::toLinear<ACCURATE>(sRGBColor(0.98f, 0.92f, 0.89f)))
|
||||
@@ -314,7 +321,6 @@ int main(int argc, char** argv) {
|
||||
engine->destroy(app.reflectedMonkey);
|
||||
engine->destroy(app.lightEntity);
|
||||
engine->destroy(app.quadEntity);
|
||||
engine->destroy(app.invertedMeshMatInstance);
|
||||
engine->destroy(app.meshMatInstance);
|
||||
engine->destroy(app.meshMaterial);
|
||||
engine->destroy(app.monkeyMesh.renderable);
|
||||
@@ -357,12 +363,11 @@ int main(int argc, char** argv) {
|
||||
app.offscreenCamera->setCustomProjection(renderingProjection, cullingProjection,
|
||||
camera.getNear(), camera.getCullingFar());
|
||||
switch (app.mode) {
|
||||
case App::ReflectionMode::NEGATIVE_SCALE_TRANSFORM:
|
||||
case App::ReflectionMode::RENDERABLES:
|
||||
tcm.setTransform(tcm.getInstance(app.reflectedMonkey), reflection * xform);
|
||||
app.offscreenCamera->setModelMatrix(model);
|
||||
break;
|
||||
case App::ReflectionMode::MATERIAL:
|
||||
tcm.setTransform(tcm.getInstance(app.reflectedMonkey), xform);
|
||||
case App::ReflectionMode::CAMERA:
|
||||
app.offscreenCamera->setModelMatrix(reflection * model);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1411,10 +1411,7 @@ class_<MaterialInstance>("MaterialInstance")
|
||||
.function("setStencilWriteMask", EMBIND_LAMBDA(void,
|
||||
(MaterialInstance* self, uint8_t writeMask), {
|
||||
self->setStencilWriteMask(writeMask, backend::StencilFace::FRONT_AND_BACK);
|
||||
}), allow_raw_pointers())
|
||||
.function("setFrontFaceWindingInverted", &MaterialInstance::setFrontFaceWindingInverted)
|
||||
.function("isFrontFaceWindingInverted", &MaterialInstance::isFrontFaceWindingInverted);
|
||||
|
||||
}), allow_raw_pointers());
|
||||
|
||||
class_<TextureSampler>("TextureSampler")
|
||||
.constructor<backend::SamplerMinFilter, backend::SamplerMagFilter, backend::SamplerWrapMode>()
|
||||
|
||||
Reference in New Issue
Block a user