如何解决使用自定义QSurfaceFormat时PySide2 OpenGL错误
我正在使用QSurfaceFormat
来明确定义 OpenGL Core配置文件并设置次要/主要版本。事实是,自定义表面格式的分配给我以下错误:
Traceback (most recent call last):
File "/home/artem/PycharmProjects/PolyEdit3D/PolyEdit3D/Widgets/PlyViewport.py",line 22,in initializeGL
gl.glEnable(gl.GL_COLOR_BUFFER_BIT)
File "/home/artem/.local/lib/python3.7/site-packages/OpenGL/platform/baseplatform.py",line 415,in __call__
return self( *args,**named )
File "src/errorchecker.pyx",line 58,in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError
OpenGL.error.GLError: GLError(
err = 1280,description = b'invalid enumerant',baseOperation = glEnable,cArguments = (GL_COLOR_BUFFER_BIT,)
)
Traceback (most recent call last):
File "/home/artem/PycharmProjects/PolyEdit3D/PolyEdit3D/Widgets/PlyViewport.py",line 69,in paintGL
gl.glDrawElements(gl.GL_TRIANGLES,6,gl.GL_UNSIGNED_INT,ctypes.c_void_p(0))
File "src/latebind.pyx",line 39,in OpenGL_accelerate.latebind.LateBind.__call__
File "src/wrapper.pyx",line 318,in OpenGL_accelerate.wrapper.Wrapper.__call__
File "src/wrapper.pyx",line 311,in OpenGL_accelerate.wrapper.Wrapper.__call__
File "/home/artem/.local/lib/python3.7/site-packages/OpenGL/platform/baseplatform.py",in OpenGL_accelerate.errorchecker._ErrorChecker.glCheckError
OpenGL.error.GLError: GLError(
err = 1282,description = b'invalid operation',baseOperation = glDrawElements,pyArgs = (
GL_TRIANGLES,GL_UNSIGNED_INT,c_void_p(None),),cArgs = (
GL_TRIANGLES,cArguments = (
GL_TRIANGLES,)
)
您会看到gl.glEnable(gl.GL_COLOR_BUFFER_BIT)
和其他简单内容中存在错误。如果不指定QSurfaceFormat
,所有内容都会像超级按钮一样。
这是我的表面格式类:
class GLSurfaceFormat(QtGui.QSurfaceFormat):
def __init__(self):
super(GLSurfaceFormat,self).__init__()
self.__initSurface()
def __initSurface(self):
self.setRenderableType(QtGui.QSurfaceFormat.OpenGL)
self.setMinorVersion(3)
self.setMajorVersion(4)
self.setProfile(QtGui.QSurfaceFormat.CoreProfile)
self.setColorSpace(QtGui.QSurfaceFormat.sRGBColorSpace)
self.setSwapBehavior(QtGui.QSurfaceFormat.DoubleBuffer)
这是我的分配方式:
QApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
QSurfaceFormat.setDefaultFormat(GLSurfaceFormat())
app = QApplication(sys.argv)
...
您能告诉我,QSurfaceFormat
使用中是否有任何错误,或者还有其他问题?
!UPDATE! 这是一个简单的示例,您可以在其中重现相同的行为:
from PySide2 import QtCore,QtGui,QtWidgets
from OpenGL import GL as gl
from OpenGL.GL.shaders import compileProgram,compileShader
import numpy as np
import ctypes
import sys
import glm
class PlyViewportWidget(QtWidgets.QOpenGLWidget):
def __init__(self):
super(PlyViewportWidget,self).__init__(parent=None)
self.vao = None
self.vbo = None
self.ebo = None
self.shaderProg = None
self.isWireframe = False
def initializeGL(self):
gl.glEnable(gl.GL_COLOR_BUFFER_BIT)
gl.glClearColor(0.4,0.4,1)
with open("fragment.glsl",'r') as f:
fragment = compileShader(f.read(),gl.GL_FRAGMENT_SHADER)
with open("vertex.glsl","r") as f:
vertex = compileShader(f.read(),gl.GL_VERTEX_SHADER)
self.shaderProg = compileProgram(vertex,fragment)
vertices = np.array(
[
0.5,0.5,0.0,-0.5,0.0
],dtype=ctypes.c_float
)
indices = np.array(
[
0,1,3,2,3
],dtype=ctypes.c_uint
)
self.vbo = gl.glGenBuffers(1)
self.ebo = gl.glGenBuffers(1)
gl.glBindBuffer(gl.GL_ARRAY_BUFFER,self.vbo)
gl.glBufferData(gl.GL_ARRAY_BUFFER,vertices.nbytes,vertices,gl.GL_STATIC_DRAW)
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER,self.ebo)
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER,indices.nbytes,indices,gl.GL_STATIC_DRAW)
gl.glEnableVertexAttribArray(0)
gl.glVertexAttribPointer(0,gl.GL_FLOAT,gl.GL_FALSE,3 * ctypes.sizeof(ctypes.c_float),ctypes.c_void_p(0))
gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0)
gl.glBindVertexArray(0)
gl.glUseProgram(self.shaderProg)
def paintGL(self):
gl.glClearColor(0.4,1.0)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
trans = self.getTransformMatrix()
#u_transform = gl.glGetUniformLocation(self.shaderProg,"u_transform")
#gl.glUniformMatrix4fv(u_transform,u_transform)
gl.glBindVertexArray(self.vao)
gl.glDrawElements(gl.GL_TRIANGLES,ctypes.c_void_p(0))
def resizeGL(self,w:int,h:int):
gl.glViewport(0,w,h)
def keyPressEvent(self,event:QtGui.QKeyEvent):
self.makeCurrent()
if event.key() == QtCore.Qt.Key_Z and not self.isWireframe:
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_LINE)
self.isWireframe = True
self.update()
elif event.key() == QtCore.Qt.Key_Z and self.isWireframe:
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_FILL)
self.isWireframe = False
self.update()
event.accept()
def getTransformMatrix(self):
return glm.rotate(glm.mat4(1.0),glm.radians(90.0),glm.vec3(1.0,0.0))
class GLSurfaceFormat(QtGui.QSurfaceFormat):
def __init__(self):
super(GLSurfaceFormat,self).__init__()
self.__initSurface()
def __initSurface(self):
self.setRenderableType(QtGui.QSurfaceFormat.OpenGL)
self.setMinorVersion(3)
self.setMajorVersion(4)
self.setProfile(QtGui.QSurfaceFormat.CoreProfile)
self.setColorSpace(QtGui.QSurfaceFormat.sRGBColorSpace)
self.setSwapBehavior(QtGui.QSurfaceFormat.DoubleBuffer)
if __name__ == '__main__':
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseDesktopOpenGL)
# Uncomment to get this damn error!!!
#QtGui.QSurfaceFormat.setDefaultFormat(GLSurfaceFormat())
app = QtWidgets.QApplication(sys.argv)
window = PlyViewportWidget()
window.show()
sys.exit(app.exec_())
vertex.glsl
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos,1.0);
}
fragment.glsl
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f,0.5f,0.2f,1.0f);
}
解决方法
col_list
不是glEnable
的有效枚举常量,但它是glClear
的适当参数。
在glClearColor
设置了清晰的颜色之后,调用GL_COLOR_BUFFER_BIT
:
glClear
您错过了创建命名为Vertex Array Object的操作:
class PlyViewportWidget(QtWidgets.QOpenGLWidget):
# [...]
def initializeGL(self):
#gl.glEnable(gl.GL_COLOR_BUFFER_BIT) <---- DELETE
gl.glClearColor(0.4,0.4,1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT) # <---- ADD
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。