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

138 lines
4.3 KiB
C++
Raw Normal View History

2023-01-21 18:43:21 +01:00
#include "Material.h"
#include "Window/WindowManager.h"
#include "MaterialInstance.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-01-16 19:24:49 +01:00
#include <fstream>
2023-01-21 18:43:21 +01:00
using namespace Seele;
2023-11-01 13:38:49 +01:00
Material::Material()
{
}
2023-01-21 18:43:21 +01:00
2023-11-05 10:36:01 +01:00
Material::Material(Gfx::PGraphics graphics,
2023-11-01 23:12:30 +01:00
Gfx::ODescriptorLayout layout,
2023-02-24 22:09:07 +01:00
uint32 uniformDataSize,
uint32 uniformBinding,
std::string materialName,
2023-11-11 22:39:17 +01:00
Array<OShaderExpression> expressions,
2023-11-05 10:36:01 +01:00
Array<std::string> parameter,
2023-02-24 22:09:07 +01:00
MaterialNode brdf)
2023-10-24 15:01:09 +02:00
: graphics(graphics)
, uniformDataSize(uniformDataSize)
, uniformBinding(uniformBinding)
2023-11-05 10:36:01 +01:00
, instanceId(0)
2023-11-01 23:12:30 +01:00
, layout(std::move(layout))
2023-01-21 18:43:21 +01:00
, materialName(materialName)
2023-11-01 23:12:30 +01:00
, codeExpressions(std::move(expressions))
2023-11-05 10:36:01 +01:00
, parameters(std::move(parameter))
, brdf(std::move(brdf))
2023-01-21 18:43:21 +01:00
{
}
Material::~Material()
{
}
2023-11-05 10:36:01 +01:00
OMaterialInstance Material::instantiate()
2023-01-21 18:43:21 +01:00
{
2023-11-05 10:36:01 +01:00
return new MaterialInstance(
instanceId++,
graphics,
codeExpressions,
parameters,
uniformBinding,
uniformDataSize);
2023-01-21 18:43:21 +01:00
}
2023-02-13 14:56:13 +01:00
void Material::save(ArchiveBuffer& buffer) const
2023-01-21 18:43:21 +01:00
{
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);
2023-11-01 13:38:49 +01:00
Serialization::save(buffer, layout->getSetIndex());
2023-02-13 14:56:13 +01:00
const auto& bindings = layout->getBindings();
Serialization::save(buffer, bindings.size());
for (const auto& binding : bindings)
{
Serialization::save(buffer, binding.binding);
Serialization::save(buffer, binding.bindingFlags);
Serialization::save(buffer, binding.descriptorCount);
Serialization::save(buffer, binding.descriptorType);
Serialization::save(buffer, binding.shaderStages);
}
}
void Material::load(ArchiveBuffer& buffer)
{
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);
2023-02-13 14:56:13 +01:00
uint32 setIndex;
Serialization::load(buffer, setIndex);
uint64 numBindings;
Serialization::load(buffer, numBindings);
layout = graphics->createDescriptorLayout();
for (uint64 i = 0; i < numBindings; ++i)
{
uint32 binding;
Serialization::load(buffer, binding);
Gfx::SeDescriptorBindingFlags bindingFlags;
Serialization::load(buffer, bindingFlags);
uint32 descriptorCount;
Serialization::load(buffer, descriptorCount);
Gfx::SeDescriptorType descriptorType;
Serialization::load(buffer, descriptorType);
Gfx::SeShaderStageFlags shaderStages;
Serialization::load(buffer, shaderStages);
layout->addDescriptorBinding(binding, descriptorType, descriptorCount, bindingFlags, shaderStages);
}
layout->create();
2023-01-21 18:43:21 +01:00
}
2023-02-24 22:09:07 +01:00
void Material::compile()
{
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
codeStream << "import Material;\n";
codeStream << "import BRDF;\n";
codeStream << "import MaterialParameter;\n";
codeStream << "struct " << materialName << " : IMaterial {\n";
for(const auto& parameter : parameters)
{
2023-11-11 22:39:17 +01:00
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
for(const auto& expr :codeExpressions)
2023-02-24 22:09:07 +01:00
{
2023-11-17 22:31:26 +01:00
codeStream << "\t\t" << expr->evaluate(varState);
2023-02-24 22:09:07 +01: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";
2023-11-05 10:36:01 +01:00
graphics->getShaderCompiler()->registerMaterial(this);
2023-02-24 22:09:07 +01:00
}