feat(shaders_lab): uniform annotations → auto-generated ImGui controls
- cpp/functions/gfx/uniform_parser: regex-based parser of @slider/@color/@toggle/@xy annotations (+ inline tests) - cpp/functions/gfx/uniform_panel: ImGui widgets + value store + glUniform* apply - shader_canvas: optional uniforms callback invoked per-frame - gl_loader: +glUniform1i/3f/4f - seed plasma: demo uniforms u_speed + u_color - rebuild Windows .exe Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,8 @@ add_imgui_app(shaders_lab
|
||||
${CMAKE_SOURCE_DIR}/functions/gfx/gl_framebuffer.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/gfx/fullscreen_quad.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/gfx/shader_canvas.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/gfx/uniform_parser.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/gfx/uniform_panel.cpp
|
||||
${CMAKE_SOURCE_DIR}/functions/core/fps_overlay.cpp
|
||||
)
|
||||
target_include_directories(shaders_lab PRIVATE
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
#include "gfx/shader_canvas.h"
|
||||
#include "gfx/gl_shader.h"
|
||||
#include "gfx/uniform_parser.h"
|
||||
#include "gfx/uniform_panel.h"
|
||||
#include "core/fps_overlay.h"
|
||||
#include "seed_shaders.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
static fn::gfx::ShaderCanvas g_canvas;
|
||||
static std::string g_source = PLASMA;
|
||||
@@ -15,10 +18,14 @@ static std::string g_last_err;
|
||||
static int g_last_err_line = -1;
|
||||
static std::chrono::steady_clock::time_point g_last_edit;
|
||||
static bool g_dirty = true;
|
||||
static std::vector<fn::gfx::UniformDescriptor> g_descs;
|
||||
static fn::gfx::UniformStore g_store;
|
||||
|
||||
static void try_compile() {
|
||||
auto r = fn::gfx::compile_fragment(g_source);
|
||||
if (r.ok) {
|
||||
g_descs = fn::gfx::parse_uniforms(g_source);
|
||||
fn::gfx::uniforms_sync(g_store, g_descs);
|
||||
fn::gfx::canvas_set_program(g_canvas, r.program);
|
||||
g_last_err.clear();
|
||||
g_last_err_line = -1;
|
||||
@@ -91,13 +98,16 @@ static void render() {
|
||||
|
||||
// --- Canvas panel ---
|
||||
if (ImGui::Begin("Canvas")) {
|
||||
fn::gfx::canvas_render(g_canvas, static_cast<float>(ImGui::GetTime()));
|
||||
fn::gfx::canvas_render(g_canvas, static_cast<float>(ImGui::GetTime()),
|
||||
[](unsigned int program) {
|
||||
fn::gfx::uniforms_apply(g_store, g_descs, program);
|
||||
});
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// --- Controls panel ---
|
||||
if (ImGui::Begin("Controls")) {
|
||||
ImGui::TextDisabled("Controls (fase 2)");
|
||||
fn::gfx::uniforms_panel(g_store, g_descs);
|
||||
ImGui::Spacing();
|
||||
fps_overlay();
|
||||
}
|
||||
|
||||
@@ -4,24 +4,14 @@
|
||||
// compile_fragment() prepends those automatically.
|
||||
|
||||
static const char* PLASMA = R"glsl(
|
||||
uniform float u_speed; // @slider min=0.1 max=5 default=1
|
||||
uniform vec3 u_color; // @color default=0.5,0.2,0.8
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / u_resolution;
|
||||
float t = u_time * 0.5;
|
||||
|
||||
float v1 = sin(uv.x * 10.0 + t);
|
||||
float v2 = sin(uv.y * 10.0 + t * 1.3);
|
||||
float v3 = sin((uv.x + uv.y) * 10.0 + t * 0.7);
|
||||
float v4 = sin(length(uv - 0.5) * 20.0 - t * 2.0);
|
||||
|
||||
float v = (v1 + v2 + v3 + v4) * 0.25;
|
||||
|
||||
vec3 col = vec3(
|
||||
sin(v * 3.14159 + 0.0) * 0.5 + 0.5,
|
||||
sin(v * 3.14159 + 2.094) * 0.5 + 0.5,
|
||||
sin(v * 3.14159 + 4.188) * 0.5 + 0.5
|
||||
);
|
||||
|
||||
fragColor = vec4(col, 1.0);
|
||||
float t = u_time * u_speed;
|
||||
vec3 c = u_color * (0.5 + 0.5 * cos(t + uv.xyx + vec3(0.0, 2.0, 4.0)));
|
||||
fragColor = vec4(c, 1.0);
|
||||
}
|
||||
)glsl";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user