Source code for picogl.ui.backend.glut.window.glut_legacy

import numpy as np
from OpenGL.raw.GL.VERSION.GL_1_0 import glViewport
from pyglm import glm

from picogl.logger import Logger as log
from picogl.logger import setup_logging
from picogl.renderer import GLContext
from picogl.ui.backend.glut.window.gl import GLWindow
from picogl.utils.gl_init import execute_gl_tasks, init_gl_list, paint_gl_list


[docs] class GlutRendererWindow(GLWindow): """Glut Rendered Window""" def __init__( self, width, height, title: str = None, context: GLContext = None, *args, **kwargs, ): super().__init__(title=title, *args, **kwargs)
[docs] self.context = GLContext() if context is None else context
[docs] self.title = title
[docs] self.renderer = None
[docs] self.width = width
[docs] self.height = height
# Mouse interaction state
[docs] self.last_mouse_x = None
[docs] self.last_mouse_y = None
[docs] self.rotation_x = 0.0
[docs] self.rotation_y = 0.0
setup_logging()
[docs] self.zoom_fov: int = 45 # field of view
[docs] self.zoom_distance: int = 10 # camera backwards in Z
[docs] self.distance_threshold: float = 5.0
[docs] def initializeGL(self): """Initial OpenGL configuration.""" log.message("Initializing OpenGL context...") execute_gl_tasks(init_gl_list) self.renderer.initialize_shaders() self.renderer.initialize()
[docs] def calculate_mvp_matrix(self, width: int = 1920, height: int = 1080): """calculate_mvp_matrix""" self.context.projection = glm.perspective( glm.radians(self.zoom_fov), float(width) / float(height), 0.1, 1000.0 ) self.context.eye = glm.vec3(4, 3, self.zoom_distance) self.context.center = glm.vec3(0, 0, 0) self.context.up = glm.vec3(0, 1, 0) self.context.view = glm.lookAt( self.context.eye, self.context.center, self.context.up ) self.context.model_matrix = glm.mat4(1.0) # The camera position in world space is just the eye self.context.eye_np = np.array(self.context.eye.to_list(), dtype=np.float32) self.context.mvp_matrix = ( self.context.projection * self.context.view * self.context.model_matrix )
[docs] def resizeGL(self, width, height): """resizeGL""" log.message(f"Resizing viewport to {width}x{height}...") self.width = width self.height = height glViewport(0, 0, width, height) self.calculate_mvp_matrix(width, height)
[docs] def paintGL(self): """paintGL""" execute_gl_tasks(paint_gl_list) self.renderer.render()
[docs] def update_mvp(self): """Base perspective matrix from your existing method""" width, height = self.get_size() self.calculate_mvp_matrix(width, height) # Apply rotations rotation_matrix = glm.rotate( glm.mat4(1.0), glm.radians(self.rotation_x), glm.vec3(1, 0, 0) ) rotation_matrix = glm.rotate( rotation_matrix, glm.radians(self.rotation_y), glm.vec3(0, 1, 0) ) self.context.mvp_matrix = self.context.mvp_matrix * rotation_matrix self.update() # Trigger repaint
[docs] def mousePressEvent(self, button, state, x, y): """mousePressEvent""" if state == 0: # Mouse button pressed self.last_mouse_x = x self.last_mouse_y = y
[docs] def mouseMoveEvent(self, x, y): """mouseMoveEvent""" if self.last_mouse_x is not None and self.last_mouse_y is not None: dx = x - self.last_mouse_x dy = y - self.last_mouse_y # Adjust sensitivity as needed self.rotation_x += dy * 0.5 self.rotation_y += dx * 0.5 self.update_mvp() self.last_mouse_x = x self.last_mouse_y = y
[docs] def wheelEvent(self, wheel=0, direction=0, x=0, y=0): """ Mouse wheel zoom: adjusts distance if far, FOV if close. Positive direction -> zoom in, Negative -> zoom out. """ zoom_step = direction * 0.5 if self.zoom_distance > self.distance_threshold: # Distance zoom self.zoom_distance = max(1.0, self.zoom_distance - zoom_step) else: # FOV zoom self.zoom_fov = max(10.0, min(90.0, self.zoom_fov - zoom_step)) print( f"Zoom mode: {'distance' if self.zoom_distance > self.distance_threshold else 'fov'} " f"| Distance: {self.zoom_distance:.2f} | FOV: {self.zoom_fov:.2f}" ) self.update_mvp()
[docs] def get_size(self): return self.width, self.height
if __name__ == "__main__":
[docs] win = GlutRendererWindow(width=1024, height=768)
win.run()