Cogs.Core
MaterialBuilder.cpp
1#include "Rendering/IGraphicsDevice.h"
2#include "Rendering/ICapabilities.h"
3
4#include "Foundation/Logging/Logger.h"
5
6#include "MaterialBuilder.h"
7
8#include "EffectManager.h"
9
10#include "Context.h"
11
12#include "TextureManager.h"
13
14#include "ShaderBuilder.h"
15#include "Renderer/IRenderer.h"
16
17namespace {
18 Cogs::Logging::Log logger = Cogs::Logging::getLogger("MaterialBuilder");
19
20}
21
22bool Cogs::Core::applyConstantBuffers(class Context * context, const MaterialProperties & materialProperties, ConstantBuffers & constantBuffers)
23{
24 for (auto & buffer : materialProperties.buffers) {
25 auto bufferKey = constantBuffers.addBuffer(buffer.name, buffer.isPerInstance);
26
27 for (auto & parsedValue : buffer.values) {
28 auto & propertyName = parsedValue.name;
29
30 auto flags = parsedValue.flags;
31
32 switch (parsedValue.type) {
33 case MaterialDataType::Float:
34 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.floatValue, MaterialDataType::Float, buffer.isPerInstance);
35 break;
36 case MaterialDataType::Float2:
37 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float2Value, MaterialDataType::Float2, buffer.isPerInstance);
38 break;
39 case MaterialDataType::Float3:
40 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float3Value, MaterialDataType::Float3, buffer.isPerInstance);
41 break;
42 case MaterialDataType::Float4:
43 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float4Value, MaterialDataType::Float4, buffer.isPerInstance);
44 break;
45 case MaterialDataType::Float4x4:
46 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float4x4Value, MaterialDataType::Float4x4, buffer.isPerInstance);
47 break;
48 case MaterialDataType::Float4Array:
49 if (parsedValue.dimension != static_cast<size_t>(-1)) {
50 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float4Value, MaterialDataType::Float4Array, buffer.isPerInstance, parsedValue.dimension);
51 }
52 else {
53 LOG_WARNING(logger, "Constant buffer float4[]-member must have a known size");
54 return false;
55 }
56 break;
57 case MaterialDataType::Float4x4Array:
58 if (parsedValue.dimension != static_cast<size_t>(-1)) {
59 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.float4x4Value, MaterialDataType::Float4x4Array, buffer.isPerInstance, parsedValue.dimension);
60 }
61 else {
62 LOG_WARNING(logger, "Constant buffer float4x4[]-member must have a known size");
63 return false;
64 }
65 break;
66 case MaterialDataType::Bool:
67 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.boolValue, MaterialDataType::Bool, buffer.isPerInstance);
68 break;
69 case MaterialDataType::Int:
70 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.intValue, MaterialDataType::Int, buffer.isPerInstance);
71 break;
72 case MaterialDataType::Int2:
73 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.int2Value, MaterialDataType::Int2, buffer.isPerInstance);
74 break;
75 case MaterialDataType::Int3:
76 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.int3Value, MaterialDataType::Int3, buffer.isPerInstance);
77 break;
78 case MaterialDataType::Int4:
79 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.int4Value, MaterialDataType::Int4, buffer.isPerInstance);
80 break;
81 case MaterialDataType::UInt:
82 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.uintValue, MaterialDataType::UInt, buffer.isPerInstance);
83 break;
84 case MaterialDataType::UInt2:
85 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.uint2Value, MaterialDataType::UInt2, buffer.isPerInstance);
86 break;
87 case MaterialDataType::UInt3:
88 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.uint3Value, MaterialDataType::UInt3, buffer.isPerInstance);
89 break;
90 case MaterialDataType::UInt4:
91 constantBuffers.addVariable(bufferKey, flags, propertyName, parsedValue.uint4Value, MaterialDataType::UInt4, buffer.isPerInstance);
92 break;
93 default:
94 LOG_WARNING(logger, "Unsupported constant buffer type %s", DataTypeNames[size_t(parsedValue.type)]);
95 return false;
96 }
97 }
98
99 constantBuffers.finalizeBuffer(context, bufferKey);
100 }
101 return true;
102}
103
104bool Cogs::Core::applyMaterialProperties(Context * context, const MaterialProperties & materialProperties, Material & material)
105{
106 if (!applyConstantBuffers(context, materialProperties, material.constantBuffers)) return false;
107
108 if (!materialProperties.buffers.size()) {
109 // If no buffers were added, bump buffers generation to still invalidate bindings to built-in
110 // buffers like scene and environment data.
111 material.constantBuffers.buffersGeneration++;
112 }
113
114 TextureHandle defaultTexture[] = {
115 context->textureManager->white,
116 context->textureManager->whiteCube,
117 TextureHandle::NoHandle,
118 TextureHandle::NoHandle,
119 };
120
121 for (const MaterialTextureDefinition& texture : materialProperties.textures) {
122 assert((size_t)texture.dimensions < sizeof(defaultTexture)/sizeof(defaultTexture[0]));
123 if(texture.isArray){
124 for(uint32_t i=0; i<texture.arraySize; i++){
125 VariableKey key = material.addTextureProperty(texture.name+'['+std::to_string(i)+']',
126 defaultTexture[static_cast<size_t>(texture.dimensions)],
127 texture.dimensions,
128 SamplerState::AddressMode::Wrap,
129 SamplerState::FilterMode::MinMagMipLinear,
130 texture.isPerInstance, texture.isArray, texture.arraySize);
131
132 if (texture.isSrgb) {
133 material.textureProperties[key].flags |= MaterialPropertyFlags::sRGB;
134 }
135 }
136 }
137 else{
138 VariableKey key = material.addTextureProperty(texture.name,
139 defaultTexture[static_cast<size_t>(texture.dimensions)],
140 texture.dimensions,
141 SamplerState::AddressMode::Wrap,
142 SamplerState::FilterMode::MinMagMipLinear,
143 texture.isPerInstance,
144 texture.isArray,
145 texture.arraySize);
146 if (texture.isSrgb) {
147 material.textureProperties[key].flags |= MaterialPropertyFlags::sRGB;
148 }
149 }
150 }
151 return true;
152}
153
154bool Cogs::Core::applyMaterialDefinition(class Context * context, const MaterialDefinition & materialDefinition, Material & material)
155{
156 material.setName(materialDefinition.name);
157
158 material.enginePermutationMask = materialDefinition.enginePermutationMask;
159
160 for (auto & opt : materialDefinition.options) {
161 applyMaterialOption(material.options, opt.first, opt.second);
162 }
163
164 if (!applyMaterialProperties(context, materialDefinition.properties, material)) return false;
165
166 return true;
167}
Log implementation class.
Definition: LogManager.h:139
uint16_t VariableKey
Used to lookup material properties.
Definition: Resources.h:46
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180