"""
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__()
self.init_glut()
[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__":
win.run()