Как настроить PyOpenGL с PyQt5? - PullRequest
0 голосов
/ 11 февраля 2020

Я хочу создать несколько трехмерных математических проектов с python. Лучший способ визуализировать это с помощью PyOpenGL. Я также хочу запустить его в PyQt5, чтобы у меня был графический интерфейс рядом с рендером. Вся информация, которую я могу найти, использует PyGame или QtDesigner. Я хотел бы работать без QtDesigner. Кто-нибудь знает, где я мог бы найти учебник о том, как это настроить?

РЕДАКТИРОВАТЬ:

Мне удалось сделать некоторые веб-исследования. Я нашел следующий код на https://pythonprogramming.net/community/37/Cube%20rotation%20with%20pyopengl%20and%20pyqt/, где автор просит помощи относительно того, что он не работает. он говорит об этом следующее:

Я очень новичок в python. У меня проблема с моим кодом, это очень простой вращающийся куб. У меня нет проблем с этим кодом куба с экраном pygame, но когда я использую его с pyqt (или виджетами Qt designer), он запускается, но ничего не показывает !!!

Я скопировал его код в мою IDe, затем сохранил его как cubes.py. Я открыл экземпляр CMD в каталоге файла и вызвал его. Он открыл крошечное черное окно Qt в середине экрана: the result of the code

Когда я пытаюсь изменить размер окна, перетаскивая угол, он бросает глубину traceback:

  File "C:\Users\aweso\Documents\Python\cubes\cubes.py", line 1, in <module>
    from OpenGL.GL import *
ModuleNotFoundError: No module named 'OpenGL'

C:\Users\aweso\Documents\Python\cubes>cubes.py
Traceback (most recent call last):
  File "C:\Users\aweso\Documents\Python\cubes\cubes.py", line 56, in paintGL
    glEnd()
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\latebind.py", line 63, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\GL\exceptional.py", line 45, in glEnd
    return baseFunction( )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\platform\baseplatform.py", line 415, in __call__
    return self( *args, **named )
  File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\lib\site-packages\OpenGL\error.py", line 234, in glCheckError
    baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
        err = 1280,
        description = b'invalid enumerant',
        baseOperation = glEnd,
        cArguments = ()
)

Вот его код, неизмененный:

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL import *
from PyQt5.QtOpenGL import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
import sys,time

class MainWindow(QGLWidget):
    def __init__(self):
        super(MainWindow, self).__init__()

        self.widget = glWidget(self)
        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.widget)
        self.setLayout(mainLayout)

class glWidget(QGLWidget):

    def __init__(self, parent):
        QGLWidget.__init__(self, parent)

        #self.setMinimumSize(400, 400)

        self.verticies = (
            (1,-1,-1),
            (1,1,-1),
            (-1,1,-1),
            (-1,-1,-1),
            (1,-1,1),
            (1,1,1),
            (-1,-1,1),
            (-1,1,1))
        self.edges = (
            (0,1),
            (0,3),
            (0,4),
            (2,1),
            (2,3),
            (2,7),
            (6,3),
            (6,4),
            (6,7),
            (5,1),
            (5,4),
            (5,7))

    def paintGL(self):
        while True:
            #glRotatef(1,3,1,1)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glBegin(GL_LINE)
            for self.edge in self.edges:
                for self.vertex in self.edge:
                    glVertex3fv(self.verticies[self.vertex])
            glEnd()
            glFlush()
            time.sleep(1)       

    def resizeGL(self, w, h):
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(-50, 50, -50, 50, -50.0, 50.0)
        glViewport(0, 0, w, h)

    def initializeGL(self):

        #glClearColor(0.0, 0.0, 0.0, 1.0)
        gluPerspective(45,800/600,0.1,50.0)
        glTranslatef(0.0,0.0,-5)
        glRotatef(0,0,0,0)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

1 Ответ

0 голосов
/ 11 февраля 2020

Однажды я разработал интерактивную 3D-программу, используя PyOpenGL и PyQt5. Вот шип код того времени. Я sh это может быть полезно для вас.

import sys
import math
from array import array

from OpenGL import GL

from PyQt5.QtCore import pyqtSignal, QPoint, QSize, Qt
from PyQt5.QtGui import QColor, QImage
from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QWidget)
from PyQt5.QtOpenGL import QGLWidget

from shader import ShaderProgram


class Window (QWidget):

    def __init__(self):
        super(Window, self).__init__()

        self.glWidget = GLWidget()

        mainLayout = QHBoxLayout()
        mainLayout.addWidget(self.glWidget)
        self.setLayout(mainLayout)

        self.setWindowTitle('Hello')


class GLWidget (QGLWidget):

    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

    def sizeHint(self):
        return QSize(1200, 1000)

    def initializeGL(self):
        GL.glClearColor(0.0, 0.0, 1.0, 0.0)  # it's also possible.

        GL.glEnable(GL.GL_DEPTH_TEST)
        # GL.glEnable(GL.GL_VERTEX_ARRAY)

        self._createVertexBuffer()

        self.program = ShaderProgram('hello.vert', 'hello.frag')
        self.program.use()

        self.frontTexture = self._createTexture('tex.png')
        self.backTexture = self._createTexture('back-tex.jpg')

         # set texture units

        GL.glActiveTexture(GL.GL_TEXTURE0)
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.frontTexture)
        GL.glUniform1i(GL.glGetUniformLocation(self.program.getProgram(), b'frontTexture'), 0)

        GL.glActiveTexture(GL.GL_TEXTURE1)
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.backTexture)
        GL.glUniform1i(GL.glGetUniformLocation(self.program.getProgram(), b'backTexture'), 1)

    def paintGL(self):
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        self._draw()

    def resizeGL(self, width, height):
        side = min(width, height)
        if side < 0:
            return

        GL.glViewport((width - side) // 2, (height - side) // 2, side, side)

    def _createTexture(self, texFilePath):
        qImage = QImage(texFilePath)

        texture = QGLWidget.bindTexture(self, qImage, GL.GL_TEXTURE_2D, GL.GL_RGBA)

        GL.glGenerateMipmap(GL.GL_TEXTURE_2D)

        return texture

    def _createVertexBuffer(self):
        vertices = array('f', [-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0,  1.0, 0.0, -1.0, 1.0, 0.0]).tobytes()
        colors = array('f', [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0]).tobytes()
        indices = [0, 1, 2, 0, 3, 2]
        texCoords = array('f', [0.0, 0.0, 1.0, 0.0, 1.0,  1.0, 0.0, 1.0]).tobytes()

        self.vertices = vertices
        self.colors = colors
        self.indices = indices
        self.texCoords = texCoords

    def _draw(self):

        GL.glEnableVertexAttribArray(0)
        GL.glEnableVertexAttribArray(1)
        GL.glEnableVertexAttribArray(2)

        GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, self.vertices)
        GL.glVertexAttribPointer(1, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, self.colors)
        GL.glVertexAttribPointer(2, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, self.texCoords)

        GL.glDrawElements(GL.GL_TRIANGLES, 6, GL.GL_UNSIGNED_INT, self.indices)

        GL.glDisableVertexAttribArray(0)
        GL.glDisableVertexAttribArray(1)
        GL.glDisableVertexAttribArray(2)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
...