Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

minimalist PyOpenGL example in PyQt5 application

I am learning PyOpenGL and use it in PyQt5 application. I am trying to convert some of my old simple examples from C++/Qt to Python. The following example should draw white triangle on black background. At least it does in the corresponding C++/Qt code. But it does nothing, just a black window. Any ideas what I am missing? Note that I need the 'modern' approach using shaders (however according to my knowledge - I may be wrong - the following code should just use a default trivial shader, i.e white color in 2D) instead of all that oldish glBegin(), glEnd().

import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication


class OpenGLWidget(QOpenGLWidget):

    def initializeGL(self):
        vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)

        bufferId = GL.glGenBuffers(1)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
        GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.size, vertices, GL.GL_STATIC_DRAW)

        GL.glEnableVertexAttribArray(0)
        GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, 0)

    def paintGL(self):
        GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)


app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()
like image 732
V.K. Avatar asked Jun 27 '17 13:06

V.K.


1 Answers

OK, finally, I found my errors:

GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)  # nbytes instead of size

and

GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)  # i.e. None instead of 0

The complete minimalistic example is as follows:

import numpy as np
from OpenGL import GL
from PyQt5.QtWidgets import QOpenGLWidget, QApplication


class OpenGLWidget(QOpenGLWidget):

    def initializeGL(self):
        vertices = np.array([0.0, 1.0, -1.0, -1.0, 1.0, -1.0], dtype=np.float32)

        bufferId = GL.glGenBuffers(1)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, bufferId)
        GL.glBufferData(GL.GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL.GL_STATIC_DRAW)

        GL.glEnableVertexAttribArray(0)
        GL.glVertexAttribPointer(0, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, None)

    def paintGL(self):
        GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)


app = QApplication([])
widget = OpenGLWidget()
widget.show()
app.exec_()

Note that this however does not follow the 'best practice' - you should be using shaders and VAO! This code is really just the shortest possible...

like image 123
V.K. Avatar answered Sep 21 '22 00:09

V.K.