1#include "Foundation/Logging/Logger.h"
8#include "MaterialManager.h"
10#include "MaterialBuilder.h"
21 for (
auto & buffer : contantBuffers.
buffers) {
22 if (buffer.name == name) {
23 assert(
false &&
"Buffer with the given name already exists.");
28 bool checkVariableKey(
const char* method,
VariableKey key,
size_t numKeys)
31 LOG_ERROR(logger,
"%s: Invalid VariableKey: %d", method, key);
40Cogs::Core::ConstantBufferKey Cogs::Core::ConstantBuffers::addBuffer(
const PropertyName & name,
bool isPerInstance)
42 checkNameNotInBuffer(*
this, name);
46 const ConstantBufferKey key =
static_cast<ConstantBufferKey
>(
buffers.size() - 1);
51 buffer.isPerInstance = isPerInstance;
60 float * values =
nullptr;
63 case MaterialDataType::Float:
64 values = (
float *)data;
67 case MaterialDataType::Float2:
68 values = (
float *)data;
71 case MaterialDataType::Float3:
72 values = (
float *)data;
75 case MaterialDataType::Float4:
76 values = (
float *)data;
83 if (!values || !length)
return;
86 for (
int i = 0; i < std::min(3, length); i++) {
87 values[i] = std::pow(std::abs(values[i]), 2.2f);
93 for (
int i = 0; i < length; i++) {
94 l += values[i] * values[i];
96 l = l < std::numeric_limits<float>::epsilon() ? 0.f : 1.f / l;
97 for (
int i = 0; i < length; i++) {
98 values[i] = l * values[i];
104 for (
int i = 0; i < length; i++) {
105 values[i] = std::max(0.f, values[i]);
108 l = l < std::numeric_limits<float>::epsilon() ? 0.f : 1.f / l;
109 for (
int i = 0; i < length; i++) {
110 values[i] = l * values[i];
118 if (!checkVariableKey(
"setTextureProperty", key, textureProperties.size())) {
123 if (value != textureVariable.texture.
handle) {
124 textureVariable.texture.
handle = value;
125 textureVariable.
dirty =
true;
132 const VariableKey variableKey = constantBuffers.getPropertyKey(key);
134 if (variableKey == NoProperty) {
135 return MaterialDataType::Unknown;
138 const auto& materialProperty = constantBuffers.variables[variableKey];
139 return materialProperty.type;
144 setTextureAddressMode(key, mode, mode, mode);
149 if (!checkVariableKey(
"setTextureAddressMode", key, textureProperties.size())) {
154 if (smode != textureVariable.texture.
sMode || tmode != textureVariable.texture.tMode || umode != textureVariable.texture.uMode) {
155 textureVariable.texture.
sMode = smode;
156 textureVariable.texture.tMode = tmode;
157 textureVariable.texture.uMode = umode;
158 textureVariable.
dirty =
true;
166 if (!checkVariableKey(
"setTextureFilterMode", key, textureProperties.size())) {
171 if (textureVariable.texture.
filterMode != filterMode) {
172 textureVariable.texture.
filterMode = filterMode;
173 textureVariable.
dirty =
true;
178size_t Cogs::Core::Material::getVariantIndex(
const StringView& key)
const
186 return NoVariantIndex;
189void Cogs::Core::Material::setVariant(
size_t index,
int value)
191 if (definition.variants.size() <= index) {
192 LOG_ERROR(logger,
"Variant index out of range.");
195 assert(definition.variants[index].index == index &&
"Variant selector index invalid.");
197 if (!variantDefinition.isShared) {
198 LOG_ERROR_ONCE(logger,
"Trying to set a non-shared variant via the material.");
202 if (variantDefinition.type != ShaderVariantType::Int) {
203 LOG_ERROR(logger,
"Variant type is not Int");
206 if (variantDefinition.defaultValue != value) {
207 variantDefinition.defaultValue = value;
213void Cogs::Core::Material::setVariant(
const StringView& key,
int value)
215 size_t ix = getVariantIndex(key);
216 if (ix == Material::NoVariantIndex) {
217 LOG_ERROR(logger,
"Unrecognized variant name '%.*s'", StringViewFormat(key));
220 setVariant(ix, value);
230 for (
auto & e : effects) {
231 if (e.code == code)
return e.handle;
243void Cogs::Core::Material::setProperty(
const StringView& name,
const void* data,
const size_t sizeInBytes)
245 VariableKey key = constantBuffers.getPropertyKey(name);
249 uint8_t valueBuffer[
sizeof(glm::mat4)];
250 if (sizeInBytes <=
sizeof(glm::mat4)) {
251 std::memcpy(valueBuffer, data, sizeInBytes);
253 enforcePropertyFlags(materialProperty, materialProperty.flags, valueBuffer);
261 if (sizeInBytes != 1 && sizeInBytes != 4) {
265 else if (sizeInBytes != materialProperty.
descriptor.size) {
271 LOG_ERROR(logger,
"setProperty: Invalid size given Property=%s, Expected=%zu, Given=%zu",
272 materialProperty.
name.data(), materialProperty.
descriptor.size, sizeInBytes);
275 constantBuffers.buffers[materialProperty.
buffer].setValue(materialProperty.
descriptor,
static_cast<const uint8_t*
>(data));
Material manager handling loading and processing of Material resources.
EffectHandle loadMaterialVariant(Material *material, const MaterialInstance *materialInstance, const MeshStreamsLayout *streamsLayout, const EnginePermutation *permutation, const RenderPassOptions &passOptions, const ClipShapeType clipShape)
Log implementation class.
Provides a weakly referenced view over the contents of a string.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
ClipShapeType
Specifices what kind of shape a clip shape has.
MaterialDataType
Defines available data types for material properties.
@ Normalized
Value is a direction vector is subject to normalization.
@ PartitionOfUnity
A set of non-negative weights that sum to one.
@ sRGB
Value is a color and is subject to gamma correction.
std::string PropertyName
Typedef for property names.
uint16_t VariableKey
Used to lookup material properties.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
void setChanged(Cogs::Core::Context *context, Cogs::ComponentModel::Component *component, Reflection::FieldId fieldId)
Must be Called after changing a Component field. Mark field changed. Request engine update.
std::vector< MaterialPropertyBuffer > buffers
Constant buffer instances.
uint16_t buffersGeneration
If the constant buffer bindings need updates.
Material instances represent a specialized Material combined with state for all its buffers and prope...
Defines a single material property.
bool dirty
If the property is dirty.
MaterialPropertyDescriptor descriptor
Property descriptor.
ConstantBufferKey buffer
Key to the buffer the property value is stored in.
PropertyName name
Name of the property, used to reference named uniforms of constant buffer members in shaders.
MaterialDataType type
Type of data held by property.
EffectHandle getEffect(size_t code, const MaterialInstance *materialInstance, const MeshStreamsLayout *streamsLayout, const EnginePermutation *enginePermutation, const RenderPassOptions &passOptions, const ClipShapeType clipShape)
MaterialDataType getPropertyDataType(const StringView &key)
Gets data type for the given property. Returns MaterialDataType::Unknown if not found.
void setTextureFilterMode(const VariableKey key, SamplerState::FilterMode filterMode)
Set filtermode used for the texture property.
void setTextureProperty(const VariableKey key, TextureHandle value)
Set the texture property with the given key to the texture resource held by value.
void setTextureAddressMode(const VariableKey key, SamplerState::AddressMode mode)
Set the address mode used for the texture property with the given key to mode.
Property value for texture samplers.
SamplerState::FilterMode filterMode
Filter mode to use when rendering with this texture.
SamplerState::AddressMode sMode
Address mode to use when rendering with this texture.
TextureHandle handle
Handle to a texture resource, or TextureHandle::NoHandle if texture should be disabled.
AddressMode
Addressing modes to use when sampling textures.
FilterMode
Filter modes to specify how texture data is treated when sampled.