PyOpenGL 读取回缓冲区颜色
PyOpenGL reading back buffer color
我的 Pyqt5 window 中有一个球体由 PyOpenGL 绘制:
然后,我使用 self.swapBuffers() 切换到后台缓冲区,然后再次绘制到后台缓冲区,但颜色不同。
然后单击鼠标,我正在尝试读取后台缓冲区颜色,
但它给了我前端缓冲区的值。这里的问题,是否可以从后面读取值,如果可以,这里到底有什么问题?
用 link
中的答案生成的小例子
from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt5 import QtGui
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import *
from PyQt5.QtOpenGL import *
import sys
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.widget = GLWidget(self)
self.statusbar = QStatusBar()
self.statusbar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.statusbar.showMessage("Click anywhere on the QGLWidget to see a pixel's RGBA value!")
layout = QVBoxLayout()
layout.addWidget(self.widget)
layout.addWidget(self.statusbar)
layout.setContentsMargins(5, 5, 5, 5)
self.setLayout(layout)
class GLWidget(QGLWidget):
def __init__(self, parent):
QGLWidget.__init__(self, parent)
self.setMinimumSize(640, 480)
#LMB = left mouse button
#True: fires mouseMoveEvents even when not holding down LMB
#False: only fire mouseMoveEvents when holding down LMB
self.setMouseTracking(False)
def initializeGL(self):
glClearColor(0, 0, 0, 1)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
def resizeGL(self, width, height):
#glViewport is needed for proper resizing of QGLWidget
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def paintGL(self):
w, h = self.width(), self.height()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Q = gluNewQuadric()
glTranslatef(w/2, h/2, -w/2*0.1)
glColor3f(1.0, 1.0, 1.0)
gluSphere(Q, w/2*0.1, 32, 32)
glTranslatef(-w/2, -h/2, +w/2*0.1)
self.swapBuffers()
glTranslatef(w/2, h/2, -w/2*0.1)
# print(GlWidget.joint_nodes[i][1], GlWidget.joint_nodes[i][2])
glColor3f(1.0, 1.0, 0.5)
gluSphere(Q, w/2*0.1, 32, 32)
glTranslatef(-w/2, -h/2, w/2*0.1)
self.swapBuffers()
def mousePressEvent(self, event):
x, y = event.x(), event.y()
self.swapBuffers()
glReadBuffer(GL_BACK)
c= glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT)
print('c = ',c)
def mouseMoveEvent(self, event):
pass
def mouseReleaseEvent(self, event):
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle("Color Picker Demo")
window.show()
app.exec_()
以下顺序
self.swapBuffers()
glReadBuffer(GL_BACK)
c= glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT)
永远不会工作。缓冲区交换后,后台缓冲区的内容变为 undefined.
I have one sphere in my Pyqt5 window drawn by PyOpenGL. Then, I am
switching to the back buffer using self.swapBuffers()
and then draw
again to the back buffer but with a different color.
嗯,不,你没有那样做。你只渲染一次,用paintGL
结尾的self.swapBuffers()
呈现渲染内容。后台缓冲区的内容现在未定义。单击鼠标时,您再次交换缓冲区,因此未定义的内容作为前台缓冲区变得可见,后台缓冲区再次未定义,并读回。您甚至都不会尝试使用不同的颜色进行绘图。
当然 GPU 很有可能在内部使用某种交换链,因此“未定义”内容通常是先前帧的内容,而不仅仅是前一帧。
你的整个方案没有意义。 如果你想使用简单的渲染方法进行拾取,你根本不会使用SwapBuffers
。只需渲染到后台缓冲区,然后从后台缓冲区中读回。当您渲染下一帧可见时,您会再次覆盖同一个后台缓冲区的内容,最后交换缓冲区以呈现它。
我的 Pyqt5 window 中有一个球体由 PyOpenGL 绘制:
然后,我使用 self.swapBuffers() 切换到后台缓冲区,然后再次绘制到后台缓冲区,但颜色不同。
然后单击鼠标,我正在尝试读取后台缓冲区颜色,
但它给了我前端缓冲区的值。这里的问题,是否可以从后面读取值,如果可以,这里到底有什么问题?
用 link
from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt5 import QtGui
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import *
from PyQt5.QtOpenGL import *
import sys
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.widget = GLWidget(self)
self.statusbar = QStatusBar()
self.statusbar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.statusbar.showMessage("Click anywhere on the QGLWidget to see a pixel's RGBA value!")
layout = QVBoxLayout()
layout.addWidget(self.widget)
layout.addWidget(self.statusbar)
layout.setContentsMargins(5, 5, 5, 5)
self.setLayout(layout)
class GLWidget(QGLWidget):
def __init__(self, parent):
QGLWidget.__init__(self, parent)
self.setMinimumSize(640, 480)
#LMB = left mouse button
#True: fires mouseMoveEvents even when not holding down LMB
#False: only fire mouseMoveEvents when holding down LMB
self.setMouseTracking(False)
def initializeGL(self):
glClearColor(0, 0, 0, 1)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
def resizeGL(self, width, height):
#glViewport is needed for proper resizing of QGLWidget
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def paintGL(self):
w, h = self.width(), self.height()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
Q = gluNewQuadric()
glTranslatef(w/2, h/2, -w/2*0.1)
glColor3f(1.0, 1.0, 1.0)
gluSphere(Q, w/2*0.1, 32, 32)
glTranslatef(-w/2, -h/2, +w/2*0.1)
self.swapBuffers()
glTranslatef(w/2, h/2, -w/2*0.1)
# print(GlWidget.joint_nodes[i][1], GlWidget.joint_nodes[i][2])
glColor3f(1.0, 1.0, 0.5)
gluSphere(Q, w/2*0.1, 32, 32)
glTranslatef(-w/2, -h/2, w/2*0.1)
self.swapBuffers()
def mousePressEvent(self, event):
x, y = event.x(), event.y()
self.swapBuffers()
glReadBuffer(GL_BACK)
c= glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT)
print('c = ',c)
def mouseMoveEvent(self, event):
pass
def mouseReleaseEvent(self, event):
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.setWindowTitle("Color Picker Demo")
window.show()
app.exec_()
以下顺序
self.swapBuffers() glReadBuffer(GL_BACK) c= glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT)
永远不会工作。缓冲区交换后,后台缓冲区的内容变为 undefined.
I have one sphere in my Pyqt5 window drawn by PyOpenGL. Then, I am switching to the back buffer using
self.swapBuffers()
and then draw again to the back buffer but with a different color.
嗯,不,你没有那样做。你只渲染一次,用paintGL
结尾的self.swapBuffers()
呈现渲染内容。后台缓冲区的内容现在未定义。单击鼠标时,您再次交换缓冲区,因此未定义的内容作为前台缓冲区变得可见,后台缓冲区再次未定义,并读回。您甚至都不会尝试使用不同的颜色进行绘图。
当然 GPU 很有可能在内部使用某种交换链,因此“未定义”内容通常是先前帧的内容,而不仅仅是前一帧。
你的整个方案没有意义。 如果你想使用简单的渲染方法进行拾取,你根本不会使用SwapBuffers
。只需渲染到后台缓冲区,然后从后台缓冲区中读回。当您渲染下一帧可见时,您会再次覆盖同一个后台缓冲区的内容,最后交换缓冲区以呈现它。