내 openGLWidget에 대한 추가 클래스를 생성하지 않으면 glRotate가 한 번만 작동하는 이유는 무엇입니까?

줄리어스 허 피치

Python을 사용하여 6 축 모션 센서의 출력을 표시하는 GUI를 작성 중입니다. 창에는 실시간으로 회전을 표시하는 OpenGL 위젯이 있어야합니다. 일반적으로 나는 별도의 클래스를 작성 openGLWidget하지만 UI에는 많은 요소가 있으므로 처음부터 구성하는 것이 합리적이지 않은 것 같습니다. 대신 .ui 파일을로드하고 필요한 모든 것을 찾으면됩니다. 그러나 glRotate()함수는 한 번만 업데이트되고 다시는 업데이트되지 않으며이 문제의 원인이 무엇인지 전혀 알 수 없습니다.

from PyQt5 import QtWidgets, uic
from PyQt5.QtCore import *
import OpenGL.GL as gl
import OpenGL.GLU as glu
import sys


class Ui(QtWidgets.QWidget):
    def __init__(self):
        super(Ui, self).__init__()
        uic.loadUi('gl_test.ui', self)

        self.openGLWidget = self.findChild(QtWidgets.QOpenGLWidget, 'openGLWidget')
        self.openGLWidget.initializeGL()
        self.openGLWidget.paintGL = self.paintGL
        self.openGLWidget.initializeGL = self.initializeGL
        self.object = None

        self.rotation = 45.0

#       QTimer for updating the GL Viewport
        self.GLtimer = QTimer()
        self.GLtimer.setInterval(100)
        self.GLtimer.timeout.connect(self.openGLWidget.paintGL)
        self.GLtimer.start()

    def paintGL(self):
        try:
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            gl.glMatrixMode(gl.GL_PROJECTION)
            gl.glLoadIdentity()
            x, y, width, height = gl.glGetDoublev(gl.GL_VIEWPORT)
            glu.gluPerspective(
                45,  # field of view in degrees
                width / float(height or 1),  # aspect ratio
                .25,  # near clipping plane
                200,  # far clipping plane
            )
            gl.glMatrixMode(gl.GL_MODELVIEW)
            gl.glLoadIdentity()
            gl.glTranslated(0.0, 0.0, -10.0)
            self.rotation += 1
            print(self.rotation)
            gl.glRotate(self.rotation, 1, 0, 0)  # works only once for some reason?
            gl.glCallList(self.object)
        except Exception as exc:
            print(exc)
            pass

    def initializeGL(self):
        try:
            # making an example cube
            self.object = gl.glGenLists(1)
            gl.glNewList(self.object, gl.GL_COMPILE)
            gl.glBegin(gl.GL_QUADS)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(1.0, 1.0, -1.0)
            gl.glVertex3f(-1.0, 1.0, -1.0)
            gl.glVertex3f(-1.0, 1.0, 1.0)
            gl.glVertex3f(1.0, 1.0, 1.0)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(1.0, -1.0, 1.0)
            gl.glVertex3f(-1.0, -1.0, 1.0)
            gl.glVertex3f(-1.0, -1.0, -1.0)
            gl.glVertex3f(1.0, -1.0, -1.0)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(1.0, 1.0, 1.0)
            gl.glVertex3f(-1.0, 1.0, 1.0)
            gl.glVertex3f(-1.0, -1.0, 1.0)
            gl.glVertex3f(1.0, -1.0, 1.0)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(1.0, -1.0, -1.0)
            gl.glVertex3f(-1.0, -1.0, -1.0)
            gl.glVertex3f(-1.0, 1.0, -1.0)
            gl.glVertex3f(1.0, 1.0, -1.0)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(-1.0, 1.0, 1.0)
            gl.glVertex3f(-1.0, 1.0, -1.0)
            gl.glVertex3f(-1.0, -1.0, -1.0)
            gl.glVertex3f(-1.0, -1.0, 1.0)

            gl.glColor3f(0.0, 1.0, 0.0)
            gl.glVertex3f(1.0, 1.0, -1.0)
            gl.glVertex3f(1.0, 1.0, 1.0)
            gl.glVertex3f(1.0, -1.0, 1.0)
            gl.glVertex3f(1.0, -1.0, -1.0)

            gl.glEnd()
            gl.glEndList()

            gl.glEnable(gl.GL_CULL_FACE)
        except Exception as exc:
            print(exc)
            pass


def main():
    app = QtWidgets.QApplication(sys.argv)
    window = Ui()
    window.show()
    app.exec_()


main()

.ui 파일 코드

이것은 작동하지 않는 부분입니다. self.rotation이 매번 증가 paintGl()하므로 glRotate()큐브가 회전 할 것으로 예상되지만 어떤 이유로 든 그렇지 않습니다.

Rabbid76

문제는 타이머 이벤트입니다.

self.GLtimer.timeout.connect(self.openGLWidget.paintGL)

.paintGL직접 전화하는 것은 권장되지 않습니다 . OpenGL은 아무것도 그릴 수 없으며 OpenGL Context 는 그리기 전후에 최신 상태로 만들어야하며 창을 업데이트해야합니다. 첫 번째 호출 .paintGL은 프레임 워크에 의해 수행 되기 때문에 초기 드로잉을 볼 수 있습니다 . 타이머 이벤트에서 발생하는 다음 호출은 유효한 출력을 생성하지 않습니다. 을 호출해야합니다 .update(). 그러면 컨텍스트가 현재 상태가되고 다음과 같이 트리거 .paintGL()됩니다.

class Ui(QtWidgets.QWidget):
    def __init__(self):

        # [...]

        self.GLtimer = QTimer()
        self.GLtimer.setInterval(100)
        self.GLtimer.timeout.connect(self.redraw) 
        self.GLtimer.start()

    def redraw(self):
        # updated the widget - triggers paintGL to be called
        self.openGLWidget.update()

애니메이션은 원래 코드에 의해 생성됩니다. 단,에서 선 그리기 모드로 전환했습니다 glPolygonMode.

gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE)

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관