+template<class T>
+bool Renderer::WriteDefaultUniform(const Graphics::UniformInfo* uniformInfo, Render::UniformBufferView& ubo, const T& data)
+{
+ if(uniformInfo && !uniformInfo->name.empty())
+ {
+ WriteUniform(ubo, *uniformInfo, data);
+ return true;
+ }
+ return false;
+}
+
+template<class T>
+void Renderer::WriteUniform(Render::UniformBufferView& ubo, const Graphics::UniformInfo& uniformInfo, const T& data)
+{
+ WriteUniform(ubo, uniformInfo, &data, sizeof(T));
+}
+
+void Renderer::WriteUniform(Render::UniformBufferView& ubo, const Graphics::UniformInfo& uniformInfo, const void* data, uint32_t size)
+{
+ ubo.Write(data, size, ubo.GetOffset() + uniformInfo.offset);
+}
+
+void Renderer::FillUniformBuffer(Program& program,
+ const SceneGraph::RenderInstruction& instruction,
+ Render::UniformBufferView& ubo,
+ std::vector<Graphics::UniformBufferBinding>*& outBindings,
+ uint32_t& offset,
+ BufferIndex updateBufferIndex)
+{
+ auto& reflection = mGraphicsController->GetProgramReflection(program.GetGraphicsProgram());
+ auto uboCount = reflection.GetUniformBlockCount();
+
+ // Setup bindings
+ uint32_t dataOffset = offset;
+ for(auto i = 0u; i < uboCount; ++i)
+ {
+ mUniformBufferBindings[i].dataSize = reflection.GetUniformBlockSize(i);
+ mUniformBufferBindings[i].binding = reflection.GetUniformBlockBinding(i);
+
+ dataOffset += GetUniformBufferDataAlignment(mUniformBufferBindings[i].dataSize);
+ mUniformBufferBindings[i].buffer = ubo.GetBuffer(&mUniformBufferBindings[i].offset);
+
+ for(UniformIndexMappings::Iterator iter = mUniformIndexMap.Begin(),
+ end = mUniformIndexMap.End();
+ iter != end;
+ ++iter)
+ {
+ auto& uniform = *iter;
+ int arrayIndex = uniform.arrayIndex;
+
+ if(!uniform.uniformFunc)
+ {
+ auto uniformInfo = Graphics::UniformInfo{};
+ auto uniformFound = program.GetUniform(uniform.uniformName.GetCString(),
+ uniform.uniformNameHashNoArray ? uniform.uniformNameHashNoArray
+ : uniform.uniformNameHash,
+ uniformInfo);
+
+ uniform.uniformOffset = uniformInfo.offset;
+ uniform.uniformLocation = uniformInfo.location;
+
+ if(uniformFound)
+ {
+ auto dst = ubo.GetOffset() + uniformInfo.offset;
+ const auto typeSize = GetPropertyValueSizeForUniform((*iter).propertyValue->GetType());
+ const auto dest = dst + static_cast<uint32_t>(typeSize) * arrayIndex;
+ const auto func = GetPropertyValueGetter((*iter).propertyValue->GetType());
+
+ ubo.Write(&((*iter).propertyValue->*func)(updateBufferIndex),
+ typeSize,
+ dest);
+
+ uniform.uniformSize = typeSize;
+ uniform.uniformFunc = func;
+ }
+ }
+ else
+ {
+ auto dst = ubo.GetOffset() + uniform.uniformOffset;
+ const auto typeSize = uniform.uniformSize;
+ const auto dest = dst + static_cast<uint32_t>(typeSize) * arrayIndex;
+ const auto func = uniform.uniformFunc;
+
+ ubo.Write(&((*iter).propertyValue->*func)(updateBufferIndex),
+ typeSize,
+ dest);
+ }
+ }
+ }
+ // write output bindings
+ outBindings = &mUniformBufferBindings;
+
+ // Update offset
+ offset = dataOffset;
+}
+
+void Renderer::SetSortAttributes(SceneGraph::RenderInstructionProcessor::SortAttributes& sortAttributes) const