#include "gfx/uniform_panel.h" #include "gfx/gl_loader.h" #include "imgui.h" namespace fn::gfx { void uniforms_sync(UniformStore& store, const std::vector& descs) { // Remove keys no longer present for (auto it = store.values.begin(); it != store.values.end(); ) { bool found = false; for (auto& d : descs) if (d.name == it->first) { found = true; break; } it = found ? std::next(it) : store.values.erase(it); } // Add new entries with defaults for (auto& d : descs) { if (store.values.count(d.name)) continue; std::array arr = { d.defaults[0], d.defaults[1], d.defaults[2], d.defaults[3] }; store.values[d.name] = arr; } } void uniforms_panel(UniformStore& store, const std::vector& descs) { if (descs.empty()) { ImGui::TextDisabled("Declare uniforms with @slider ... annotations."); return; } for (auto& d : descs) { auto it = store.values.find(d.name); if (it == store.values.end()) continue; float* v = it->second.data(); switch (d.widget) { case WidgetKind::Slider: { if (d.glsl_type == GLSLType::Int) { int tmp = static_cast(v[0]); if (ImGui::SliderInt(d.name.c_str(), &tmp, static_cast(d.min[0]), static_cast(d.max[0]))) { v[0] = static_cast(tmp); } } else { ImGuiSliderFlags flags = d.log_scale ? ImGuiSliderFlags_Logarithmic : 0; ImGui::SliderFloat(d.name.c_str(), &v[0], d.min[0], d.max[0], "%.3f", flags); } break; } case WidgetKind::Color: { if (d.glsl_type == GLSLType::Vec4) ImGui::ColorEdit4(d.name.c_str(), v); else ImGui::ColorEdit3(d.name.c_str(), v); break; } case WidgetKind::Toggle: { bool tmp = v[0] != 0.0f; if (ImGui::Checkbox(d.name.c_str(), &tmp)) v[0] = tmp ? 1.0f : 0.0f; break; } case WidgetKind::XY: { ImGui::SliderFloat2(d.name.c_str(), v, d.min[0], d.max[0]); break; } } } } void uniforms_apply(const UniformStore& store, const std::vector& descs, unsigned int program) { for (auto& d : descs) { auto it = store.values.find(d.name); if (it == store.values.end()) continue; const float* v = it->second.data(); GLint loc = glGetUniformLocation(program, d.name.c_str()); if (loc < 0) continue; switch (d.glsl_type) { case GLSLType::Float: glUniform1f(loc, v[0]); break; case GLSLType::Int: glUniform1i(loc, static_cast(v[0])); break; case GLSLType::Bool: glUniform1i(loc, v[0] != 0.0f ? 1 : 0); break; case GLSLType::Vec2: glUniform2f(loc, v[0], v[1]); break; case GLSLType::Vec3: glUniform3f(loc, v[0], v[1], v[2]); break; case GLSLType::Vec4: glUniform4f(loc, v[0], v[1], v[2], v[3]); break; } } } } // namespace fn::gfx