diff options
| author | Tim Keller <tjkeller.xyz> | 2025-05-10 16:26:33 -0500 |
|---|---|---|
| committer | Tim Keller <tjkeller.xyz> | 2025-05-10 16:26:33 -0500 |
| commit | 3aed05a6cb265e4f60a17f87eb368fb33c93a562 (patch) | |
| tree | 678661df04e9ae66ee7e4636d396bde8171cf2d3 | |
| parent | b823139687f3c55dd3695e11a0cf8f9693524e9b (diff) | |
| download | immich-frame-3aed05a6cb265e4f60a17f87eb368fb33c93a562.tar.xz immich-frame-3aed05a6cb265e4f60a17f87eb368fb33c93a562.zip | |
cleanup some
| -rw-r--r-- | renderer.py | 49 | ||||
| -rw-r--r-- | texture.py | 4 | ||||
| -rw-r--r-- | window.py | 51 |
3 files changed, 59 insertions, 45 deletions
diff --git a/renderer.py b/renderer.py index 92d0686..01c9f3f 100644 --- a/renderer.py +++ b/renderer.py @@ -8,7 +8,7 @@ class ImageRenderer: def __init__(self): # Setup shader and quad self.shader = self._init_shader() - self._init_quad() + self.vao = self._init_quad() # Get uniform locations from the shader self.uTransform = glGetUniformLocation(self.shader, "uTransform") @@ -21,8 +21,11 @@ class ImageRenderer: # Setup transition self.transition = None - def set_transition(self, transition): - self.transition = transition(self) + # State helper + self._state = None + + def set_transition(self, transition_cls): + self.transition = transition_cls(self) @staticmethod def compile_shader(source, shader_type): @@ -33,7 +36,8 @@ class ImageRenderer: raise RuntimeError(glGetShaderInfoLog(shader).decode()) # Raise error with log if failed return shader - def _init_shader(self): + @staticmethod + def _init_shader(): vertex_src = """ #version 330 core layout (location = 0) in vec2 aPos; // Vertex position @@ -68,7 +72,8 @@ class ImageRenderer: glLinkProgram(prog) return prog - def _init_quad(self): + @staticmethod + def _init_quad(): # Define a full-screen quad with positions and texture coordinates quad = np.array([ -1, -1, 0, 0, # Bottom-left @@ -78,9 +83,9 @@ class ImageRenderer: ], dtype=np.float32) # Create and bind a Vertex Array Object - self.vao = glGenVertexArrays(1) + vao = glGenVertexArrays(1) vbo = glGenBuffers(1) - glBindVertexArray(self.vao) + glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, quad.nbytes, quad, GL_STATIC_DRAW) @@ -91,8 +96,9 @@ class ImageRenderer: # Setup vertex attributes: texture coordinates (location = 1) glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16, ctypes.c_void_p(8)) glEnableVertexAttribArray(1) + return vao - def draw_static(self, tex, win_w, win_h, alpha): + def draw_image(self, tex, win_w, win_h, alpha): glUseProgram(self.shader) glBindVertexArray(self.vao) glBindTexture(GL_TEXTURE_2D, tex.id) @@ -124,9 +130,25 @@ class ImageRenderer: # Draw the textured quad glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) + def draw_static(self, tex, win_w, win_h, alpha): + # Set the background color to black + glClearColor(0.0, 0.0, 0.0, 1.0) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + self.draw_image(tex, win_w, win_h, alpha) + + glutSwapBuffers() + def draw_transition(self, tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration): assert self.transition, "No transition has been set" - return self.transition.draw(tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration) + + # Set the background color to black + glClearColor(0.0, 0.0, 0.0, 1.0) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + self.transition.draw(tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration) + + glutSwapBuffers() class Transition(Protocol): @@ -144,9 +166,6 @@ class TransitionMix(Transition): if alpha > 1.0: alpha = 1.0 - # Draw the first image - self.renderer.draw_static(tex_start, win_w, win_h, 1 - alpha) # TODO instead of decreasing alpha, draw transparent letterboxes - # Draw the second image (with transparency) - self.renderer.draw_static(tex_end, win_w, win_h, alpha) - - return alpha >= 1.0 # Complete + # Draw the images on top of one another + self.renderer.draw_image(tex_start, win_w, win_h, 1 - alpha) # TODO instead of decreasing alpha, draw transparent letterboxes + self.renderer.draw_image(tex_end, win_w, win_h, alpha) @@ -7,8 +7,8 @@ class ImageTexture: def __init__(self, image_source, exif=None): self.id = None img = Image.open(image_source) - self.exif = exif or ImageTexture.get_exif(img) - img = ImageTexture.handle_orientation(img, self.exif) + self.exif = exif or self.get_exif(img) + img = self.handle_orientation(img, self.exif) img = img.convert("RGBA") # Ensure the image is in RGBA mode self.width = img.width self.height = img.height @@ -15,8 +15,8 @@ class PixDisplay: self.textures = [] self.current_texture_index = 0 self.renderer = None - self.window_width = 0 - self.window_height = 0 + self.win_w = 0 + self.win_h = 0 self.max_framerate = 30 self.display_duration = 2.0 @@ -32,13 +32,16 @@ class PixDisplay: self.frame_time = int(1000 / 60) # In ms @property + def prev_texture_index(self): return self.current_texture_index - 1 + + @property def next_texture_index(self): return (self.current_texture_index + 1) % len(self.textures) @property - def texture_current(self): return self.textures[self.current_texture_index] + def tex(self): return self.textures[self.current_texture_index] @property - def texture_next(self): return self.textures[self.next_texture_index] + def tex_next(self): return self.textures[self.next_texture_index] # Main display function def display(self): @@ -48,46 +51,38 @@ class PixDisplay: delta_time = current_time - self.last_time self.last_time = current_time + # Draw black window if no textures are available if not self.textures: - glClearColor(0.0, 0.0, 0.0, 1.0) # Set the background color to black + glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glutSwapBuffers() return # Ensure textures are initialized - self.texture_current.gl_init() - self.texture_next.gl_init() + self.tex.gl_init() + self.tex_next.gl_init() # Progress image time self.image_time += delta_time # Get window size - window_width, window_height = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT) - - if self.image_time < self.display_duration: - if window_width != self.window_width or window_height != self.window_height: - self.window_width, self.window_height = window_width, window_height - - glClearColor(0.0, 0.0, 0.0, 1.0) # Set the background color to black - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - self.renderer.draw_static(self.texture_current, self.window_width, self.window_height, 1) - - glutSwapBuffers() + old_win_w, old_win_h = self.win_w, self.win_h + self.win_w, self.win_h = glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT) + + # Draw static image except during a transition + if self.image_time <= self.display_duration: + # Avoid redraw unless window size has changed + if self.win_w != old_win_w or self.win_h != old_win_h: + self.renderer.draw_static(self.tex, self.win_w, self.win_h, 1) return - self.window_width, self.window_height = window_width, window_height - - glClearColor(0.0, 0.0, 0.0, 1.0) # Set the background color to black - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - # DRAW + # Draw transition transition_time = self.image_time - self.display_duration - complete = self.renderer.draw_transition(self.texture_current, self.texture_next, self.window_width, self.window_height, delta_time, transition_time, self.transition_duration) - glutSwapBuffers() + # Draw frame of transition, function will return True if the transition is complete + self.renderer.draw_transition(self.tex, self.tex_next, self.win_w, self.win_h, delta_time, transition_time, self.transition_duration) - if complete: + if transition_time >= self.transition_duration: self.image_time = 0 self.current_texture_index = self.next_texture_index |
