from PySide6.QtOpenGLWidgets import QOpenGLWidget
from PySide6.QtCore import Qt
from PySide6.QtGui import QMouseEvent, QOpenGLFunctions, QVector3D, QMatrix4x4, QKeyEvent, QWheelEvent
from OpenGL import GL, GLUT, GLU
class OpenGLSpaceWidget(QOpenGLWidget):
def __init__(self, parent=None):
super(OpenGLSpaceWidget, self).__init__(parent)
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
self.h = 10 # Задаем глубину ямы
self.a = 2 # Задаем размер основания параллелепипеда
self.camera_rotation = QVector3D(45, 0, 0)
self.camera_position = QVector3D(0, 1, 0)
self.move_speed = 0.1
self.zoom_speed = 0.1
self.sensitivity = 0.1 # Чувствительность камеры к движению мыши
self.is_left_button_pressed = False
self.last_pos = None
def initializeGL(self):
GL.glClearColor(2/255, 194/255, 175/255, 1.0) # фон
GL.glEnable(GL.GL_DEPTH_TEST)
def resizeGL(self, w, h):
# Установка области просмотра
GL.glViewport(0, 0, w, h)
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glMatrixMode(GL.GL_MODELVIEW)
def paintGL(self):
# Рисуем пространство и яму
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glClearColor(2/255, 194/255, 175/255, 1.0) # фон
GL.glLoadIdentity()
self.rotate_camera()
self.move_camera()
# Здесь будет код для рисования
self.draw_scene()
self.draw_pit()
def move_camera(self):
print(f"Позиция камеры: {self.camera_position}")
GL.glTranslatef(self.camera_position.x(), self.camera_position.y(), self.camera_position.z())
GL.glScalef(self.camera_position.z(), self.camera_position.z(), self.camera_position.z())
def rotate_camera(self):
print(f"Поворот камеры: {self.camera_rotation}")
# Применяем поворот камеры
rotation_matrix = QMatrix4x4()
rotation_matrix.rotate(self.camera_rotation.x(), 1, 0, 0)
rotation_matrix.rotate(self.camera_rotation.y(), 0, 1, 0)
rotation_matrix.rotate(self.camera_rotation.z(), 0, 0, 1)
# Применяем матрицу преобразования
GL.glMultMatrixf(rotation_matrix.data())
def draw_scene(self):
# Рисуем зеленую плоскость
GL.glColor3f(62/255, 117/255, 59/255) # Зеленый цвет
# Большие области
zones = [
# left bottom
[
[-10*self.a, 0, -10*self.a],
[-10*self.a, 0, 0],
[0, 0, 0],
[0, 0, -10*self.a]
],
# left top
[
[-10*self.a, 0, self.a],
[-10*self.a, 0, 10*self.a],
[0, 0, 10*self.a],
[0, 0, self.a],
],
# right top
[
[self.a, 0, self.a],
[self.a, 0, 10*self.a],
[10*self.a, 0, 10*self.a],
[10*self.a, 0, self.a],
],
# right bottom
[
[self.a, 0, -10*self.a],
[self.a, 0, 0],
[10*self.a, 0, 0],
[10*self.a, 0, -10*self.a]
],
# Маленькие области
# left
[
[-10*self.a, 0, 0],
[-10*self.a, 0, self.a],
[0, 0, self.a],
[0, 0, 0]
],
# top
[
[0, 0, self.a],
[0, 0, 10*self.a],
[self.a, 0, 10*self.a],
[self.a, 0, self.a]
],
# right
[
[self.a, 0, 0],
[self.a, 0, self.a],
[10*self.a, 0, self.a],
[10*self.a, 0, 0]
],
# bottom
[
[0, 0, -10*self.a],
[0, 0, 0],
[self.a, 0, 0],
[self.a, 0, -10*self.a]
]
]
for zone in zones:
GL.glBegin(GL.GL_QUADS)
for vector in zone:
GL.glVertex3f(vector[0], vector[1], vector[2])
GL.glEnd()
# bottom
def draw_pit(self):
# Рисуем параллелепипед с основанием A и высотой H
GL.glColor3f(1.0, 0.0, 0.0) # Красный цвет
zones = [
[
[0, -self.h, 0],
[0, -self.h, self.a],
[self.a, -self.h, self.a],
[self.a, -self.h, 0]
],
[
[0, -self.h, self.a],
[0, 0, self.a],
[self.a, 0, self.a],
[self.a, -self.h, self.a]
],
[
[self.a, -self.h, 0],
[self.a, 0, 0],
[self.a, 0, self.a],
[self.a, -self.h, self.a]
],
[
[0, -self.h, 0],
[0, 0, 0],
[self.a, 0, 0],
[self.a, -self.h, 0]
],
[
[0, -self.h, 0],
[0, 0, 0],
[0, 0, self.a],
[0, -self.h, self.a]
]
]
for zone in zones:
GL.glBegin(GL.GL_QUADS)
for vector in zone:
GL.glVertex3f(vector[0], vector[1], vector[2])
GL.glEnd()
# PySidePart
def mousePressEvent(self, event: QMouseEvent) -> None:
if event.button() == Qt.MouseButton.LeftButton:
self.is_left_button_pressed = True
self.last_pos = event.pos()
def mouseReleaseEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
self.is_left_button_pressed = False
self.last_pos = None
def mouseMoveEvent(self, event):
if self.is_left_button_pressed:
if self.last_pos is None:
return
dx = event.x() - self.last_pos.x()
# dy = event.y() - self.last_pos.y()
self.camera_rotation += QVector3D(0, dx * self.sensitivity, 0)
self.last_pos = event.pos()
self.update() # Запустить перерисовку
def keyPressEvent(self, event: QKeyEvent):
if event.key() == Qt.Key.Key_W:
self.camera_position += QVector3D(0, 0, self.move_speed)
elif event.key() == Qt.Key.Key_A:
self.camera_position += QVector3D(-self.move_speed, 0, 0)
elif event.key() == Qt.Key.Key_S:
self.camera_position += QVector3D(0, 0, -self.move_speed)
elif event.key() == Qt.Key.Key_D:
self.camera_position += QVector3D(self.move_speed, 0, 0)
else:
print(event.key())
print(event.keyCombination())
self.update() # Запустить перерисовку
def wheelEvent(self, event: QWheelEvent):
delta = event.angleDelta().y()
# Изменение положения камеры в зависимости от направления колеса мыши
if delta > 0:
self.camera_position += QVector3D(0, self.zoom_speed, 0)
elif delta < 0 and self.camera_position.y()-self.zoom_speed > 1:
self.camera_position += QVector3D(0, -self.zoom_speed, 0)
self.update() # Запустить перерисовку