#include "GlobalParamsBuffer.h" #include "GlRenderConstants.h" #include "Std140Buffer.h" #include GlobalParamsBuffer::GlobalParamsBuffer(OpenGLRenderer& renderer) : mRenderer(renderer) { } bool GlobalParamsBuffer::Update(const RuntimeRenderState& state, unsigned availableSourceHistoryLength, unsigned availableTemporalHistoryLength) { std::vector buffer; buffer.reserve(512); AppendStd140Float(buffer, static_cast(state.timeSeconds)); AppendStd140Vec2(buffer, static_cast(state.inputWidth), static_cast(state.inputHeight)); AppendStd140Vec2(buffer, static_cast(state.outputWidth), static_cast(state.outputHeight)); AppendStd140Float(buffer, static_cast(state.utcTimeSeconds)); AppendStd140Float(buffer, static_cast(state.utcOffsetSeconds)); AppendStd140Float(buffer, static_cast(state.frameCount)); AppendStd140Float(buffer, static_cast(state.mixAmount)); AppendStd140Float(buffer, static_cast(state.bypass)); const unsigned effectiveSourceHistoryLength = availableSourceHistoryLength < state.effectiveTemporalHistoryLength ? availableSourceHistoryLength : state.effectiveTemporalHistoryLength; const unsigned effectiveTemporalHistoryLength = (state.temporalHistorySource == TemporalHistorySource::PreLayerInput) ? (availableTemporalHistoryLength < state.effectiveTemporalHistoryLength ? availableTemporalHistoryLength : state.effectiveTemporalHistoryLength) : 0u; AppendStd140Int(buffer, static_cast(effectiveSourceHistoryLength)); AppendStd140Int(buffer, static_cast(effectiveTemporalHistoryLength)); for (const ShaderParameterDefinition& definition : state.parameterDefinitions) { auto valueIt = state.parameterValues.find(definition.id); const ShaderParameterValue value = valueIt != state.parameterValues.end() ? valueIt->second : ShaderParameterValue(); switch (definition.type) { case ShaderParameterType::Float: AppendStd140Float(buffer, value.numberValues.empty() ? 0.0f : static_cast(value.numberValues[0])); break; case ShaderParameterType::Vec2: AppendStd140Vec2(buffer, value.numberValues.size() > 0 ? static_cast(value.numberValues[0]) : 0.0f, value.numberValues.size() > 1 ? static_cast(value.numberValues[1]) : 0.0f); break; case ShaderParameterType::Color: AppendStd140Vec4(buffer, value.numberValues.size() > 0 ? static_cast(value.numberValues[0]) : 1.0f, value.numberValues.size() > 1 ? static_cast(value.numberValues[1]) : 1.0f, value.numberValues.size() > 2 ? static_cast(value.numberValues[2]) : 1.0f, value.numberValues.size() > 3 ? static_cast(value.numberValues[3]) : 1.0f); break; case ShaderParameterType::Boolean: AppendStd140Int(buffer, value.booleanValue ? 1 : 0); break; case ShaderParameterType::Enum: { int selectedIndex = 0; for (std::size_t optionIndex = 0; optionIndex < definition.enumOptions.size(); ++optionIndex) { if (definition.enumOptions[optionIndex].value == value.enumValue) { selectedIndex = static_cast(optionIndex); break; } } AppendStd140Int(buffer, selectedIndex); break; } case ShaderParameterType::Text: break; } } buffer.resize(AlignStd140(buffer.size(), 16), 0); glBindBuffer(GL_UNIFORM_BUFFER, mRenderer.GlobalParamsUBO()); if (mRenderer.GlobalParamsUBOSize() != static_cast(buffer.size())) { glBufferData(GL_UNIFORM_BUFFER, static_cast(buffer.size()), buffer.data(), GL_DYNAMIC_DRAW); mRenderer.SetGlobalParamsUBOSize(static_cast(buffer.size())); } else { glBufferSubData(GL_UNIFORM_BUFFER, 0, static_cast(buffer.size()), buffer.data()); } glBindBufferBase(GL_UNIFORM_BUFFER, kGlobalParamsBindingPoint, mRenderer.GlobalParamsUBO()); glBindBuffer(GL_UNIFORM_BUFFER, 0); return true; }