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

433 lines
10 KiB
C++

#include "ShaderExpression.h"
#include "Graphics/Resources.h"
#include "Asset/TextureAsset.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/Graphics.h"
#include "Graphics/Descriptor.h"
#include <fstream>
#include <fmt/core.h>
using namespace Seele;
void ExpressionInput::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, source);
Serialization::save(buffer, type);
}
void ExpressionInput::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, source);
Serialization::load(buffer, type);
}
void ExpressionOutput::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, name);
Serialization::save(buffer, type);
}
void ExpressionOutput::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, name);
Serialization::load(buffer, type);
}
ShaderExpression::ShaderExpression()
{
}
ShaderExpression::ShaderExpression(std::string key)
: key(key)
{
}
ShaderExpression::~ShaderExpression()
{
}
void ShaderExpression::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, inputs);
Serialization::save(buffer, output);
Serialization::save(buffer, key);
}
void ShaderExpression::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, inputs);
Serialization::load(buffer, output);
Serialization::load(buffer, key);
}
ShaderParameter::ShaderParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderExpression(name)
, byteOffset(byteOffset)
, binding(binding)
{
}
ShaderParameter::~ShaderParameter()
{
}
std::string ShaderParameter::evaluate(Map<std::string, std::string>& varState) const
{
varState[key] = key;
return "";
}
void ShaderParameter::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
Serialization::save(buffer, byteOffset);
Serialization::save(buffer, binding);
}
void ShaderParameter::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
Serialization::load(buffer, byteOffset);
Serialization::load(buffer, binding);
}
FloatParameter::FloatParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data(0)
{
output.name = name;
output.type = ExpressionType::FLOAT;
}
FloatParameter::~FloatParameter()
{
}
void FloatParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void FloatParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(float));
}
void FloatParameter::generateDeclaration(std::ofstream& stream) const
{
stream << "\tlayout(offset = " << byteOffset << ") float " << key << ";\n";
}
VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data()
{
output.name = name;
output.type = ExpressionType::FLOAT3;
}
VectorParameter::~VectorParameter()
{
}
void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(Vector));
}
void VectorParameter::generateDeclaration(std::ofstream& stream) const
{
stream << "\tlayout(offset = " << byteOffset << ") float3 " << key << ";\n";
}
void VectorParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void VectorParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
output.name = name;
output.type = ExpressionType::TEXTURE;
}
TextureParameter::~TextureParameter()
{
}
void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*)
{
descriptorSet->updateTexture(binding, data->getTexture());
}
void TextureParameter::generateDeclaration(std::ofstream& stream) const
{
stream << "\tTexture2D " << key << ";\n";
}
void TextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void TextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
}
SamplerParameter::SamplerParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
output.name = name;
output.type = ExpressionType::SAMPLER;
}
SamplerParameter::~SamplerParameter()
{
}
void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*)
{
descriptorSet->updateSampler(binding, data);
}
void SamplerParameter::generateDeclaration(std::ofstream& stream) const
{
stream << "\tSamplerState " << key << ";\n";
}
void SamplerParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
}
void SamplerParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
data = buffer.getGraphics()->createSampler(SamplerCreateInfo{});
}
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
output.name = name;
output.type = ExpressionType::TEXTURE;
}
CombinedTextureParameter::~CombinedTextureParameter()
{
}
void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*)
{
descriptorSet->updateTexture(binding, data->getTexture(), sampler);
}
void CombinedTextureParameter::generateDeclaration(std::ofstream& stream) const
{
stream << "\tTexture2D " << key << ";\n";
}
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void CombinedTextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
sampler = buffer.getGraphics()->createSampler({});
}
ConstantExpression::ConstantExpression()
{
}
ConstantExpression::ConstantExpression(std::string expr, ExpressionType type)
: expr(expr)
{
output.name = "cexpr";
output.type = type;
}
ConstantExpression::~ConstantExpression()
{
}
std::string ConstantExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("const_exp_{}", key);
varState[key] = varName;
return fmt::format("let {} = {};\n", varName, expr);
}
void ConstantExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
Serialization::save(buffer, expr);
}
void ConstantExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
Serialization::load(buffer, expr);
}
AddExpression::AddExpression()
{
}
AddExpression::~AddExpression()
{
}
std::string AddExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("exp_{}", key);
varState[key] = varName;
return fmt::format("let {} = {} + {};\n", varName, varState[inputs.at("lhs").source], varState[inputs.at("rhs").source]);
}
void AddExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
}
void AddExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
}
std::string SubExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("exp_{}", key);
varState[key] = varName;
return fmt::format("let {} = {} - {};\n", varName, varState[inputs.at("lhs").source], varState[inputs.at("rhs").source]);
}
void SubExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
}
void SubExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
}
std::string MulExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("exp_{}", key);
varState[key] = varName;
return fmt::format("let {} = {} * {};\n", varName, varState[inputs.at("lhs").source], varState[inputs.at("rhs").source]);
}
void MulExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
}
void MulExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
}
std::string SwizzleExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("exp_{}", key);
std::string swizzle = "";
for(uint32 i = 0; i < 4; ++i)
{
if(comp[i] == -1)
{
break;
}
switch (comp[i])
{
case 0:
swizzle += "x";
break;
case 1:
swizzle += "y";
break;
case 2:
swizzle += "z";
break;
case 3:
swizzle += "w";
break;
default:
throw std::logic_error("invalid component");
}
}
varState[key] = varName;
return fmt::format("let {} = {}.{};\n", varName, varState[inputs.at("target").source], swizzle);
}
void SwizzleExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
Serialization::save(buffer, comp);
}
void SwizzleExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
Serialization::load(buffer, comp);
}
std::string SampleExpression::evaluate(Map<std::string, std::string>& varState) const
{
std::string varName = fmt::format("exp_{}", key);
varState[key] = varName;
return fmt::format("let {} = {}.Sample({}, {});\n", varName, varState[inputs.at("texture").source], varState[inputs.at("sampler").source], varState[inputs.at("coords").source]);
}
void SampleExpression::save(ArchiveBuffer& buffer) const
{
ShaderExpression::save(buffer);
}
void SampleExpression::load(ArchiveBuffer& buffer)
{
ShaderExpression::load(buffer);
}
void MaterialNode::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, profile);
Serialization::save(buffer, variables);
}
void MaterialNode::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, profile);
Serialization::load(buffer, variables);
}