395 lines
16 KiB
C++
395 lines
16 KiB
C++
/*
|
|
* Copyright (C) 2015 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_FILAMENT_MATERIAL_H
|
|
#define TNT_FILAMENT_MATERIAL_H
|
|
|
|
#include <filament/Color.h>
|
|
#include <filament/FilamentAPI.h>
|
|
#include <filament/MaterialEnums.h>
|
|
#include <filament/MaterialInstance.h>
|
|
|
|
#include <backend/CallbackHandler.h>
|
|
#include <backend/DriverEnums.h>
|
|
|
|
#include <utils/compiler.h>
|
|
#include <utils/Invocable.h>
|
|
|
|
#include <math/mathfwd.h>
|
|
|
|
#include <type_traits>
|
|
#include <utility>
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
namespace utils {
|
|
class CString;
|
|
} // namespace utils
|
|
|
|
namespace filament {
|
|
|
|
class Texture;
|
|
class TextureSampler;
|
|
|
|
class FEngine;
|
|
class FMaterial;
|
|
|
|
class Engine;
|
|
|
|
class UTILS_PUBLIC Material : public FilamentAPI {
|
|
struct BuilderDetails;
|
|
|
|
public:
|
|
using BlendingMode = filament::BlendingMode;
|
|
using Shading = filament::Shading;
|
|
using Interpolation = filament::Interpolation;
|
|
using VertexDomain = filament::VertexDomain;
|
|
using TransparencyMode = filament::TransparencyMode;
|
|
|
|
using ParameterType = backend::UniformType;
|
|
using Precision = backend::Precision;
|
|
using SamplerType = backend::SamplerType;
|
|
using SamplerFormat = backend::SamplerFormat;
|
|
using CullingMode = backend::CullingMode;
|
|
using ShaderModel = backend::ShaderModel;
|
|
using SubpassType = backend::SubpassType;
|
|
|
|
/**
|
|
* Holds information about a material parameter.
|
|
*/
|
|
struct ParameterInfo {
|
|
//! Name of the parameter.
|
|
const char* UTILS_NONNULL name;
|
|
//! Whether the parameter is a sampler (texture).
|
|
bool isSampler;
|
|
//! Whether the parameter is a subpass type.
|
|
bool isSubpass;
|
|
union {
|
|
//! Type of the parameter if the parameter is not a sampler.
|
|
ParameterType type;
|
|
//! Type of the parameter if the parameter is a sampler.
|
|
SamplerType samplerType;
|
|
//! Type of the parameter if the parameter is a subpass.
|
|
SubpassType subpassType;
|
|
};
|
|
//! Size of the parameter when the parameter is an array.
|
|
uint32_t count;
|
|
//! Requested precision of the parameter.
|
|
Precision precision;
|
|
};
|
|
|
|
class Builder : public BuilderBase<BuilderDetails> {
|
|
friend struct BuilderDetails;
|
|
public:
|
|
Builder() noexcept;
|
|
Builder(Builder const& rhs) noexcept;
|
|
Builder(Builder&& rhs) noexcept;
|
|
~Builder() noexcept;
|
|
Builder& operator=(Builder const& rhs) noexcept;
|
|
Builder& operator=(Builder&& rhs) noexcept;
|
|
|
|
/**
|
|
* Specifies the material data. The material data is a binary blob produced by
|
|
* libfilamat or by matc.
|
|
*
|
|
* @param payload Pointer to the material data, must stay valid until build() is called.
|
|
* @param size Size of the material data pointed to by "payload" in bytes.
|
|
*/
|
|
Builder& package(const void* UTILS_NONNULL payload, size_t size);
|
|
|
|
template<typename T>
|
|
using is_supported_constant_parameter_t = typename std::enable_if<
|
|
std::is_same<int32_t, T>::value ||
|
|
std::is_same<float, T>::value ||
|
|
std::is_same<bool, T>::value>::type;
|
|
|
|
/**
|
|
* Specialize a constant parameter specified in the material definition with a concrete
|
|
* value for this material. Once build() is called, this constant cannot be changed.
|
|
* Will throw an exception if the name does not match a constant specified in the
|
|
* material definition or if the type provided does not match.
|
|
*
|
|
* @tparam T The type of constant parameter, either int32_t, float, or bool.
|
|
* @param name The name of the constant parameter specified in the material definition, such
|
|
* as "myConstant".
|
|
* @param nameLength Length in `char` of the name parameter.
|
|
* @param value The value to use for the constant parameter, must match the type specified
|
|
* in the material definition.
|
|
*/
|
|
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
|
Builder& constant(const char* UTILS_NONNULL name, size_t nameLength, T value);
|
|
|
|
/** inline helper to provide the constant name as a null-terminated C string */
|
|
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
|
inline Builder& constant(const char* UTILS_NONNULL name, T value) {
|
|
return constant(name, strlen(name), value);
|
|
}
|
|
|
|
/**
|
|
* Creates the Material object and returns a pointer to it.
|
|
*
|
|
* @param engine Reference to the filament::Engine to associate this Material with.
|
|
*
|
|
* @return pointer to the newly created object or nullptr if exceptions are disabled and
|
|
* an error occurred.
|
|
*
|
|
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
|
|
* memory or other resources.
|
|
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
|
|
*/
|
|
Material* UTILS_NULLABLE build(Engine& engine);
|
|
private:
|
|
friend class FMaterial;
|
|
};
|
|
|
|
using CompilerPriorityQueue = backend:: CompilerPriorityQueue;
|
|
|
|
/**
|
|
* Asynchronously ensures that a subset of this Material's variants are compiled. After issuing
|
|
* several Material::compile() calls in a row, it is recommended to call Engine::flush()
|
|
* such that the backend can start the compilation work as soon as possible.
|
|
* The provided callback is guaranteed to be called on the main thread after all specified
|
|
* variants of the material are compiled. This can take hundreds of milliseconds.
|
|
*
|
|
* If all the material's variants are already compiled, the callback will be scheduled as
|
|
* soon as possible, but this might take a few dozen millisecond, corresponding to how
|
|
* many previous frames are enqueued in the backend. This also varies by backend. Therefore,
|
|
* it is recommended to only call this method once per material shortly after creation.
|
|
*
|
|
* If the same variant is scheduled for compilation multiple times, the first scheduling
|
|
* takes precedence; later scheduling are ignored.
|
|
*
|
|
* caveat: A consequence is that if a variant is scheduled on the low priority queue and later
|
|
* scheduled again on the high priority queue, the later scheduling is ignored.
|
|
* Therefore, the second callback could be called before the variant is compiled.
|
|
* However, the first callback, if specified, will trigger as expected.
|
|
*
|
|
* The callback is guaranteed to be called. If the engine is destroyed while some material
|
|
* variants are still compiling or in the queue, these will be discarded and the corresponding
|
|
* callback will be called. In that case however the Material pointer passed to the callback
|
|
* is guaranteed to be invalid (either because it's been destroyed by the user already, or,
|
|
* because it's been cleaned-up by the Engine).
|
|
*
|
|
* UserVariantFilterMask::ALL should be used with caution. Only variants that an application
|
|
* needs should be included in the variants argument. For example, the STE variant is only used
|
|
* for stereoscopic rendering. If an application is not planning to render in stereo, this bit
|
|
* should be turned off to avoid unnecessary material compilations.
|
|
*
|
|
* @param priority Which priority queue to use, LOW or HIGH.
|
|
* @param variants Variants to include to the compile command.
|
|
* @param handler Handler to dispatch the callback or nullptr for the default handler
|
|
* @param callback callback called on the main thread when the compilation is done on
|
|
* by backend.
|
|
*/
|
|
void compile(CompilerPriorityQueue priority,
|
|
UserVariantFilterMask variants,
|
|
backend::CallbackHandler* UTILS_NULLABLE handler = nullptr,
|
|
utils::Invocable<void(Material* UTILS_NONNULL)>&& callback = {}) noexcept;
|
|
|
|
inline void compile(CompilerPriorityQueue priority,
|
|
UserVariantFilterBit variants,
|
|
backend::CallbackHandler* UTILS_NULLABLE handler = nullptr,
|
|
utils::Invocable<void(Material* UTILS_NONNULL)>&& callback = {}) noexcept {
|
|
compile(priority, UserVariantFilterMask(variants), handler,
|
|
std::forward<utils::Invocable<void(Material* UTILS_NONNULL)>>(callback));
|
|
}
|
|
|
|
inline void compile(CompilerPriorityQueue priority,
|
|
backend::CallbackHandler* UTILS_NULLABLE handler = nullptr,
|
|
utils::Invocable<void(Material* UTILS_NONNULL)>&& callback = {}) noexcept {
|
|
compile(priority, UserVariantFilterBit::ALL, handler,
|
|
std::forward<utils::Invocable<void(Material* UTILS_NONNULL)>>(callback));
|
|
}
|
|
|
|
/**
|
|
* Creates a new instance of this material. Material instances should be freed using
|
|
* Engine::destroy(const MaterialInstance*).
|
|
*
|
|
* @param name Optional name to associate with the given material instance. If this is null,
|
|
* then the instance inherits the material's name.
|
|
*
|
|
* @return A pointer to the new instance.
|
|
*/
|
|
MaterialInstance* UTILS_NONNULL createInstance(const char* UTILS_NULLABLE name = nullptr) const noexcept;
|
|
|
|
//! Returns the name of this material as a null-terminated string.
|
|
const char* UTILS_NONNULL getName() const noexcept;
|
|
|
|
//! Returns the shading model of this material.
|
|
Shading getShading() const noexcept;
|
|
|
|
//! Returns the interpolation mode of this material. This affects how variables are interpolated.
|
|
Interpolation getInterpolation() const noexcept;
|
|
|
|
//! Returns the blending mode of this material.
|
|
BlendingMode getBlendingMode() const noexcept;
|
|
|
|
//! Returns the vertex domain of this material.
|
|
VertexDomain getVertexDomain() const noexcept;
|
|
|
|
//! Returns the material's supported variants
|
|
UserVariantFilterMask getSupportedVariants() const noexcept;
|
|
|
|
//! Returns the material domain of this material.
|
|
//! The material domain determines how the material is used.
|
|
MaterialDomain getMaterialDomain() const noexcept;
|
|
|
|
//! Returns the default culling mode of this material.
|
|
CullingMode getCullingMode() const noexcept;
|
|
|
|
//! Returns the transparency mode of this material.
|
|
//! This value only makes sense when the blending mode is transparent or fade.
|
|
TransparencyMode getTransparencyMode() const noexcept;
|
|
|
|
//! Indicates whether instances of this material will, by default, write to the color buffer.
|
|
bool isColorWriteEnabled() const noexcept;
|
|
|
|
//! Indicates whether instances of this material will, by default, write to the depth buffer.
|
|
bool isDepthWriteEnabled() const noexcept;
|
|
|
|
//! Indicates whether instances of this material will, by default, use depth testing.
|
|
bool isDepthCullingEnabled() const noexcept;
|
|
|
|
//! Indicates whether this material is double-sided.
|
|
bool isDoubleSided() const noexcept;
|
|
|
|
//! Indicates whether this material uses alpha to coverage.
|
|
bool isAlphaToCoverageEnabled() const noexcept;
|
|
|
|
//! Returns the alpha mask threshold used when the blending mode is set to masked.
|
|
float getMaskThreshold() const noexcept;
|
|
|
|
//! Indicates whether this material uses the shadowing factor as a color multiplier.
|
|
//! This values only makes sense when the shading mode is unlit.
|
|
bool hasShadowMultiplier() const noexcept;
|
|
|
|
//! Indicates whether this material has specular anti-aliasing enabled
|
|
bool hasSpecularAntiAliasing() const noexcept;
|
|
|
|
//! Returns the screen-space variance for specular-antialiasing, this value is between 0 and 1.
|
|
float getSpecularAntiAliasingVariance() const noexcept;
|
|
|
|
//! Returns the clamping threshold for specular-antialiasing, this value is between 0 and 1.
|
|
float getSpecularAntiAliasingThreshold() const noexcept;
|
|
|
|
//! Returns the list of vertex attributes required by this material.
|
|
AttributeBitset getRequiredAttributes() const noexcept;
|
|
|
|
//! Returns the refraction mode used by this material.
|
|
RefractionMode getRefractionMode() const noexcept;
|
|
|
|
//! Return the refraction type used by this material.
|
|
RefractionType getRefractionType() const noexcept;
|
|
|
|
//! Returns the reflection mode used by this material.
|
|
ReflectionMode getReflectionMode() const noexcept;
|
|
|
|
//! Returns the minimum required feature level for this material.
|
|
backend::FeatureLevel getFeatureLevel() const noexcept;
|
|
|
|
/**
|
|
* Returns the number of parameters declared by this material.
|
|
* The returned value can be 0.
|
|
*/
|
|
size_t getParameterCount() const noexcept;
|
|
|
|
/**
|
|
* Gets information about this material's parameters.
|
|
*
|
|
* @param parameters A pointer to a list of ParameterInfo.
|
|
* The list must be at least "count" large
|
|
* @param count The number of parameters to retrieve. Must be >= 0 and can be > count.
|
|
*
|
|
* @return The number of parameters written to the parameters pointer.
|
|
*/
|
|
size_t getParameters(ParameterInfo* UTILS_NONNULL parameters, size_t count) const noexcept;
|
|
|
|
//! Indicates whether a parameter of the given name exists on this material.
|
|
bool hasParameter(const char* UTILS_NONNULL name) const noexcept;
|
|
|
|
//! Indicates whether an existing parameter is a sampler or not.
|
|
bool isSampler(const char* UTILS_NONNULL name) const noexcept;
|
|
|
|
/**
|
|
* Sets the value of the given parameter on this material's default instance.
|
|
*
|
|
* @param name The name of the material parameter
|
|
* @param value The value of the material parameter
|
|
*
|
|
* @see getDefaultInstance()
|
|
*/
|
|
template <typename T>
|
|
void setDefaultParameter(const char* UTILS_NONNULL name, T value) noexcept {
|
|
getDefaultInstance()->setParameter(name, value);
|
|
}
|
|
|
|
/**
|
|
* Sets a texture and sampler parameters on this material's default instance.
|
|
*
|
|
* @param name The name of the material texture parameter
|
|
* @param texture The texture to set as parameter
|
|
* @param sampler The sampler to be used with this texture
|
|
*
|
|
* @see getDefaultInstance()
|
|
*/
|
|
void setDefaultParameter(const char* UTILS_NONNULL name,
|
|
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) noexcept {
|
|
getDefaultInstance()->setParameter(name, texture, sampler);
|
|
}
|
|
|
|
/**
|
|
* Sets the color of the given parameter on this material's default instance.
|
|
*
|
|
* @param name The name of the material color parameter
|
|
* @param type Whether the color is specified in the linear or sRGB space
|
|
* @param color The color as a floating point red, green, blue tuple
|
|
*
|
|
* @see getDefaultInstance()
|
|
*/
|
|
void setDefaultParameter(const char* UTILS_NONNULL name, RgbType type, math::float3 color) noexcept {
|
|
getDefaultInstance()->setParameter(name, type, color);
|
|
}
|
|
|
|
/**
|
|
* Sets the color of the given parameter on this material's default instance.
|
|
*
|
|
* @param name The name of the material color parameter
|
|
* @param type Whether the color is specified in the linear or sRGB space
|
|
* @param color The color as a floating point red, green, blue, alpha tuple
|
|
*
|
|
* @see getDefaultInstance()
|
|
*/
|
|
void setDefaultParameter(const char* UTILS_NONNULL name, RgbaType type, math::float4 color) noexcept {
|
|
getDefaultInstance()->setParameter(name, type, color);
|
|
}
|
|
|
|
//! Returns this material's default instance.
|
|
MaterialInstance* UTILS_NONNULL getDefaultInstance() noexcept;
|
|
|
|
//! Returns this material's default instance.
|
|
MaterialInstance const* UTILS_NONNULL getDefaultInstance() const noexcept;
|
|
|
|
protected:
|
|
// prevent heap allocation
|
|
~Material() = default;
|
|
};
|
|
|
|
} // namespace filament
|
|
|
|
#endif // TNT_FILAMENT_MATERIAL_H
|