Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3da96d424 |
@@ -7,3 +7,5 @@ for next branch cut* header.
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
|
||||
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.51.3'
|
||||
implementation 'com.google.android.filament:filament-android:1.51.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.51.3'
|
||||
pod 'Filament', '~> 1.51.0'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -7,13 +7,6 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.51.3
|
||||
|
||||
|
||||
## v1.51.2
|
||||
|
||||
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
|
||||
|
||||
## v1.51.1
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.51.3
|
||||
VERSION_NAME=1.51.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
+1
-32
@@ -1397,7 +1397,7 @@ Type
|
||||
: `string`
|
||||
|
||||
Value
|
||||
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`, `custom`. Defaults to `opaque`.
|
||||
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`. Defaults to `opaque`.
|
||||
|
||||
Description
|
||||
: Defines how/if the rendered object is blended with the content of the render target.
|
||||
@@ -1420,7 +1420,6 @@ Description
|
||||
of the material's output defines whether a fragment is discarded or not. Additionally,
|
||||
ALPHA_TO_COVERAGE is enabled for non-translucent views. See the maskThreshold section for more
|
||||
information.
|
||||
- **Custom**: blending is enabled. But the blending function is user specified. See `blendFunction`.
|
||||
|
||||
!!! Note
|
||||
When `blending` is set to `masked`, alpha to coverage is automatically enabled for the material.
|
||||
@@ -1433,36 +1432,6 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Blending and transparency: blendFunction
|
||||
|
||||
Type
|
||||
: `object`
|
||||
|
||||
Fields
|
||||
: `srcRGB`, `srcA`, `dstRGB`, `dstA`
|
||||
|
||||
Description
|
||||
: - *srcRGB*: source function applied to the RGB channels
|
||||
- *srcA*: source function applied to the alpha channel
|
||||
- *srcRGB*: destination function applied to the RGB channels
|
||||
- *srcRGB*: destination function applied to the alpha channel
|
||||
The values possible for each functions are one of `zero`, `one`, `srcColor`, `oneMinusSrcColor`,
|
||||
`dstColor`, `oneMinusDstColor`, `srcAlpha`, `oneMinusSrcAlpha`, `dstAlpha`,
|
||||
`oneMinusDstAlpha`, `srcAlphaSaturate`
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
blending : custom,
|
||||
blendFunction :
|
||||
{
|
||||
srcRGB: one,
|
||||
srcA: one,
|
||||
dstRGB: oneMinusSrcColor,
|
||||
dstA: oneMinusSrcAlpha
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Blending and transparency: postLightingBlending
|
||||
|
||||
Type
|
||||
|
||||
@@ -134,7 +134,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
|
||||
|
||||
public:
|
||||
template<typename M, typename D>
|
||||
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
|
||||
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) noexcept {
|
||||
Command* self = static_cast<Command*>(base);
|
||||
*next = align(sizeof(Command));
|
||||
#if DEBUG_COMMAND_STREAM
|
||||
@@ -168,7 +168,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
|
||||
|
||||
class CustomCommand : public CommandBase {
|
||||
std::function<void()> mCommand;
|
||||
static void execute(Driver&, CommandBase* base, intptr_t* next);
|
||||
static void execute(Driver&, CommandBase* base, intptr_t* next) noexcept;
|
||||
public:
|
||||
inline CustomCommand(CustomCommand&& rhs) = default;
|
||||
inline explicit CustomCommand(std::function<void()> cmd)
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
// the fn function will execute a batch of driver commands
|
||||
// this gives the driver a chance to wrap their execution in a meaningful manner
|
||||
// the default implementation simply calls fn
|
||||
virtual void execute(std::function<void(void)> const& fn);
|
||||
virtual void execute(std::function<void(void)> const& fn) noexcept;
|
||||
|
||||
// This is called on debug build, or when enabled manually on the backend thread side.
|
||||
virtual void debugCommandBegin(CommandStream* cmds,
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
*
|
||||
*/
|
||||
template<typename D, typename ... ARGS>
|
||||
Handle<D> allocateAndConstruct(ARGS&& ... args) {
|
||||
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
|
||||
Handle<D> h{ allocateHandle<D>() };
|
||||
D* addr = handle_cast<D*>(h);
|
||||
new(addr) D(std::forward<ARGS>(args)...);
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
*/
|
||||
template<typename D, typename B, typename ... ARGS>
|
||||
typename std::enable_if_t<std::is_base_of_v<B, D>, D>*
|
||||
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) {
|
||||
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) noexcept {
|
||||
assert_invariant(handle);
|
||||
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
|
||||
assert_invariant(addr);
|
||||
@@ -163,7 +163,7 @@ public:
|
||||
inline typename std::enable_if_t<
|
||||
std::is_pointer_v<Dp> &&
|
||||
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
|
||||
handle_cast(Handle<B>& handle) {
|
||||
handle_cast(Handle<B>& handle) noexcept {
|
||||
assert_invariant(handle);
|
||||
auto [p, tag] = handleToPointer(handle.getId());
|
||||
|
||||
@@ -185,7 +185,7 @@ public:
|
||||
inline typename std::enable_if_t<
|
||||
std::is_pointer_v<Dp> &&
|
||||
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
|
||||
handle_cast(Handle<B> const& handle) {
|
||||
handle_cast(Handle<B> const& handle) noexcept {
|
||||
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ private:
|
||||
return (id & HANDLE_HEAP_FLAG) == 0u;
|
||||
}
|
||||
|
||||
HandleBase::HandleId allocateHandleSlow(size_t size);
|
||||
HandleBase::HandleId allocateHandleSlow(size_t size) noexcept;
|
||||
void deallocateHandleSlow(HandleBase::HandleId id, size_t size) noexcept;
|
||||
|
||||
// We inline this because it's just 4 instructions in the fast case
|
||||
|
||||
@@ -149,7 +149,7 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log() noexcept {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) {
|
||||
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept {
|
||||
*next = CustomCommand::align(sizeof(CustomCommand));
|
||||
static_cast<CustomCommand*>(base)->mCommand();
|
||||
static_cast<CustomCommand*>(base)->~CustomCommand();
|
||||
|
||||
@@ -214,7 +214,7 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
|
||||
|
||||
Driver::~Driver() noexcept = default;
|
||||
|
||||
void Driver::execute(std::function<void(void)> const& fn) {
|
||||
void Driver::execute(std::function<void(void)> const& fn) noexcept {
|
||||
fn();
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ void* HandleAllocator<P0, P1, P2>::handleToPointerSlow(HandleBase::HandleId id)
|
||||
}
|
||||
|
||||
template <size_t P0, size_t P1, size_t P2>
|
||||
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) {
|
||||
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) noexcept {
|
||||
void* p = ::malloc(size);
|
||||
std::unique_lock lock(mLock);
|
||||
|
||||
|
||||
@@ -1634,7 +1634,7 @@ void MetalDriver::bindPipeline(PipelineState ps) {
|
||||
return;
|
||||
}
|
||||
|
||||
functions.validate();
|
||||
ASSERT_PRECONDITION(bool(functions), "Attempting to bind an invalid Metal program.");
|
||||
|
||||
auto [fragment, vertex] = functions.getRasterFunctions();
|
||||
|
||||
|
||||
@@ -724,19 +724,10 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
GLenum internalFormat = getInternalFormat(format);
|
||||
assert_invariant(internalFormat);
|
||||
|
||||
if (any(usage & TextureUsage::PROTECTED)) {
|
||||
if (UTILS_UNLIKELY(usage & TextureUsage::PROTECTED)) {
|
||||
// renderbuffers don't have a protected mode, so we need to use a texture
|
||||
// because protected textures are only supported on GLES 3.2, MSAA will be available.
|
||||
usage |= TextureUsage::SAMPLEABLE;
|
||||
} else if (any(usage & TextureUsage::UPLOADABLE)) {
|
||||
// if we have the uploadable flag, we also need to use a texture
|
||||
usage |= TextureUsage::SAMPLEABLE;
|
||||
} else if (target != SamplerType::SAMPLER_2D) {
|
||||
// renderbuffers can only be 2D
|
||||
usage |= TextureUsage::SAMPLEABLE;
|
||||
} else if (levels > 1) {
|
||||
// renderbuffers can't have mip levels
|
||||
usage |= TextureUsage::SAMPLEABLE;
|
||||
}
|
||||
|
||||
auto& gl = mContext;
|
||||
@@ -812,6 +803,13 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
textureStorage(t, w, h, depth, bool(usage & TextureUsage::PROTECTED));
|
||||
}
|
||||
} else {
|
||||
assert_invariant(any(usage & (
|
||||
TextureUsage::COLOR_ATTACHMENT |
|
||||
TextureUsage::DEPTH_ATTACHMENT |
|
||||
TextureUsage::STENCIL_ATTACHMENT)));
|
||||
assert_invariant(levels == 1);
|
||||
assert_invariant(target == SamplerType::SAMPLER_2D);
|
||||
assert_invariant(none(usage & TextureUsage::PROTECTED));
|
||||
t->gl.internalFormat = internalFormat;
|
||||
t->gl.target = GL_RENDERBUFFER;
|
||||
glGenRenderbuffers(1, &t->gl.id);
|
||||
|
||||
@@ -268,13 +268,13 @@ private:
|
||||
HandleAllocatorGL mHandleAllocator;
|
||||
|
||||
template<typename D, typename ... ARGS>
|
||||
Handle<D> initHandle(ARGS&& ... args) {
|
||||
Handle<D> initHandle(ARGS&& ... args) noexcept {
|
||||
return mHandleAllocator.allocateAndConstruct<D>(std::forward<ARGS>(args) ...);
|
||||
}
|
||||
|
||||
template<typename D, typename B, typename ... ARGS>
|
||||
typename std::enable_if<std::is_base_of<B, D>::value, D>::type*
|
||||
construct(Handle<B> const& handle, ARGS&& ... args) {
|
||||
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
|
||||
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ private:
|
||||
typename std::enable_if_t<
|
||||
std::is_pointer_v<Dp> &&
|
||||
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
|
||||
handle_cast(Handle<B>& handle) {
|
||||
handle_cast(Handle<B>& handle) noexcept {
|
||||
return mHandleAllocator.handle_cast<Dp, B>(handle);
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ private:
|
||||
inline typename std::enable_if_t<
|
||||
std::is_pointer_v<Dp> &&
|
||||
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
|
||||
handle_cast(Handle<B> const& handle) {
|
||||
handle_cast(Handle<B> const& handle) noexcept {
|
||||
return mHandleAllocator.handle_cast<Dp, B>(handle);
|
||||
}
|
||||
|
||||
|
||||
@@ -277,16 +277,6 @@ bool MaterialParser::getBlendingMode(BlendingMode* value) const noexcept {
|
||||
return mImpl.getFromSimpleChunk(ChunkType::MaterialBlendingMode, reinterpret_cast<uint8_t*>(value));
|
||||
}
|
||||
|
||||
bool MaterialParser::getCustomBlendFunction(std::array<BlendFunction, 4>* value) const noexcept {
|
||||
uint32_t blendFunctions = 0;
|
||||
bool const result = mImpl.getFromSimpleChunk(ChunkType::MaterialBlendFunction, &blendFunctions);
|
||||
(*value)[0] = BlendFunction((blendFunctions >> 24) & 0xFF);
|
||||
(*value)[1] = BlendFunction((blendFunctions >> 16) & 0xFF);
|
||||
(*value)[2] = BlendFunction((blendFunctions >> 8) & 0xFF);
|
||||
(*value)[3] = BlendFunction((blendFunctions >> 0) & 0xFF);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MaterialParser::getMaskThreshold(float* value) const noexcept {
|
||||
return mImpl.getFromSimpleChunk(ChunkType::MaterialMaskThreshold, value);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,6 @@ public:
|
||||
|
||||
bool getShading(Shading*) const noexcept;
|
||||
bool getBlendingMode(BlendingMode*) const noexcept;
|
||||
bool getCustomBlendFunction(std::array<backend::BlendFunction, 4>*) const noexcept;
|
||||
bool getMaskThreshold(float*) const noexcept;
|
||||
bool getAlphaToCoverageSet(bool*) const noexcept;
|
||||
bool getAlphaToCoverage(bool*) const noexcept;
|
||||
|
||||
@@ -450,8 +450,11 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
|
||||
.levels = uint8_t(levelCount),
|
||||
.format = isES2 ? TextureFormat::DEPTH24 : TextureFormat::DEPTH32F });
|
||||
|
||||
// workaround: since we have levels, this implies SAMPLEABLE (because of the gl
|
||||
// backend, which implements non-sampleables with renderbuffers, which don't have levels).
|
||||
// (should the gl driver revert to textures, in that case?)
|
||||
data.depth = builder.write(data.depth,
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT | FrameGraphTexture::Usage::SAMPLEABLE);
|
||||
|
||||
if (config.picking) {
|
||||
data.picking = builder.createTexture("Picking Buffer", {
|
||||
|
||||
@@ -16,35 +16,17 @@
|
||||
|
||||
#include "RendererUtils.h"
|
||||
|
||||
#include "PostProcessManager.h"
|
||||
|
||||
#include "details/Engine.h"
|
||||
#include "details/View.h"
|
||||
|
||||
#include "fg/FrameGraph.h"
|
||||
#include "fg/FrameGraphId.h"
|
||||
#include "fg/FrameGraphResources.h"
|
||||
#include "fg/FrameGraphTexture.h"
|
||||
|
||||
#include <filament/Options.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
@@ -171,9 +153,16 @@ FrameGraphId<FrameGraphTexture> RendererUtils::colorPass(
|
||||
data.depth = builder.read(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
|
||||
data.color = builder.write(data.color, FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
data.depth = builder.write(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
if (engine.getConfig().stereoscopicType == StereoscopicType::MULTIVIEW) {
|
||||
// Add sampleable usage flag for depth in multiview rendering, othewise it's
|
||||
// treated as renderbuffer in the backend and crashed.
|
||||
data.depth = builder.write(data.depth,
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT |
|
||||
FrameGraphTexture::Usage::SAMPLEABLE);
|
||||
layerCount = engine.getConfig().stereoscopicEyeCount;
|
||||
} else {
|
||||
data.depth = builder.write(data.depth,
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -323,8 +323,12 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
|
||||
parser->getMaskThreshold(&mMaskThreshold);
|
||||
}
|
||||
|
||||
if (mBlendingMode == BlendingMode::CUSTOM) {
|
||||
parser->getCustomBlendFunction(&mCustomBlendFunctions);
|
||||
// The fade blending mode only affects shading. For proper sorting we need to
|
||||
// treat this blending mode as a regular transparent blending operation.
|
||||
if (UTILS_UNLIKELY(mBlendingMode == BlendingMode::FADE)) {
|
||||
mRenderBlendingMode = BlendingMode::TRANSPARENT;
|
||||
} else {
|
||||
mRenderBlendingMode = mBlendingMode;
|
||||
}
|
||||
|
||||
if (mShading == Shading::UNLIT) {
|
||||
@@ -377,12 +381,6 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
|
||||
mRasterState.blendFunctionDstAlpha = BlendFunction::ONE_MINUS_SRC_COLOR;
|
||||
mRasterState.depthWrite = false;
|
||||
break;
|
||||
case BlendingMode::CUSTOM:
|
||||
mRasterState.blendFunctionSrcRGB = mCustomBlendFunctions[0];
|
||||
mRasterState.blendFunctionSrcAlpha = mCustomBlendFunctions[1];
|
||||
mRasterState.blendFunctionDstRGB = mCustomBlendFunctions[2];
|
||||
mRasterState.blendFunctionDstAlpha = mCustomBlendFunctions[3];
|
||||
mRasterState.depthWrite = false;
|
||||
}
|
||||
|
||||
bool depthWriteSet = false;
|
||||
|
||||
@@ -127,6 +127,7 @@ public:
|
||||
Shading getShading() const noexcept { return mShading; }
|
||||
Interpolation getInterpolation() const noexcept { return mInterpolation; }
|
||||
BlendingMode getBlendingMode() const noexcept { return mBlendingMode; }
|
||||
BlendingMode getRenderBlendingMode() const noexcept { return mRenderBlendingMode; }
|
||||
VertexDomain getVertexDomain() const noexcept { return mVertexDomain; }
|
||||
MaterialDomain getMaterialDomain() const noexcept { return mMaterialDomain; }
|
||||
CullingMode getCullingMode() const noexcept { return mCullingMode; }
|
||||
@@ -222,13 +223,13 @@ private:
|
||||
mutable std::array<backend::Handle<backend::HwProgram>, VARIANT_COUNT> mCachedPrograms;
|
||||
|
||||
backend::RasterState mRasterState;
|
||||
BlendingMode mRenderBlendingMode = BlendingMode::OPAQUE;
|
||||
TransparencyMode mTransparencyMode = TransparencyMode::DEFAULT;
|
||||
bool mIsVariantLit = false;
|
||||
backend::FeatureLevel mFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1;
|
||||
Shading mShading = Shading::UNLIT;
|
||||
|
||||
BlendingMode mBlendingMode = BlendingMode::OPAQUE;
|
||||
std::array<backend::BlendFunction, 4> mCustomBlendFunctions = {};
|
||||
Interpolation mInterpolation = Interpolation::SMOOTH;
|
||||
VertexDomain mVertexDomain = VertexDomain::OBJECT;
|
||||
MaterialDomain mMaterialDomain = MaterialDomain::SURFACE;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.51.3"
|
||||
spec.version = "1.51.0"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.51.3/filament-v1.51.3-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.51.0/filament-v1.51.0-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -59,7 +59,6 @@ enum UTILS_PUBLIC ChunkType : uint64_t {
|
||||
MaterialFeatureLevel = charTo64bitNum("MAT_FEAT"),
|
||||
MaterialShading = charTo64bitNum("MAT_SHAD"),
|
||||
MaterialBlendingMode = charTo64bitNum("MAT_BLEN"),
|
||||
MaterialBlendFunction = charTo64bitNum("MAT_BLFN"),
|
||||
MaterialTransparencyMode = charTo64bitNum("MAT_TRMD"),
|
||||
MaterialMaskThreshold = charTo64bitNum("MAT_THRS"),
|
||||
MaterialShadowMultiplier = charTo64bitNum("MAT_SHML"),
|
||||
|
||||
@@ -80,8 +80,6 @@ enum class BlendingMode : uint8_t {
|
||||
MULTIPLY,
|
||||
//! material brightens what's behind it
|
||||
SCREEN,
|
||||
//! custom blending function
|
||||
CUSTOM,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -227,7 +227,6 @@ public:
|
||||
|
||||
using ShaderQuality = filament::ShaderQuality;
|
||||
using BlendingMode = filament::BlendingMode;
|
||||
using BlendFunction = filament::backend::BlendFunction;
|
||||
using Shading = filament::Shading;
|
||||
using Interpolation = filament::Interpolation;
|
||||
using VertexDomain = filament::VertexDomain;
|
||||
@@ -408,15 +407,6 @@ public:
|
||||
*/
|
||||
MaterialBuilder& blending(BlendingMode blending) noexcept;
|
||||
|
||||
/**
|
||||
* Set the blend function for this material. blending must be et to CUSTOM.
|
||||
*/
|
||||
MaterialBuilder& customBlendFunctions(
|
||||
BlendFunction srcRGB,
|
||||
BlendFunction srcA,
|
||||
BlendFunction dstRGB,
|
||||
BlendFunction dstA) noexcept;
|
||||
|
||||
/**
|
||||
* Set the blending mode of the post-lighting color for this material.
|
||||
* Only OPAQUE, TRANSPARENT and ADD are supported, the default is TRANSPARENT.
|
||||
@@ -838,7 +828,6 @@ private:
|
||||
FeatureLevel mFeatureLevel = FeatureLevel::FEATURE_LEVEL_1;
|
||||
BlendingMode mBlendingMode = BlendingMode::OPAQUE;
|
||||
BlendingMode mPostLightingBlendingMode = BlendingMode::TRANSPARENT;
|
||||
std::array<BlendFunction, 4> mCustomBlendFunctions = {};
|
||||
CullingMode mCullingMode = CullingMode::BACK;
|
||||
Shading mShading = Shading::LIT;
|
||||
MaterialDomain mMaterialDomain = MaterialDomain::SURFACE;
|
||||
|
||||
@@ -388,16 +388,6 @@ MaterialBuilder& MaterialBuilder::blending(BlendingMode blending) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::customBlendFunctions(
|
||||
BlendFunction srcRGB, BlendFunction srcA,
|
||||
BlendFunction dstRGB, BlendFunction dstA) noexcept {
|
||||
mCustomBlendFunctions[0] = srcRGB;
|
||||
mCustomBlendFunctions[1] = srcA;
|
||||
mCustomBlendFunctions[2] = dstRGB;
|
||||
mCustomBlendFunctions[3] = dstA;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::postLightingBlending(BlendingMode blending) noexcept {
|
||||
mPostLightingBlendingMode = blending;
|
||||
return *this;
|
||||
@@ -1520,16 +1510,6 @@ void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo&
|
||||
container.emplace<bool>(ChunkType::MaterialDoubleSided, mDoubleSided);
|
||||
container.emplace<uint8_t>(ChunkType::MaterialBlendingMode,
|
||||
static_cast<uint8_t>(mBlendingMode));
|
||||
|
||||
if (mBlendingMode == BlendingMode::CUSTOM) {
|
||||
uint32_t const blendFunctions =
|
||||
(uint32_t(mCustomBlendFunctions[0]) << 24) |
|
||||
(uint32_t(mCustomBlendFunctions[1]) << 16) |
|
||||
(uint32_t(mCustomBlendFunctions[2]) << 8) |
|
||||
(uint32_t(mCustomBlendFunctions[3]) << 0);
|
||||
container.emplace< uint32_t >(ChunkType::MaterialBlendFunction, blendFunctions);
|
||||
}
|
||||
|
||||
container.emplace<uint8_t>(ChunkType::MaterialTransparencyMode,
|
||||
static_cast<uint8_t>(mTransparencyMode));
|
||||
container.emplace<uint8_t>(ChunkType::MaterialReflectionMode,
|
||||
|
||||
@@ -157,9 +157,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream&
|
||||
case BlendingMode::SCREEN:
|
||||
CodeGenerator::generateDefine(out, "BLEND_MODE_SCREEN", true);
|
||||
break;
|
||||
case BlendingMode::CUSTOM:
|
||||
CodeGenerator::generateDefine(out, "BLEND_MODE_CUSTOM", true);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (material.postLightingBlendingMode) {
|
||||
@@ -178,9 +175,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream&
|
||||
case BlendingMode::SCREEN:
|
||||
CodeGenerator::generateDefine(out, "POST_LIGHTING_BLEND_MODE_SCREEN", true);
|
||||
break;
|
||||
case BlendingMode::CUSTOM:
|
||||
CodeGenerator::generateDefine(out, "POST_LIGHTING_BLEND_MODE_CUSTOM", true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,6 @@ const char* toString(BlendingMode blendingMode) noexcept {
|
||||
case BlendingMode::FADE: return "fade";
|
||||
case BlendingMode::MULTIPLY: return "multiply";
|
||||
case BlendingMode::SCREEN: return "screen";
|
||||
case BlendingMode::CUSTOM: return "custom";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ const char* toString(BlendingMode blendingMode) noexcept {
|
||||
case BlendingMode::FADE: return "fade";
|
||||
case BlendingMode::MULTIPLY: return "multiply";
|
||||
case BlendingMode::SCREEN: return "screen";
|
||||
case BlendingMode::CUSTOM: return "custom";
|
||||
}
|
||||
return "--";
|
||||
}
|
||||
|
||||
@@ -76,8 +76,6 @@ static string_view readBlendingMode(string_view cursor, BlendingMode* blending)
|
||||
*blending = BlendingMode::MULTIPLY;
|
||||
} else if (sz = readPrefix("screen"sv, cursor); sz > 0) {
|
||||
*blending = BlendingMode::SCREEN;
|
||||
} else if (sz = readPrefix("custom"sv, cursor); sz > 0) {
|
||||
*blending = BlendingMode::CUSTOM;
|
||||
}
|
||||
return { cursor.data(), sz };
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@ if (LINUX OR ANDROID)
|
||||
list(APPEND SRCS src/linux/Path.cpp)
|
||||
endif()
|
||||
if (APPLE)
|
||||
list(APPEND SRCS src/darwin/Exception.mm)
|
||||
list(APPEND SRCS src/darwin/Path.mm)
|
||||
list(APPEND SRCS src/darwin/Systrace.cpp)
|
||||
endif()
|
||||
@@ -122,6 +123,10 @@ if (LINUX)
|
||||
target_link_libraries(${TARGET} PRIVATE dl)
|
||||
endif()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
target_link_libraries(${TARGET} PRIVATE "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Installation
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -250,71 +250,54 @@ namespace utils {
|
||||
*/
|
||||
class UTILS_PUBLIC Panic {
|
||||
public:
|
||||
|
||||
using PanicHandlerCallback = void(*)(void* user, Panic const& panic);
|
||||
|
||||
/**
|
||||
* Sets a user-defined handler for the Panic. If exceptions are enabled, the concrete Panic
|
||||
* object will be thrown upon return; moreover it is acceptable to throw from the provided
|
||||
* callback, but it is unsafe to throw the Panic object itself, since it's just an interface.
|
||||
* It is also acceptable to abort from the callback. If exceptions are not enabled, std::abort()
|
||||
* will be automatically called upon return.
|
||||
*
|
||||
* The PanicHandlerCallback can be called from any thread.
|
||||
*
|
||||
* Caveat: this API can misbehave if is used as a static library in multiple translation units,
|
||||
* some of these translation units might not see the callback.
|
||||
*
|
||||
* @param handler pointer to the user defined handler for the Panic
|
||||
* @param user user pointer given back to the callback
|
||||
*/
|
||||
static void setPanicHandler(PanicHandlerCallback handler, void* user) noexcept;
|
||||
|
||||
|
||||
virtual ~Panic() noexcept;
|
||||
|
||||
/**
|
||||
* @return a formatted and detailed description of the error including all available
|
||||
* information.
|
||||
* @return a detailed description of the error
|
||||
* @see std::exception
|
||||
*/
|
||||
virtual const char* what() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the reason string for the panic
|
||||
* @return a C string containing the reason for the panic
|
||||
* Get the reason for the panic.
|
||||
* @return a C string containing the reason for the panic.
|
||||
*/
|
||||
virtual const char* getReason() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the function name where the panic was detected. On debug build the fully qualified
|
||||
* function name is returned; on release builds only the function name is.
|
||||
* Get the type of the panic. When compiled without RTTI, this returns a generic type name.
|
||||
* @return a C string containing the type of the panic.
|
||||
*/
|
||||
virtual const char* getType() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the function name where the panic was detected
|
||||
* @return a C string containing the function name where the panic was detected
|
||||
*/
|
||||
virtual const char* getFunction() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the file name where the panic was detected. Only available on debug builds.
|
||||
* Get the file name where the panic was detected
|
||||
* @return a C string containing the file name where the panic was detected
|
||||
*/
|
||||
virtual const char* getFile() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the line number in the file where the panic was detected. Only available on debug builds.
|
||||
* Get the line number in the file where the panic was detected
|
||||
* @return an integer containing the line number in the file where the panic was detected
|
||||
*/
|
||||
virtual int getLine() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the CallStack when the panic was detected if available.
|
||||
* @return the CallStack when the panic was detected
|
||||
*/
|
||||
virtual const CallStack& getCallStack() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Logs this exception to the system-log
|
||||
*/
|
||||
virtual void log() const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Get the CallStack when the panic was detected
|
||||
* @return the CallStack when the panic was detected
|
||||
*/
|
||||
virtual const CallStack& getCallStack() const noexcept = 0;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
@@ -335,6 +318,7 @@ public:
|
||||
|
||||
// Panic interface
|
||||
const char* getReason() const noexcept override;
|
||||
const char* getType() const noexcept override;
|
||||
const char* getFunction() const noexcept override;
|
||||
const char* getFile() const noexcept override;
|
||||
int getLine() const noexcept override;
|
||||
@@ -399,7 +383,8 @@ private:
|
||||
char const* const m_function = nullptr;
|
||||
char const* const m_file = nullptr;
|
||||
const int m_line = -1;
|
||||
mutable std::string m_msg;
|
||||
std::string m_msg;
|
||||
std::string m_type;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_UTILS_DARWIN_EXCEPTION_H
|
||||
#define TNT_UTILS_DARWIN_EXCEPTION_H
|
||||
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
|
||||
namespace utils::details {
|
||||
|
||||
void throwDarwinException(const Panic& exception) UTILS_NORETURN;
|
||||
|
||||
}
|
||||
|
||||
#endif // TNT_UTILS_DARWIN_EXCEPTION_H
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <utils/compiler.h>
|
||||
|
||||
namespace utils {
|
||||
UTILS_PUBLIC
|
||||
void panic(const char *func, const char * file, int line, const char *assertion) noexcept;
|
||||
} // namespace filament
|
||||
|
||||
|
||||
+26
-79
@@ -14,64 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <utils/darwin/Exception.h>
|
||||
#endif
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdarg>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
namespace utils {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
class UserPanicHandler {
|
||||
struct CallBack {
|
||||
Panic::PanicHandlerCallback handler = nullptr;
|
||||
void* user = nullptr;
|
||||
void call(Panic const& panic) const noexcept {
|
||||
if (UTILS_UNLIKELY(handler)) {
|
||||
handler(user, panic);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mutable std::mutex mLock{};
|
||||
CallBack mCallBack{};
|
||||
|
||||
CallBack getCallback() const noexcept {
|
||||
std::lock_guard const lock(mLock);
|
||||
return mCallBack;
|
||||
}
|
||||
|
||||
public:
|
||||
static UserPanicHandler& get() noexcept {
|
||||
static UserPanicHandler data;
|
||||
return data;
|
||||
}
|
||||
|
||||
void call(Panic const& panic) const noexcept {
|
||||
getCallback().call(panic);
|
||||
}
|
||||
|
||||
void set(Panic::PanicHandlerCallback handler, void* user) noexcept {
|
||||
std::lock_guard const lock(mLock);
|
||||
mCallBack = { handler, user };
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
static std::string formatString(const char* format, va_list args) noexcept {
|
||||
std::string reason;
|
||||
|
||||
@@ -82,12 +39,10 @@ static std::string formatString(const char* format, va_list args) noexcept {
|
||||
|
||||
if (n >= 0) {
|
||||
++n; // for the nul-terminating char
|
||||
char* const buf = new(std::nothrow) char[n];
|
||||
if (buf) {
|
||||
vsnprintf(buf, size_t(n), format, args);
|
||||
reason.assign(buf);
|
||||
delete [] buf;
|
||||
}
|
||||
char* buf = new char[n];
|
||||
vsnprintf(buf, size_t(n), format, args);
|
||||
reason.assign(buf);
|
||||
delete [] buf;
|
||||
}
|
||||
return reason;
|
||||
}
|
||||
@@ -112,16 +67,8 @@ static std::string panicString(
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
Panic::~Panic() noexcept = default;
|
||||
|
||||
void Panic::setPanicHandler(PanicHandlerCallback handler, void* user) noexcept {
|
||||
UserPanicHandler::get().set(handler, user);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
TPanic<T>::TPanic(std::string reason) :
|
||||
m_reason(std::move(reason)) {
|
||||
@@ -150,6 +97,11 @@ const char* TPanic<T>::getReason() const noexcept {
|
||||
return m_reason.c_str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const char* TPanic<T>::getType() const noexcept {
|
||||
return m_type.c_str();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const char* TPanic<T>::getFunction() const noexcept {
|
||||
return m_function;
|
||||
@@ -178,13 +130,12 @@ void TPanic<T>::log() const noexcept {
|
||||
|
||||
template<typename T>
|
||||
void TPanic<T>::buildMessage() {
|
||||
std::string type;
|
||||
#if UTILS_HAS_RTTI
|
||||
type = CallStack::demangleTypeName(typeid(T).name()).c_str();
|
||||
m_type = CallStack::demangleTypeName(typeid(T).name()).c_str();
|
||||
#else
|
||||
type = "Panic";
|
||||
m_type = "Panic";
|
||||
#endif
|
||||
m_msg = panicString(type, m_function, m_line, m_file, m_reason.c_str());
|
||||
m_msg = panicString(m_type, m_function, m_line, m_file, m_reason.c_str());
|
||||
}
|
||||
|
||||
UTILS_ALWAYS_INLINE
|
||||
@@ -197,22 +148,18 @@ template<typename T>
|
||||
void TPanic<T>::panic(char const* function, char const* file, int line, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string const reason(formatString(format, args));
|
||||
std::string reason(formatString(format, args));
|
||||
va_end(args);
|
||||
T e(function, formatFile(file), line, reason);
|
||||
|
||||
// always log the Panic at the point it is detected
|
||||
e.log();
|
||||
|
||||
// Call the user provided handler
|
||||
UserPanicHandler::get().call(e);
|
||||
|
||||
// if exceptions are enabled, throw now.
|
||||
#ifdef __EXCEPTIONS
|
||||
throw e;
|
||||
#if defined(__APPLE__)
|
||||
details::throwDarwinException(e);
|
||||
#endif
|
||||
|
||||
// and finally abort if we somehow get here
|
||||
#ifdef __EXCEPTIONS
|
||||
throw e;
|
||||
#endif
|
||||
std::abort();
|
||||
}
|
||||
|
||||
@@ -223,7 +170,7 @@ namespace details {
|
||||
void panicLog(char const* function, char const* file, int line, const char* format, ...) noexcept {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
std::string const reason(formatString(format, args));
|
||||
std::string reason(formatString(format, args));
|
||||
va_end(args);
|
||||
|
||||
const std::string msg = panicString("" /* no extra message */,
|
||||
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
namespace utils::details {
|
||||
|
||||
void throwDarwinException(const Panic& exception) {
|
||||
// Turn this exception into an NSException and raise it.
|
||||
// This is allowed even if we're built without Objective-C exceptions (-fno-objc-exceptions).
|
||||
[[NSException exceptionWithName:@(exception.getType())
|
||||
reason:@(exception.getReason())
|
||||
userInfo:@{
|
||||
@"file" : @(exception.getFile()),
|
||||
@"line" : @(exception.getLine()),
|
||||
@"function" : @(exception.getFunction())
|
||||
}] raise];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -671,7 +671,6 @@ static bool processBlending(MaterialBuilder& builder, const JsonishValue& value)
|
||||
{ "fade", MaterialBuilder::BlendingMode::FADE },
|
||||
{ "multiply", MaterialBuilder::BlendingMode::MULTIPLY },
|
||||
{ "screen", MaterialBuilder::BlendingMode::SCREEN },
|
||||
{ "custom", MaterialBuilder::BlendingMode::CUSTOM },
|
||||
};
|
||||
auto jsonString = value.toJsonString();
|
||||
if (!isStringValidEnum(strToEnum, jsonString->getString())) {
|
||||
@@ -682,52 +681,6 @@ static bool processBlending(MaterialBuilder& builder, const JsonishValue& value)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool processBlendFunction(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
static const std::unordered_map<std::string, MaterialBuilder::BlendFunction> strToEnum{
|
||||
{ "zero", MaterialBuilder::BlendFunction::ZERO },
|
||||
{ "one", MaterialBuilder::BlendFunction::ONE },
|
||||
{ "srcColor", MaterialBuilder::BlendFunction::SRC_COLOR },
|
||||
{ "oneMinusSrcColor", MaterialBuilder::BlendFunction::ONE_MINUS_SRC_COLOR },
|
||||
{ "dstColor", MaterialBuilder::BlendFunction::DST_COLOR },
|
||||
{ "oneMinusDstColor", MaterialBuilder::BlendFunction::ONE_MINUS_DST_COLOR },
|
||||
{ "srcAlpha", MaterialBuilder::BlendFunction::SRC_ALPHA },
|
||||
{ "oneMinusSrcAlpha", MaterialBuilder::BlendFunction::ONE_MINUS_SRC_ALPHA },
|
||||
{ "dstAlpha", MaterialBuilder::BlendFunction::DST_ALPHA },
|
||||
{ "oneMinusDstAlpha", MaterialBuilder::BlendFunction::ONE_MINUS_DST_ALPHA },
|
||||
{ "srcAlphaSaturate", MaterialBuilder::BlendFunction::SRC_ALPHA_SATURATE },
|
||||
};
|
||||
|
||||
if (value.getType() != JsonishValue::Type::OBJECT) {
|
||||
std::cerr << "blendFunction must be an OBJECT." << std::endl;
|
||||
}
|
||||
|
||||
JsonishObject const* const jsonObject = value.toJsonObject();
|
||||
|
||||
MaterialBuilder::BlendFunction srcRGB, srcA, dstRGB, dstA;
|
||||
std::pair<const char*, MaterialBuilder::BlendFunction*> functions[] = {
|
||||
{ "srcRGB", &srcRGB },
|
||||
{ "srcA", &srcA },
|
||||
{ "dstRGB", &dstRGB },
|
||||
{ "dstA", &dstA },
|
||||
};
|
||||
|
||||
for (auto&& entry : functions) {
|
||||
const char* key = entry.first;
|
||||
const JsonishValue* v = jsonObject->getValue(key);
|
||||
if (!v) {
|
||||
std::cerr << "blendFunction: entry without '" << key << "' key." << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (v->getType() != JsonishValue::STRING) {
|
||||
std::cerr << "blendFunction: '" << key << "' value must be STRING." << std::endl;
|
||||
return false;
|
||||
}
|
||||
*entry.second = stringToEnum(strToEnum, v->toJsonString()->getString());
|
||||
}
|
||||
builder.customBlendFunctions(srcRGB, srcA, dstRGB, dstA);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool processPostLightingBlending(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
static const std::unordered_map<std::string, MaterialBuilder::BlendingMode> strToEnum {
|
||||
{ "add", MaterialBuilder::BlendingMode::ADD },
|
||||
@@ -1241,7 +1194,6 @@ ParametersProcessor::ParametersProcessor() {
|
||||
mParameters["variables"] = { &processVariables, Type::ARRAY };
|
||||
mParameters["requires"] = { &processRequires, Type::ARRAY };
|
||||
mParameters["blending"] = { &processBlending, Type::STRING };
|
||||
mParameters["blendFunction"] = { &processBlendFunction, Type::OBJECT };
|
||||
mParameters["postLightingBlending"] = { &processPostLightingBlending, Type::STRING };
|
||||
mParameters["vertexDomain"] = { &processVertexDomain, Type::STRING };
|
||||
mParameters["culling"] = { &processCulling, Type::STRING };
|
||||
|
||||
@@ -369,8 +369,8 @@ using EntityVector = std::vector<utils::Entity>;
|
||||
|
||||
register_vector<std::string>("RegistryKeys");
|
||||
register_vector<utils::Entity>("EntityVector");
|
||||
register_vector<allow_raw_pointer<FilamentInstance*>>("AssetInstanceVector");
|
||||
register_vector<allow_raw_pointer<MaterialInstance*>>("MaterialInstanceVector");
|
||||
register_vector<FilamentInstance*>("AssetInstanceVector");
|
||||
register_vector<MaterialInstance*>("MaterialInstanceVector");
|
||||
|
||||
// CORE FILAMENT CLASSES
|
||||
// ---------------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"version": "1.51.3",
|
||||
"version": "1.51.0",
|
||||
"description": "Real-time physically based rendering engine",
|
||||
"main": "filament.js",
|
||||
"module": "filament.js",
|
||||
|
||||
Reference in New Issue
Block a user