121 lines
4.0 KiB
C++
121 lines
4.0 KiB
C++
#include "RuntimeShaderParams.h"
|
|
|
|
#include "Std140Buffer.h"
|
|
|
|
#include <chrono>
|
|
|
|
namespace
|
|
{
|
|
ShaderParameterValue DefaultValueForDefinition(const ShaderParameterDefinition& definition)
|
|
{
|
|
ShaderParameterValue value;
|
|
switch (definition.type)
|
|
{
|
|
case ShaderParameterType::Float:
|
|
value.numberValues = definition.defaultNumbers.empty() ? std::vector<double>{ 0.0 } : definition.defaultNumbers;
|
|
break;
|
|
case ShaderParameterType::Vec2:
|
|
value.numberValues = definition.defaultNumbers.size() == 2 ? definition.defaultNumbers : std::vector<double>{ 0.0, 0.0 };
|
|
break;
|
|
case ShaderParameterType::Color:
|
|
value.numberValues = definition.defaultNumbers.size() == 4 ? definition.defaultNumbers : std::vector<double>{ 1.0, 1.0, 1.0, 1.0 };
|
|
break;
|
|
case ShaderParameterType::Boolean:
|
|
value.booleanValue = definition.defaultBoolean;
|
|
break;
|
|
case ShaderParameterType::Enum:
|
|
value.enumValue = definition.defaultEnumValue;
|
|
break;
|
|
case ShaderParameterType::Text:
|
|
value.textValue = definition.defaultTextValue;
|
|
break;
|
|
case ShaderParameterType::Trigger:
|
|
value.numberValues = { 0.0, -1000000.0 };
|
|
break;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
int EnumIndexForDefault(const ShaderParameterDefinition& definition, const ShaderParameterValue& value)
|
|
{
|
|
for (std::size_t optionIndex = 0; optionIndex < definition.enumOptions.size(); ++optionIndex)
|
|
{
|
|
if (definition.enumOptions[optionIndex].value == value.enumValue)
|
|
return static_cast<int>(optionIndex);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
double UtcSecondsOfDay()
|
|
{
|
|
const auto now = std::chrono::system_clock::now();
|
|
const auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
|
const long long secondsPerDay = 24 * 60 * 60;
|
|
long long daySeconds = seconds % secondsPerDay;
|
|
if (daySeconds < 0)
|
|
daySeconds += secondsPerDay;
|
|
return static_cast<double>(daySeconds);
|
|
}
|
|
}
|
|
|
|
std::vector<unsigned char> BuildRuntimeShaderGlobalParamsStd140(
|
|
const RuntimeShaderArtifact& artifact,
|
|
uint64_t frameIndex,
|
|
unsigned width,
|
|
unsigned height)
|
|
{
|
|
std::vector<unsigned char> buffer;
|
|
buffer.reserve(512);
|
|
|
|
AppendStd140Float(buffer, static_cast<float>(frameIndex) / 60.0f);
|
|
AppendStd140Vec2(buffer, static_cast<float>(width), static_cast<float>(height));
|
|
AppendStd140Vec2(buffer, static_cast<float>(width), static_cast<float>(height));
|
|
AppendStd140Float(buffer, static_cast<float>(UtcSecondsOfDay()));
|
|
AppendStd140Float(buffer, 0.0f);
|
|
AppendStd140Float(buffer, 0.37f);
|
|
AppendStd140Float(buffer, static_cast<float>(frameIndex));
|
|
AppendStd140Float(buffer, 1.0f);
|
|
AppendStd140Float(buffer, 0.0f);
|
|
AppendStd140Int(buffer, 0);
|
|
AppendStd140Int(buffer, 0);
|
|
AppendStd140Int(buffer, 0);
|
|
|
|
for (const ShaderParameterDefinition& definition : artifact.parameterDefinitions)
|
|
{
|
|
const ShaderParameterValue value = DefaultValueForDefinition(definition);
|
|
switch (definition.type)
|
|
{
|
|
case ShaderParameterType::Float:
|
|
AppendStd140Float(buffer, value.numberValues.empty() ? 0.0f : static_cast<float>(value.numberValues[0]));
|
|
break;
|
|
case ShaderParameterType::Vec2:
|
|
AppendStd140Vec2(buffer,
|
|
value.numberValues.size() > 0 ? static_cast<float>(value.numberValues[0]) : 0.0f,
|
|
value.numberValues.size() > 1 ? static_cast<float>(value.numberValues[1]) : 0.0f);
|
|
break;
|
|
case ShaderParameterType::Color:
|
|
AppendStd140Vec4(buffer,
|
|
value.numberValues.size() > 0 ? static_cast<float>(value.numberValues[0]) : 1.0f,
|
|
value.numberValues.size() > 1 ? static_cast<float>(value.numberValues[1]) : 1.0f,
|
|
value.numberValues.size() > 2 ? static_cast<float>(value.numberValues[2]) : 1.0f,
|
|
value.numberValues.size() > 3 ? static_cast<float>(value.numberValues[3]) : 1.0f);
|
|
break;
|
|
case ShaderParameterType::Boolean:
|
|
AppendStd140Int(buffer, value.booleanValue ? 1 : 0);
|
|
break;
|
|
case ShaderParameterType::Enum:
|
|
AppendStd140Int(buffer, EnumIndexForDefault(definition, value));
|
|
break;
|
|
case ShaderParameterType::Text:
|
|
break;
|
|
case ShaderParameterType::Trigger:
|
|
AppendStd140Int(buffer, 0);
|
|
AppendStd140Float(buffer, -1000000.0f);
|
|
break;
|
|
}
|
|
}
|
|
|
|
buffer.resize(AlignStd140(buffer.size(), 16), 0);
|
|
return buffer;
|
|
}
|