Files
Seele/src/Engine/Material/Material.cpp
T

127 lines
4.9 KiB
C++
Raw Normal View History

2023-01-21 18:43:21 +01:00
#include "Material.h"
2024-04-15 13:48:34 +02:00
#include "Graphics/Enums.h"
2023-01-29 18:58:59 +01:00
#include "Graphics/Graphics.h"
2023-11-15 17:42:57 +01:00
#include "Graphics/Shader.h"
2024-06-09 12:20:04 +02:00
#include "MaterialInstance.h"
#include "Serialization/Serialization.h"
#include "Window/WindowManager.h"
2024-01-16 19:24:49 +01:00
#include <fstream>
2023-01-21 18:43:21 +01:00
2024-06-09 12:20:04 +02:00
2023-01-21 18:43:21 +01:00
using namespace Seele;
2024-05-09 08:41:46 +02:00
std::atomic_uint64_t Material::materialIdCounter = 0;
Array<PMaterial> Material::materials;
2024-06-09 12:20:04 +02:00
Material::Material() {}
2023-01-21 18:43:21 +01:00
2024-06-09 12:20:04 +02:00
Material::Material(Gfx::PGraphics graphics, Gfx::ODescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding,
std::string materialName, Array<OShaderExpression> expressions, Array<std::string> parameter, MaterialNode brdf)
: graphics(graphics), uniformDataSize(uniformDataSize), uniformBinding(uniformBinding), instanceId(0), layout(std::move(layout)),
materialName(materialName), codeExpressions(std::move(expressions)), parameters(std::move(parameter)), brdf(std::move(brdf)),
materialId(materialIdCounter++) {
2024-05-09 08:41:46 +02:00
materials.add(this);
2023-01-21 18:43:21 +01:00
}
2024-06-09 12:20:04 +02:00
Material::~Material() {}
OMaterialInstance Material::instantiate() {
return new MaterialInstance(instanceId++, graphics, codeExpressions, parameters, uniformBinding, uniformDataSize);
2023-01-21 18:43:21 +01:00
}
2024-06-09 12:20:04 +02:00
void Material::save(ArchiveBuffer& buffer) const {
2023-11-01 13:38:49 +01:00
Serialization::save(buffer, uniformDataSize);
Serialization::save(buffer, uniformBinding);
Serialization::save(buffer, instanceId);
2023-04-09 16:39:53 +02:00
Serialization::save(buffer, materialName);
2023-07-13 21:01:20 +02:00
Serialization::save(buffer, codeExpressions);
2023-11-01 13:38:49 +01:00
Serialization::save(buffer, parameters);
2023-07-13 21:01:20 +02:00
Serialization::save(buffer, brdf);
2024-04-19 18:23:36 +02:00
Serialization::save(buffer, layout->getName());
2023-02-13 14:56:13 +01:00
const auto& bindings = layout->getBindings();
Serialization::save(buffer, bindings.size());
2024-06-09 12:20:04 +02:00
for (const auto& binding : bindings) {
2023-02-13 14:56:13 +01:00
Serialization::save(buffer, binding.binding);
Serialization::save(buffer, binding.descriptorType);
2024-04-15 13:48:34 +02:00
Serialization::save(buffer, binding.textureType);
Serialization::save(buffer, binding.descriptorCount);
Serialization::save(buffer, binding.bindingFlags);
2023-02-13 14:56:13 +01:00
Serialization::save(buffer, binding.shaderStages);
}
}
2024-06-09 12:20:04 +02:00
void Material::load(ArchiveBuffer& buffer) {
2023-02-13 14:56:13 +01:00
graphics = buffer.getGraphics();
2023-11-01 13:38:49 +01:00
Serialization::load(buffer, uniformDataSize);
Serialization::load(buffer, uniformBinding);
Serialization::load(buffer, instanceId);
2023-02-13 14:56:13 +01:00
Serialization::load(buffer, materialName);
2023-11-01 13:38:49 +01:00
Serialization::load(buffer, codeExpressions);
Serialization::load(buffer, parameters);
Serialization::load(buffer, brdf);
2024-04-19 18:23:36 +02:00
std::string descriptorName;
Serialization::load(buffer, descriptorName);
2023-02-13 14:56:13 +01:00
uint64 numBindings;
Serialization::load(buffer, numBindings);
2024-04-19 18:23:36 +02:00
layout = graphics->createDescriptorLayout(descriptorName);
2024-06-09 12:20:04 +02:00
for (uint64 i = 0; i < numBindings; ++i) {
2023-02-13 14:56:13 +01:00
uint32 binding;
Serialization::load(buffer, binding);
2024-04-15 13:48:34 +02:00
Gfx::SeDescriptorType descriptorType;
Serialization::load(buffer, descriptorType);
Gfx::SeImageViewType textureType;
Serialization::load(buffer, textureType);
2023-02-13 14:56:13 +01:00
uint32 descriptorCount;
Serialization::load(buffer, descriptorCount);
2024-04-15 13:48:34 +02:00
Gfx::SeDescriptorBindingFlags bindingFlags;
Serialization::load(buffer, bindingFlags);
2023-02-13 14:56:13 +01:00
Gfx::SeShaderStageFlags shaderStages;
Serialization::load(buffer, shaderStages);
2024-06-09 12:20:04 +02:00
layout->addDescriptorBinding(Gfx::DescriptorBinding{
.binding = binding,
.descriptorType = descriptorType,
.textureType = textureType,
.descriptorCount = descriptorCount,
.bindingFlags = bindingFlags,
.shaderStages = shaderStages,
});
2023-02-13 14:56:13 +01:00
}
layout->create();
2024-05-12 19:36:32 +02:00
materialId = materialIdCounter++;
2023-01-21 18:43:21 +01:00
}
2024-06-09 12:20:04 +02:00
void Material::compile() {
std::ofstream codeStream("./shaders/generated/" + materialName + ".slang");
2023-02-24 22:09:07 +01:00
codeStream << "import BRDF;\n";
codeStream << "import MaterialParameter;\n";
2024-04-26 19:32:38 +02:00
codeStream << "struct " << materialName << "{\n";
2024-06-09 12:20:04 +02:00
for (const auto& parameter : parameters) {
PShaderParameter handle =
PShaderExpression(*codeExpressions.find([&parameter](const OShaderExpression& exp) { return exp->key == parameter; }));
2023-11-05 10:36:01 +01:00
handle->generateDeclaration(codeStream);
2023-02-24 22:09:07 +01:00
}
codeStream << "\ttypedef " << brdf.profile << " BRDF;\n";
2023-11-11 13:56:12 +01:00
codeStream << "\t" << brdf.profile << " prepare(MaterialParameter input) {\n";
2023-02-24 22:09:07 +01:00
codeStream << "\t\t" << brdf.profile << " result;\n";
2023-11-05 10:36:01 +01:00
Map<std::string, std::string> varState;
2023-11-11 22:39:17 +01:00
// initialize variable state
2024-06-09 12:20:04 +02:00
for (const auto& expr : codeExpressions) {
2023-11-17 22:31:26 +01:00
codeStream << "\t\t" << expr->evaluate(varState);
2023-02-24 22:09:07 +01:00
}
2024-06-09 12:20:04 +02:00
for (const auto& [name, exp] : brdf.variables) {
2023-11-17 22:31:26 +01:00
codeStream << "\t\tresult." << name << " = " << varState[exp] << ";" << std::endl;
2023-02-24 22:09:07 +01:00
}
codeStream << "\t\treturn result;\n";
codeStream << "\t}\n";
codeStream << "};\n";
2024-04-26 19:32:38 +02:00
codeStream << "layout(set=4)";
codeStream << "ParameterBlock<" << materialName << "> pMaterial;";
2023-11-05 10:36:01 +01:00
graphics->getShaderCompiler()->registerMaterial(this);
2023-02-24 22:09:07 +01:00
}