diff --git a/src/gui_2.py b/src/gui_2.py index e090686..bea9b1c 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -39,6 +39,7 @@ else: from pydantic import BaseModel from imgui_bundle import imgui, hello_imgui, immapp, imgui_node_editor as ed +from src.shader_manager import BlurPipeline PROVIDERS: list[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax"] COMMS_CLAMP_CHARS: int = 300 @@ -212,6 +213,49 @@ class App: self.ui_tool_filter_category = "All" self.ui_discussion_split_h = 300.0 self.shader_uniforms = {'crt': 1.0, 'scanline': 0.5, 'bloom': 0.8} + self.ui_frosted_glass_enabled = False + self._blur_pipeline: BlurPipeline | None = None + self.ui_frosted_glass_enabled = False + self._blur_pipeline = None + + def _pre_render_blur(self): + if not self.ui_frosted_glass_enabled: + return + if not self._blur_pipeline: + return + ws = imgui.get_io().display_size + fb_scale = imgui.get_io().display_framebuffer_scale.x + import time + t = time.time() + self._blur_pipeline.prepare_global_blur(int(ws.x), int(ws.y), t, fb_scale) + + def _render_frosted_background(self, window_pos: tuple, window_size: tuple): + if not self.ui_frosted_glass_enabled: + return + if not self._blur_pipeline: + return + blur_tex = self._blur_pipeline.get_blur_texture() + if not blur_tex: + return + ws = imgui.get_io().display_size + fb_scale = imgui.get_io().display_framebuffer_scale.x + screen_w = ws.x * fb_scale + screen_h = ws.y * fb_scale + uv_x = window_pos[0] / screen_w + uv_y = 1.0 - (window_pos[1] / screen_h) + uv_w = window_size[0] / screen_w + uv_h = window_size[1] / screen_h + dl = imgui.get_window_draw_list() + self._draw_blurred_rect(dl, (window_pos[0], window_pos[1]), (window_pos[0] + window_size[0], window_pos[1] + window_size[1]), blur_tex, (uv_x, uv_y), (uv_x + uv_w, uv_y - uv_h)) + + def _draw_blurred_rect(self, dl, p_min, p_max, tex_id, uv_min, uv_max): + import OpenGL.GL as gl + gl.glEnable(gl.GL_BLEND) + gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) + imgui.push_texture_id(tex_id) + dl.add_image_quad(p_min, p_max, uv_min, uv_max, imgui.get_color_u32((1, 1, 1, 1))) + imgui.pop_texture_id() + gl.glDisable(gl.GL_BLEND) def _handle_approve_tool(self, user_data=None) -> None: """UI-level wrapper for approving a pending tool execution ask.""" @@ -437,6 +481,8 @@ class App: exp, opened = imgui.begin('Shader Editor', self.show_windows['Shader Editor']) self.show_windows['Shader Editor'] = bool(opened) if exp: + _, self.ui_frosted_glass_enabled = imgui.checkbox('Frosted Glass', self.ui_frosted_glass_enabled) + imgui.separator() changed_crt, self.shader_uniforms['crt'] = imgui.slider_float('CRT Curvature', self.shader_uniforms['crt'], 0.0, 2.0) changed_scan, self.shader_uniforms['scanline'] = imgui.slider_float('Scanline Intensity', self.shader_uniforms['scanline'], 0.0, 1.0) changed_bloom, self.shader_uniforms['bloom'] = imgui.slider_float('Bloom Threshold', self.shader_uniforms['bloom'], 0.0, 1.0) @@ -3993,6 +4039,27 @@ def hello(): def _post_init(self) -> None: theme.apply_current() + self._init_blur_pipeline() + + def _init_blur_pipeline(self): + if self._blur_pipeline is None: + self._blur_pipeline = BlurPipeline() + ws = imgui.get_io().display_size + fb_scale = imgui.get_io().display_framebuffer_scale.x + self._blur_pipeline.setup_fbos(int(ws.x), int(ws.y), fb_scale) + self._blur_pipeline.compile_deepsea_shader() + self._blur_pipeline.compile_blur_shaders() + + def _pre_new_frame(self) -> None: + if not self.ui_frosted_glass_enabled: + return + if self._blur_pipeline is None: + self._init_blur_pipeline() + ws = imgui.get_io().display_size + fb_scale = imgui.get_io().display_framebuffer_scale.x + import time + t = time.time() + self._blur_pipeline.prepare_global_blur(int(ws.x), int(ws.y), t, fb_scale) def run(self) -> None: """Initializes the ImGui runner and starts the main application loop.""" @@ -4049,6 +4116,7 @@ def hello(): self.runner_params.callbacks.load_additional_fonts = self._load_fonts self.runner_params.callbacks.setup_imgui_style = theme.apply_current self.runner_params.callbacks.post_init = self._post_init + self.runner_params.callbacks.pre_new_frame = self._pre_new_frame self._fetch_models(self.current_provider) md_options = markdown_helper.get_renderer().options immapp.run(self.runner_params, add_ons_params=immapp.AddOnsParams(with_markdown_options=md_options))