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

"""
Glut Window
"""

import sys

import OpenGL.GL as GL
import OpenGL.GLU as GLU
import OpenGL.GLUT as GLUT

from picogl.ui.abc_window import AbstractGLWindow


[docs] class GLWindow(AbstractGLWindow): """GLWindow"""
[docs] def __init__(self, title: str = "window", *args, **kwargs): """__init__""" super().__init__()
[docs] self.window = None
[docs] self.width = None
[docs] self.height = None
[docs] self.title = title
self.init_glut()
[docs] self.controller = None
[docs] self.update_if = GLUT.glutPostRedisplay
[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 init_glut(self): """init_glut""" GLUT.glutInit(sys.argv) GLUT.glutInitDisplayMode(GLUT.GLUT_RGBA | GLUT.GLUT_DOUBLE | GLUT.GLUT_DEPTH) GLUT.glutInitWindowSize(800, 480) if self.title is not None: title_bytes = self.title.encode("utf-8") else: title_bytes = b"Window Title" self.window = GLUT.glutCreateWindow(title_bytes) GLUT.glutDisplayFunc(self.display) GLUT.glutReshapeFunc(self.resizeGL) GLUT.glutKeyboardFunc(self.keyPressEvent) GLUT.glutSpecialFunc(self.on_special_key) GLUT.glutMouseFunc(self.mousePressEvent) GLUT.glutMotionFunc(self.mouseMoveEvent) GLUT.glutMouseWheelFunc(self.wheelEvent)
[docs] def initializeGL(self): """initialize_gl""" GL.glClearColor(0.0, 0, 0.4, 0) GL.glDepthFunc(GL.GL_LESS) GL.gl_enable(GL.GL_DEPTH_TEST)
[docs] def paintGL(self): """paintGL""" GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) GLU.gluLookAt(4.0, 3.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) # built in model_matrix GLUT.glutSolidTeapot(1) print("please override paintGL")
[docs] def update(self): """draw""" GLUT.glutPostRedisplay()
[docs] def display(self): """display""" self.paintGL() GLUT.glutSwapBuffers()
[docs] def idle(self): """idle""" pass
[docs] def resizeGL(self, width: int, height: int): """resize""" print("please override resize") self.width = width self.height = height GL.glViewport(0, 0, width, height) GLU.gluPerspective(45.0, float(width) / float(height), 0.1, 1000.0)
[docs] def keyPressEvent(self, key, x, y): """on_keyboard""" if self.controller is not None: self.controller.on_keyboard(key, x, y) else: print("please overrider on_keyboard")
[docs] def on_special_key(self, key, x, y): """on_special_key""" if self.controller is not None: self.controller.on_special_key(key, x, y) else: print("please overrider on_keyboard")
[docs] def mousePressEvent(self, *args, **kwargs): """on_mouse""" if self.controller is not None: self.controller.mousePressEvent(*args, **kwargs) else: print("please overrider on_mouse")
[docs] def mouseMoveEvent(self, *args, **kwargs): """on_mousemove""" if self.controller is not None: self.controller.mouseMoveEvent(*args, **kwargs) else: print("please overrider on_mousemove")
[docs] def run(self): """run""" GLUT.glutMainLoop()
if __name__ == "__main__":
[docs] win = GLWindow()
win.run()