[英]glReadPixels is showing error with PyQt5. with GLUT Window it is working properly
我正在開發具有OpenGL窗口的軟件。 我正在使用PyQt5
創建軟件的GUI,對於opengGL窗口,我正在使用QOpengGLWidget
,對於對象選擇,我正在使用模板 緩沖區,並在以下mousePressEvent(self, event)
函數上讀取STENCIL_INDEX :
id = glReadPixels(event.x(), self.height - event.y() - 1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)
但是當我使用Qt5 GUI並顯示以下錯誤時,此方法不起作用:
Traceback (most recent call last):
File "/home/akv26/Desktop/internProject/Main/opengl.py", line 92, in mousePressEvent
val = glReadPixels(event.x(), self.height - event.y() - 1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)
File "/home/akv26/.local/lib/python3.7/site-packages/OpenGL/GL/images.py", line 371, in glReadPixels
imageData
File "/home/akv26/.local/lib/python3.7/site-packages/OpenGL/platform/baseplatform.py", line 402, in __call__
return self( *args, **named )
File "/home/akv26/.local/lib/python3.7/site-packages/OpenGL/error.py", line 232, in glCheckError
baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glReadPixels,
cArguments = (
183,
228,
1,
1,
GL_DEPTH_COMPONENT,
GL_FLOAT,
array([[0.]], dtype=float32),
)
)
Aborted (core dumped)
這是我的自定義QOpenGLWidget
的代碼:
import sys
from PyQt5.QtWidgets import QOpenGLWidget
from PyQt5.QtCore import QSize, Qt
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from math import *
class MyGLWidget(QOpenGLWidget):
def initializeGL(self):
glutInit()
glClearColor(1.0, 0.5, 0.2, 0.5)
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_LIGHT0)
glEnable(GL_LIGHT1)
glEnable(GL_NORMALIZE)
glShadeModel(GL_SMOOTH)
def resizeGL(self, w, h):
self.height=h
if h==0:
h=1
ratio = w * 1.0 / h
# Use the Projection Matrix
glMatrixMode(GL_PROJECTION)
# Reset Matrix
glLoadIdentity()
# Set the viewport to be the entire window
glViewport(0, 0, w, h)
# Set the correct perspective.
gluPerspective(45.0, ratio, 0.1, 100.0)
# Get Back to the Modelview
glMatrixMode(GL_MODELVIEW)
def paintGL(self):
glClearStencil(0)
glClear(GL_STENCIL_BUFFER_BIT)
glEnable(GL_STENCIL_TEST)
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)
ambientColor = [0.2,0.2,0.2,1.0]
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor)
lightColor0 = [0.5,0.5,0.5,1.0]
lightPos0 = [0, 0, -10.0, 1.0]
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0)
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0)
lightColor1 = [0.5, 0.2, 0.2, 1.0]
lightPos1 = [-1.0, 0.5, 0.5, 0.0]
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1)
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
gluLookAt(-5, 5, -5, 0, 0, 0, 0.0, 1.0, 0.0)
self.drawSome()
def drawSome(self):
glStencilFunc(GL_ALWAYS, 1, -1)
glBegin(GL_QUADS)
glColor3f(0.0, 0.5, 0.0)
glNormal3f(0,0,-1)
glVertex3f(-1,-1,0)
glVertex3f(-1,1,0)
glVertex3f(1,1,0)
glVertex3f(1,-1,0)
glEnd()
glTranslatef(0,0,0)
glColor3f(0.5,0,0)
glStencilFunc(GL_ALWAYS, 2, -1)
glutSolidCube(1.0)
def mousePressEvent(self, event):
id = glReadPixels(event.x(), self.height - event.y() - 1, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_INT)
print(id)
當我將其與GLUT窗口一起使用時,如下所示:
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from math import *
import numpy as np
window_width=0
window_height=0
def changeSize(w, h):
global window_height, window_width
window_width=w
window_height=h
# Prevent a divide by zero, when window is too short
# (you cant make a window of zero width).
if h==0:
h=1
ratio = w * 1.0 / h
# Use the Projection Matrix
glMatrixMode(GL_PROJECTION)
# Reset Matrix
glLoadIdentity()
# Set the viewport to be the entire window
glViewport(0, 0, w, h)
# Set the correct perspective.
gluPerspective(45.0, ratio, 0.1, 100.0)
# Get Back to the Modelview
glMatrixMode(GL_MODELVIEW)
def drawSome():
glStencilFunc(GL_ALWAYS, 1, -1)
glBegin(GL_QUADS)
glColor3f(0.0, 0.5, 0.0)
glNormal3f(0,0,-1)
glVertex3f(-1,-1,0)
glVertex3f(-1,1,0)
glVertex3f(1,1,0)
glVertex3f(1,-1,0)
glEnd()
glTranslatef(0,0,0)
glColor3f(0.5,0,0)
glStencilFunc(GL_ALWAYS, 2, -1)
glutSolidCube(1.0)
def renderScene():
glClearStencil(0)
glClear(GL_STENCIL_BUFFER_BIT)
glEnable(GL_STENCIL_TEST)
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)
ambientColor = [0.2,0.2,0.2,1.0]
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor)
lightColor0 = [0.5,0.5,0.5,1.0] #Color
lightPos0 = [0, 0, -10.0, 1.0]
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0)
glLightfv(GL_LIGHT0, GL_POSITION, lightPos0)
lightColor1 = [0.5, 0.2, 0.2, 1.0]
lightPos1 = [-1.0, 0.5, 0.5, 0.0]
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor1)
glLightfv(GL_LIGHT1, GL_POSITION, lightPos1)
# Clear Color and Depth Buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# Reset transformations
glLoadIdentity()
# Set the camera
# gluLookAt(x, 1.0, z, x+lx, 1.0, z+lz, 0.0, 1.0, 0.0)
gluLookAt(-5, 5, -5, 0, 0, 0, 0.0, 1.0, 0.0)
drawSome()
glutSwapBuffers()
def mouse(button, state, x, y):
global window_height
id = glReadPixels(x, window_height - y - 1, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_INT)
print(id[0][0])
if __name__ == '__main__':
glutInit()
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA)
# glutInitWindowPosition(100,100)
glutInitWindowSize(320,320)
glutCreateWindow("Lighthouse3D - GLUT Tutorial")
glClearColor(1.0, 0.5, 0.2, 0.5)
# register callbacks
glutDisplayFunc(renderScene)
glutReshapeFunc(changeSize)
glutMouseFunc(mouse)
# glutTimerFunc(0, Timer, 0)
# here are the new entries
glutIgnoreKeyRepeat(1)
# OpenGL init
glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_LIGHT0)
glEnable(GL_LIGHT1)
glEnable(GL_NORMALIZE)
glShadeModel(GL_SMOOTH)
glutMainLoop()
如何使用QT5 GUI解決問題?
glReadPixels
要求渲染上下文是線程上的當前上下文。 Qt會自動進行上下文管理,並且有據可查的是,在名為…GL
的方法之外,上下文可能不是當前的。
您必須在這些方法之外明確地使上下文成為當前上下文,為此Qt OpenGL類提供了方法makeCurrent
和doneCurrent
。 調用glReadPixels
來調用這些函數; 確保檢查makeCurrent
成功,因為上下文可能已經在其他線程中成為當前上下文。
我懷疑調用glReadPixels
時當前沒有OpenGL上下文。 你是mousePressEvent
可能應該調用QOpenGLWidget::makeCurrent
...
def mousePressEvent(self, event):
# Make the OpenGL context associated with this `QOpenGLWidget` current. and dont forget self
self.makeCurrent()
id = glReadPixels(event.x(), self.height - event.y() - 1, 1, 1, GL_STENCIL_INDEX, GL_UNSIGNED_INT)
print(id)
self.doneCurrent()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.