Solved Drawing a triangle using PyQt5 and OpenGL 3.3 (rewriting the Qt C++ example)
-
My current PyQt5 example does not show a window and does not give me any error messages.
This is Qt C++ example that works very good. I want to use QOpenGLBuffer in my PyQt5 code.
main.cpp
#include <QApplication> #include <QOpenGLWidget> #include <QOpenGLShaderProgram> #include <QOpenGLBuffer> class Widget : public QOpenGLWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr) : QOpenGLWidget(parent) { } private: QOpenGLShaderProgram m_program; QOpenGLBuffer m_vertPosBuffer; void initializeGL() override { glClearColor(0.5f, 0.8f, 0.7f, 1.f); resize(400, 500); const char *vertShaderSrc = "attribute vec3 aPosition;" "void main()" "{" " gl_Position = vec4(aPosition, 1.0);" "}"; const char *fragShaderSrc = "void main()" "{" " gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0);" "}"; m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, vertShaderSrc); m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragShaderSrc); m_program.link(); m_program.bind(); float vertPositions[] = { -0.5f, -0.5f, 0.f, 0.5f, -0.5f, 0.f, 0.f, 0.5f, 0.f }; m_vertPosBuffer.create(); m_vertPosBuffer.bind(); m_vertPosBuffer.allocate(vertPositions, sizeof(vertPositions)); m_program.bindAttributeLocation("aPosition", 0); m_program.setAttributeBuffer(0, GL_FLOAT, 0, 3); m_program.enableAttributeArray(0); } void paintGL() override { glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); } void resizeGL(int w, int h) override { glViewport(0, 0, w, h); } }; #include "main.moc" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
This is my trying to rewrite the code above to PyQt5. As you can see I want to rewrite it very close to Qt C++. I want to have two very similar example. But this code does not show a windows and does not show any error messages.
import sys import numpy as np from OpenGL import GL as gl from PyQt5.QtWidgets import QOpenGLWidget, QApplication from PyQt5.QtGui import (QOpenGLBuffer, QOpenGLShaderProgram, QOpenGLShader) from PyQt5.QtCore import Qt class OpenGLWidget(QOpenGLWidget): def __init__(self): super().__init__() self.setWindowTitle("Triangle, PyQt5, OpenGL ES 2.0") self.resize(300, 300) def initializeGL(self): gl.glClearColor(0.5, 0.8, 0.7, 1.0) vertShaderSrc = """ attribute vec3 aPosition; void main() { gl_Position = vec4(aPosition, 1.0); } """ fragShaderSrc = """ void main() { gl_FragColor = vec4(0.5, 0.2, 0.9, 1.0); } """ program = QOpenGLShaderProgram() program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertShaderSrc) program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragShaderSrc) program.link() program.bind() vertPositions = np.array([ -0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0], dtype=np.float32) vertPosBuffer = QOpenGLBuffer() vertPosBuffer.create() vertPosBuffer.bind() vertPosBuffer.allocate(vertPositions, len(vertPositions) * 4) program.bindAttributeLocation("aPosition", 0) program.setAttributeBuffer(0, gl.GL_FLOAT, 0, 3) program.enableAttributeArray(0) def paintGL(self): gl.glClear(gl.GL_COLOR_BUFFER_BIT) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) def main(): QApplication.setAttribute(Qt.AA_UseDesktopOpenGL) a = QApplication(sys.argv) w = OpenGLWidget() w.show() sys.exit(a.exec_()) if __name__ == "__main__": main()
-
eyllanesc solved my problem here: https://stackoverflow.com/questions/64914388/drawing-a-triangle-using-pyqt5-and-opengl-rewriting-the-qt-c-example/64915511#64915511
The problem is that the QOpenGLBuffer is a local variable that is destroyed instantly, whereas in C++ QOpenGLBuffer is an attribute of the class. The solution is to change vertPosBuffer to self.vertPosBuffer
-
eyllanesc solved my problem here: https://stackoverflow.com/questions/64914388/drawing-a-triangle-using-pyqt5-and-opengl-rewriting-the-qt-c-example/64915511#64915511
The problem is that the QOpenGLBuffer is a local variable that is destroyed instantly, whereas in C++ QOpenGLBuffer is an attribute of the class. The solution is to change vertPosBuffer to self.vertPosBuffer