+void ProgramImpl::UpdateStandaloneUniformBlock(const char* ptr)
+{
+ const auto& reflection = GetReflection();
+
+ const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo();
+
+ auto& gl = *GetController().GetGL();
+
+ // Set uniforms
+ int index = 0;
+ auto cachePtr = reinterpret_cast<char*>(mImpl->uniformData.data());
+ for(const auto& info : extraInfos)
+ {
+ auto& setter = mImpl->uniformSetters[index++];
+
+ auto offset = info.offset;
+ switch(setter.type)
+ {
+ case UniformSetter::Type::FLOAT:
+ {
+ if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize))
+ {
+ (gl.*(setter.uniformfProc))(info.location, info.arraySize, reinterpret_cast<const float*>(&ptr[offset]));
+ memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize);
+ }
+ break;
+ }
+ case UniformSetter::Type::INT:
+ {
+ if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize))
+ {
+ (gl.*(setter.uniformiProc))(info.location, info.arraySize, reinterpret_cast<const int*>(&ptr[offset]));
+ memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize);
+ }
+ break;
+ }
+ case UniformSetter::Type::MATRIX:
+ {
+ if(0 != memcmp(&cachePtr[offset], &ptr[offset], info.size * info.arraySize))
+ {
+ (gl.*(setter.uniformMatrixProc))(info.location, info.arraySize, GL_FALSE, reinterpret_cast<const float*>(&ptr[offset]));
+ memcpy(&cachePtr[offset], &ptr[offset], info.size * info.arraySize);
+ }
+ break;
+ }
+ case UniformSetter::Type::UNDEFINED:
+ {
+ }
+ }
+ }
+}
+
+void ProgramImpl::BuildStandaloneUniformCache()
+{
+ const auto& reflection = GetReflection();
+ const auto& extraInfos = reflection.GetStandaloneUniformExtraInfo();
+
+ // Prepare pointers to the uniform setter calls
+ mImpl->uniformSetters.resize(extraInfos.size());
+ int index = 0;
+ for(const auto& info : extraInfos)
+ {
+ auto type = GLTypeConversion(info.type).type;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::UNDEFINED;
+ switch(type)
+ {
+ case GLType::FLOAT_VEC2:
+ {
+ mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform2fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT;
+ break;
+ }
+ case GLType::FLOAT_VEC3:
+ {
+ mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform3fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT;
+ break;
+ }
+ case GLType::FLOAT_VEC4:
+ {
+ mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform4fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT;
+ break;
+ }
+ case GLType::INT_VEC2:
+ {
+ mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform2iv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::INT;
+ break;
+ }
+ case GLType::INT_VEC3:
+ {
+ mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform3iv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::INT;
+ break;
+ }
+ case GLType::INT_VEC4:
+ {
+ mImpl->uniformSetters[index].uniformiProc = &GlAbstraction::Uniform4iv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::INT;
+ break;
+ }
+ case GLType::BOOL:
+ case GLType::BOOL_VEC2:
+ case GLType::BOOL_VEC3:
+ case GLType::BOOL_VEC4:
+ case GLType::FLOAT:
+ {
+ mImpl->uniformSetters[index].uniformfProc = &GlAbstraction::Uniform1fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::FLOAT;
+ break;
+ }
+ case GLType::FLOAT_MAT2:
+ {
+ mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix2fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX;
+ break;
+ }
+ case GLType::FLOAT_MAT3:
+ {
+ mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix3fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX;
+ break;
+ }
+ case GLType::FLOAT_MAT4:
+ {
+ mImpl->uniformSetters[index].uniformMatrixProc = &GlAbstraction::UniformMatrix4fv;
+ mImpl->uniformSetters[index].type = UniformSetter::Type::MATRIX;
+ break;
+ }
+ case GLType::SAMPLER_2D:
+ case GLType::SAMPLER_CUBE:
+ default:
+ {
+ }
+ }
+ index++;
+ }
+}
+