我正在尝试使用计算着色器使用OpenGL渲染图像。我创建了一个计算着色器并为其编程,然后创建了一个顶点着色器和片段着色器,以及一个为它们编写的程序。然后我创建一个纹理和两个三角形,并在三角形上渲染纹理。到目前为止,我一直无法让着色器正确地执行任何操作,因为glCompileShader
似乎没有捕捉到着色器编译不正确时的情况,所以我无法判断哪里出了问题。我在每个编译和链接步骤之后添加了glGetError
调用,以查看问题可能是什么,但它们都没有抛出错误;所发生的只是glUseProgram
引发invalid operation
错误。
RenderShaderSource:
# version 460 core
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(rgba32f, binding = 0) uniform image2D screen;
void main()
}
Vertex ShaderSource:
# version 460 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 uvs;
out vec2 UVs;
void main()
{
gl_Position = vec4(pos.x, pos.y, pos.z, 1.0);
UVs = uvs;
}
FragmentShaderSource:
# version 460 core
out vec4 FragColor;
uniform sampler2D screen;
in vec2 UVs;
void main()
{
FragColor = texture(screen, UVs);
}
Python代码(删除多余的注解和不相关的代码):
class GLWidget(QOpenGLWidget):
width = 100
height = 100
def initializeGL(self):
print('--initializeGL--')
print('GL version', glGetString(GL_VERSION))
# Render shader
renderShader = glCreateShader(GL_COMPUTE_SHADER)
glShaderSource(renderShader, renderShaderSource)
glCompileShader(renderShader)
status = glGetError()
if status != GL_NO_ERROR: raise RuntimeError('Error {} compiling renderShader'.format(status))
# Render program
renderProgram = glCreateProgram()
glAttachShader(renderProgram, renderShader)
glLinkProgram(renderProgram)
status = glGetError()
if status != GL_NO_ERROR: raise RuntimeError('Error {} linking renderProgram'.format(status))
# Vertex shader
vertexShader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertexShader, vertexShaderSource)
glCompileShader(vertexShader)
status = glGetError()
if status != GL_NO_ERROR: raise RuntimeError('Error {} compiling vertexShader'.format(status))
# Fragment shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragmentShader, fragmentShaderSource)
glCompileShader(fragmentShader)
status = glGetError()
if status != GL_NO_ERROR: raise RuntimeError('Error {} compiling fragmentShader'.format(status))
# Display program
displayProgram = glCreateProgram()
glAttachShader(displayProgram, vertexShader)
glAttachShader(displayProgram, fragmentShader)
glLinkProgram(displayProgram)
status = glGetError()
if status != GL_NO_ERROR: raise RuntimeError('Error {} linking displayProgram'.format(status))
# Texture to render to
screenTex = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, screenTex)
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, self.width, self.height)
glBindImageTexture(0, screenTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F)
# Shape to render texture on
self.vertices = numpy.array([
-1.0, -1.0, 0.0, 0.0, 0.0,
-1.0, 1.0, 0.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0, 1.0,
1.0, -1.0, 0.0, 1.0, 0.0
], dtype='float32')
# Buffers for rendering shape
vertexArray = glGenVertexArrays(1)
vertexBuffer = glGenBuffers(1)
glBindVertexArray(vertexArray)
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer)
glBufferData(GL_ARRAY_BUFFER, 4 * len(self.vertices), self.vertices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, False, 4 * 3, None)
glEnableVertexAttribArray(0)
# Unbind from the vertex buffer and vertex array
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
self.renderProgram = renderProgram
self.displayProgram = displayProgram
self.vertexArray = vertexArray
self.vertexBuffer = vertexBuffer
def resizeGL(self, width, height):
print('--resizeGL--')
self.width = width
self.height = height
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-1, 1, 1, -1, -1, 1)
def paintGL(self):
print('--paintGL--')
# Run render portion
glUseProgram(self.renderProgram)
glDispatchCompute(self.width, self.height, 1)
glMemoryBarrier(GL_ALL_BARRIER_BITS)
# Run display portion
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear(GL_COLOR_BUFFER_BIT)
glUseProgram(self.displayProgram)
glBindVertexArray(self.vertexArray)
glDrawArrays(GL_TRIANGLES, 0, 6)
很明显,我的计算着色器(请参见renderShaderSource)是这个场景中的问题,我的意思是它有不匹配的{}东西。但当我运行程序时,glUseProgram
错误而不是glGetError
:
--initUI--
--initializeGL--
GL version b'4.6 (Compatibility Profile) Mesa 21.2.6'
--resizeGL--
--paintGL--
Traceback (most recent call last):
File "gl.py", line 146, in paintGL
glUseProgram(self.renderProgram)
File "/home/aweso/.local/lib/python3.8/site-packages/OpenGL/platform/baseplatform.py", line 415, in __call__
return self( *args,**named )
File "/home/aweso/.local/lib/python3.8/site-packages/OpenGL/error.py", line 230, in glCheckError
raise self._errorClass(
OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glUseProgram,
cArguments = (2,)
)
--paintGL--
Traceback (most recent call last):
File "gl.py", line 146, in paintGL
glUseProgram(self.renderProgram)
File "/home/aweso/.local/lib/python3.8/site-packages/OpenGL/error.py", line 230, in glCheckError
raise self._errorClass(
OpenGL.error.GLError: GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glUseProgram,
cArguments = (2,)
)
为什么所有glGetError
调用都没有捕获计算着色器未能编译的情况?
在Ubuntu 20.04、集成了GPU的英特尔酷睿i3-1005G1上运行的Python3.8。OpenGL 4.6 MESA 21.2.6.OpenGL视区是一个PyQt6 QOpenGLWidget
1条答案
按热度按时间ua4mk5z41#
无法使用
glGetError
获取着色器编译错误。您必须调用glGetShaderiv
/glGetShaderInfoLog
来获取编译错误。例如:可以使用
glGetProgramiv
/glGetProgramInfoLog
获取程序链接错误。例如:我也推荐Debug Output。例如: