from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * from time import time from renderer import ImageRenderer, TransitionMix from texture import ImageTexture class PixDisplay: def __init__(self): self.last_time = 0 self.start_time = 0 self.image_time = 0 self.textures = [] self.current_texture_index = 0 self.renderer = None self.win_w = 0 self.win_h = 0 self.max_framerate = 30 self.display_duration = 2.0 self.transition_duration = 0.5 @property def max_framerate(self): return self._max_fps @max_framerate.setter def max_framerate(self, max_fps): self._max_fps = max_fps # This is just for the getter since otherwise e.g. int(1000/int(1000/60)) would round to 62 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 tex(self): return self.textures[self.current_texture_index] @property def tex_next(self): return self.textures[self.next_texture_index] # Main display function def display(self): # Calculate timings current_time = time() alive_time = current_time - self.start_time 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) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glutSwapBuffers() return # Ensure textures are initialized self.tex.gl_init() self.tex_next.gl_init() # Progress image time self.image_time += delta_time # Get window size 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 # Draw transition transition_time = self.image_time - self.display_duration # 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 transition_time >= self.transition_duration: self.image_time = 0 self.current_texture_index = self.next_texture_index def timer(self, value): glutPostRedisplay() glutTimerFunc(self.frame_time, self.timer, 0) # Schedule next frame # Initialization and main loop def main(self): # Initialize the window glutInit(sys.argv) glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB) glutCreateWindow("Image Viewer with Fade Transition") glEnable(GL_TEXTURE_2D) self.renderer = ImageRenderer() self.renderer.set_transition(TransitionMix) self.image_time = 0 self.start_time = time() self.last_time = time() # Set up the OpenGL viewport and projection glMatrixMode(GL_PROJECTION) glLoadIdentity() glOrtho(-1, 1, -1, 1, -1, 1) glMatrixMode(GL_MODELVIEW) # Enable alpha blending glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) # Run display glutDisplayFunc(self.display) glutTimerFunc(self.frame_time, self.timer, 0) glutMainLoop()