feat(shader): Add prepare_global_blur and high-DPI scaling support
- Add prepare_global_blur() method combining Deep Sea render + blur - Add fb_scale parameter to setup_fbos() for high-DPI display support - FBOs now created at scaled resolution (width * fb_scale, height * fb_scale) - prepare_global_blur() auto-initializes FBOs if scale changes - Add test_blur_pipeline_prepare_global_blur - Add test_blur_pipeline_high_dpi_scaling Task: Phase 2, Tasks 1-2 of frosted_glass_20260313 track
This commit is contained in:
@@ -164,6 +164,7 @@ class BlurPipeline:
|
||||
self.deepsea_program: int | None = None
|
||||
self._fb_width: int = 0
|
||||
self._fb_height: int = 0
|
||||
self._fb_scale: int = 1
|
||||
|
||||
def _compile_shader(self, vertex_src: str, fragment_src: str) -> int:
|
||||
program = gl.glCreateProgram()
|
||||
@@ -206,12 +207,16 @@ class BlurPipeline:
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
|
||||
return fbo, tex
|
||||
|
||||
def setup_fbos(self, width: int, height: int):
|
||||
blur_w = max(1, width // 4)
|
||||
blur_h = max(1, height // 4)
|
||||
def setup_fbos(self, width: int, height: int, fb_scale: float = 1.0):
|
||||
scale = max(1, int(fb_scale))
|
||||
blur_w = max(1, (width * scale) // 4)
|
||||
blur_h = max(1, (height * scale) // 4)
|
||||
self._fb_width = blur_w
|
||||
self._fb_height = blur_h
|
||||
self.scene_fbo, self.scene_tex = self._create_fbo(width, height)
|
||||
self._fb_scale = scale
|
||||
scene_w = width * scale
|
||||
scene_h = height * scale
|
||||
self.scene_fbo, self.scene_tex = self._create_fbo(scene_w, scene_h)
|
||||
self.blur_fbo_a, self.blur_tex_a = self._create_fbo(blur_w, blur_h)
|
||||
self.blur_fbo_b, self.blur_tex_b = self._create_fbo(blur_w, blur_h)
|
||||
|
||||
@@ -355,8 +360,10 @@ void main() {
|
||||
def render_deepsea_to_fbo(self, width: int, height: int, time: float):
|
||||
if not self.deepsea_program or not self.scene_fbo:
|
||||
return
|
||||
scene_w = width * self._fb_scale
|
||||
scene_h = height * self._fb_scale
|
||||
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.scene_fbo)
|
||||
gl.glViewport(0, 0, width, height)
|
||||
gl.glViewport(0, 0, scene_w, scene_h)
|
||||
gl.glClearColor(0.01, 0.05, 0.12, 1.0)
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||
gl.glUseProgram(self.deepsea_program)
|
||||
@@ -365,7 +372,7 @@ void main() {
|
||||
gl.glUniform1f(u_time, time)
|
||||
u_res = gl.glGetUniformLocation(self.deepsea_program, "u_resolution")
|
||||
if u_res != -1:
|
||||
gl.glUniform2f(u_res, float(width), float(height))
|
||||
gl.glUniform2f(u_res, float(scene_w), float(scene_h))
|
||||
gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, 4)
|
||||
gl.glUseProgram(0)
|
||||
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
||||
@@ -402,7 +409,16 @@ void main() {
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||
self._render_quad(self.v_blur_program, self.blur_tex_a, (texel_x, texel_y))
|
||||
gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
|
||||
gl.glViewport(0, 0, width, height)
|
||||
restore_w = width * self._fb_scale
|
||||
restore_h = height * self._fb_scale
|
||||
gl.glViewport(0, 0, restore_w, restore_h)
|
||||
|
||||
def prepare_global_blur(self, width: int, height: int, time: float, fb_scale: float = 1.0):
|
||||
if not self.scene_fbo:
|
||||
if self._fb_scale != int(fb_scale):
|
||||
self.setup_fbos(width, height, fb_scale)
|
||||
self.render_deepsea_to_fbo(width, height, time)
|
||||
self.prepare_blur(width, height, time)
|
||||
|
||||
def get_blur_texture(self) -> int | None:
|
||||
return self.blur_tex_b
|
||||
|
||||
Reference in New Issue
Block a user