Я застрял, пытаясь изменить данные в VBO.
Я настроил сцену с двумя примитивами Triangle, используя VBO через вспомогательный класс python OpenGL.arrays.vbo
. Это сработало.
Затем я хочу изменить данные (в приведенном ниже минимальном примере просто сдвинуть одну вершину при нажатии кнопки), которые я не могу заставить работать. Я не уверен, правильно ли я использую VBO или есть какая-то тривиальность, блокирующая перерисовку на стороне PyQt5.
Ниже приведен полный минимальный пример, важные вещи выполняются в функциях-членах initializeGL
, paintGL
и shift
.
Внутри GLWidget.shift
я пробовал разные подходы, следуя документам и этому ответу а> безуспешно. Любая помощь приветствуется.
#!/usr/bin/env python
import ctypes
import sys
import numpy as np
import OpenGL.arrays.vbo as glvbo
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import (QApplication, QHBoxLayout, QOpenGLWidget,
QWidget, QPushButton)
import OpenGL.GL as gl
class Window(QWidget):
def __init__(self):
super(Window, self).__init__()
self.glWidget = GLWidget()
button = QPushButton('shift', self)
button.clicked.connect(self.glWidget.shift)
layout = QHBoxLayout()
layout.addWidget(self.glWidget)
layout.addWidget(button)
self.setLayout(layout)
class GLWidget(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.object = None
def minimumSizeHint(self):
return QSize(400, 400)
def initializeGL(self):
gl.glClearColor(0., 0., 0., 0.)
# a red and a green triangle
self.vertices = np.array([
# <- x,y,z -----> <- r,g,b -->
-0.5, -0.2, 0.0, 1.0, 0.0, 0.0,
0.5, -0.5, 0.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.0, 1.0, 0.0, 0.0,
0.4, -0.2, 0.0, 0.0, 1.0, 0.0,
1.4, -0.5, 0.0, 0.0, 1.0, 0.0,
1.4, 0.5, 0.0, 0.0, 1.0, 0.0,
], 'f')
self.vbo = glvbo.VBO(self.vertices)
self.vbo.bind()
self.object = gl.glGenLists(1)
gl.glNewList(self.object, gl.GL_COMPILE)
gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
gl.glEnableClientState(gl.GL_COLOR_ARRAY)
buffer_offset = ctypes.c_void_p
stride = (3+3)*self.vertices.itemsize
gl.glVertexPointer(3, gl.GL_FLOAT, stride, None)
gl.glColorPointer(3, gl.GL_FLOAT, stride, buffer_offset(12))
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
gl.glDisableClientState(gl.GL_COLOR_ARRAY)
gl.glEndList()
gl.glShadeModel(gl.GL_FLAT)
def paintGL(self):
gl.glClear(
gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
gl.glLoadIdentity()
gl.glRotated(50.0, 0.0, 1.0, 0.0)
gl.glCallList(self.object)
def resizeGL(self, width, height):
side = min(width, height)
if side < 0:
return
gl.glViewport((width - side) // 2, (height - side) // 2, side,
side)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(-1., +1., -1., +1., -100.0, 100.0)
gl.glMatrixMode(gl.GL_MODELVIEW)
def shift(self):
# shift y-position of one vertex
self.vertices[1] += 10.3
assert self.vertices is self.vbo.data
# version 1
# self.vbo.implementation.glBufferSubData(self.vbo.target, 0, self.vbo.data)
# version 2
# self.vbo[:] = self.vertices[:]
# self.vbo.bind()
# self.vbo.copy_data()
# version 2b (use slice)
# self.vbo[1:2] = self.vertices[1:2]
# self.vbo.bind()
# self.vbo.copy_data()
# version 3
self.vbo.set_array(self.vertices)
self.vbo.bind()
self.vbo.copy_data()
self.update()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Код работает на Ubuntu 18.04
машине под python 3.6
с
Vendor: Intel Open Source Technology Center
Renderer: Mesa DRI Intel(R) HD Graphics 5500 (Broadwell GT2)
OpenGL Version: 3.0 Mesa 19.2.8
Shader Version: 1.30