summaryrefslogtreecommitdiff
path: root/renderer.py
diff options
context:
space:
mode:
authorTim Keller <tjk@tjkeller.xyz>2025-12-09 22:16:48 -0600
committerTim Keller <tjk@tjkeller.xyz>2025-12-09 22:16:57 -0600
commit3e7fdfb6c8a50c59ac933f701526ad1815dded92 (patch)
treed2c699ff93e23d0fe45845a4c2dc05d820ec317b /renderer.py
parent39738b84e9164b0f2d01f22440548c4393160013 (diff)
downloadimmich-frame-3e7fdfb6c8a50c59ac933f701526ad1815dded92.tar.xz
immich-frame-3e7fdfb6c8a50c59ac933f701526ad1815dded92.zip
refactor codebase. Reorganize file structure. Replace webpack for vite. Setup setuptools for application. Move closer to distributable appv0.3.0
Diffstat (limited to 'renderer.py')
-rw-r--r--renderer.py172
1 files changed, 0 insertions, 172 deletions
diff --git a/renderer.py b/renderer.py
deleted file mode 100644
index 52572b1..0000000
--- a/renderer.py
+++ /dev/null
@@ -1,172 +0,0 @@
-import pygame
-import numpy as np
-from OpenGL.GL import *
-from typing import Protocol
-
-class ImageRenderer:
- def __init__(self):
- # Setup shader and quad
- self.shader = self._init_shader()
- self.vao = self._init_quad()
-
- # Get uniform locations from the shader
- self.uTransform = glGetUniformLocation(self.shader, "uTransform")
- self.uAlpha = glGetUniformLocation(self.shader, "uAlpha")
-
- # Use the shader program and set default texture unit to 0
- glUseProgram(self.shader)
- glUniform1i(glGetUniformLocation(self.shader, "uTexture"), 0)
-
- # Setup transition
- self.transition = None
-
- def set_transition(self, transition_cls):
- self.transition = transition_cls(self)
-
- @staticmethod
- def compile_shader(source, shader_type):
- shader = glCreateShader(shader_type) # Create a new shader object
- glShaderSource(shader, source) # Attach the shader source code
- glCompileShader(shader) # Compile the shader
- if not glGetShaderiv(shader, GL_COMPILE_STATUS): # Check if compilation succeeded
- raise RuntimeError(glGetShaderInfoLog(shader).decode()) # Raise error with log if failed
- return shader
-
- @staticmethod
- def _init_shader():
- vertex_src = """
- #version 300 es
- precision mediump float; // Precision for float variables (mandatory for ES)
- layout (location = 0) in vec2 aPos; // Vertex position
- layout (location = 1) in vec2 aTexCoord; // Texture coordinates
- uniform mat4 uTransform; // Transformation matrix
- out vec2 TexCoord; // Output texture coordinate
-
- void main() {
- gl_Position = uTransform * vec4(aPos, 0.0, 1.0); // Apply transformation
- TexCoord = aTexCoord; // Pass tex coord to fragment shader
- }
- """
- fragment_src = """
- #version 300 es
- precision mediump float; // Precision for float variables (mandatory for ES)
- in vec2 TexCoord; // Interpolated texture coordinates
- out vec4 FragColor; // Final fragment color
- uniform sampler2D uTexture; // Texture sampler
- uniform float uAlpha; // Global alpha for transparency
-
- void main() {
- vec4 texColor = texture(uTexture, TexCoord); // Sample texture
- FragColor = vec4(texColor.rgb, texColor.a * uAlpha); // Apply alpha blending
- }
- """
-
- # Compile and link shaders into a program
- vs = ImageRenderer.compile_shader(vertex_src, GL_VERTEX_SHADER)
- fs = ImageRenderer.compile_shader(fragment_src, GL_FRAGMENT_SHADER)
- prog = glCreateProgram()
- glAttachShader(prog, vs)
- glAttachShader(prog, fs)
- glLinkProgram(prog)
- return prog
-
- @staticmethod
- def _init_quad():
- # Define a full-screen quad with positions and texture coordinates
- quad = np.array([
- -1, -1, 0, 0, # Bottom-left
- 1, -1, 1, 0, # Bottom-right
- -1, 1, 0, 1, # Top-left
- 1, 1, 1, 1, # Top-right
- ], dtype=np.float32)
-
- # Create and bind a Vertex Array Object
- vao = glGenVertexArrays(1)
- vbo = glGenBuffers(1)
- glBindVertexArray(vao)
- glBindBuffer(GL_ARRAY_BUFFER, vbo)
- glBufferData(GL_ARRAY_BUFFER, quad.nbytes, quad, GL_STATIC_DRAW)
-
- # Setup vertex attributes: position (location = 0)
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 16, ctypes.c_void_p(0))
- glEnableVertexAttribArray(0)
-
- # 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_image(self, tex, win_w, win_h, alpha):
- if not tex.initialized:
- return
- glUseProgram(self.shader)
- glBindVertexArray(self.vao)
- # FIXME check if tex.id is None
- glBindTexture(GL_TEXTURE_2D, tex.id)
-
- # Calculate aspect ratios
- img_aspect = tex.width / tex.height
- win_aspect = win_w / win_h
-
- # Calculate scaling factors to preserve image aspect ratio
- if img_aspect > win_aspect:
- sx = 1.0
- sy = win_aspect / img_aspect
- else:
- sx = img_aspect / win_aspect
- sy = 1.0
-
- # Create transformation matrix for aspect-ratio-correct rendering
- transform = np.array([
- [sx, 0, 0, 0],
- [0, sy, 0, 0],
- [0, 0, 1, 0],
- [0, 0, 0, 1],
- ], dtype=np.float32)
-
- # Pass transformation and alpha to the shader
- glUniformMatrix4fv(self.uTransform, 1, GL_FALSE, transform)
- glUniform1f(self.uAlpha, alpha)
-
- # 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)
-
- pygame.display.flip()
-
- def draw_transition(self, tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration, reversed):
- assert self.transition, "No transition has been set"
-
- # 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, reversed)
-
- pygame.display.flip()
-
-
-class Transition(Protocol):
- def __init__(self, renderer):
- self.renderer = renderer
-
- def draw(self, tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration, reversed):
- pass
-
-
-class TransitionMix(Transition):
- def draw(self, tex_start, tex_end, win_w, win_h, delta_time, transition_time, transition_duration, reversed):
- # Update alpha value for fade effect
- alpha = transition_time / transition_duration
- if alpha > 1.0:
- alpha = 1.0
-
- # 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)