@wintreist

Почему не вижу отрисованную область?

Доброго времени суток. Видимо я ничего не понимаю в 3D графике, потому что я, используя OpenGL, рисую область и параллелепипед в ней, устанавливаю камеру над ней, но при отрисовке кроме фона ничего не видно.
Может кто поймет в чем я криворук?
Почему-то при camera_position = QVector3D(0, 0, 5), если повернуть камеру, то видна зеленая область, в других местах вообще нет ничего
Код для воспроизведения
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()  # Запустить перерисовку
  • Вопрос задан
  • 27 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы