在愉快地使用 PyOpenGL 一段时间后,我现在严重卡住了。我正在开发一个 Python 包,它允许我使用 GLSL 着色器和 OpenCL 程序进行图像处理,使用纹理作为将我的数据进出 GLSL 着色器和 OpenCL 程序的标准化方式。
一切正常,除了我无法成功将纹理复制到 pbo(像素缓冲区对象)中。我正在使用 pbo 将我的纹理数据输入/输出 OpenCL,这在 PyOpenCL 中运行良好且快速:我可以将我的 OpenCL 输出从它的 pbo 复制到纹理并显示它,我还可以将数据从 cpu 加载到一个公益组织。但是我绝望地试图用 GPU 上已经存在的纹理数据填充我的 pbo,这是我需要做的才能将 GLSL 着色器生成的图像加载到 OpenCL 中以进行进一步处理。
我已经阅读了两种方法:变体 1 绑定 pbo,绑定纹理并使用 glGetTexImage() 变体 2 将纹理附加到帧缓冲区对象,绑定 fbo 和 pbo 并使用 glReadPixels()
我还读到 glReadPixels() 和 glGetTexImage() 的 PyOpenGL 版本在绑定 pbo 时应该使用的“空”指针有问题,因此我使用的是 OpenGL.raw.GL 变体。
但在这两种情况下,我都会收到“无效操作”错误,我真的看不出我做错了什么。下面是我的pixelbuffer Python类的load_texture()方法的两个版本,我希望我没有把它们剥离得太远......
变体1:
def _load_texture(self, texture):
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, self.id)
glEnable(texture.target)
glActiveTexture(GL_TEXTURE0_ARB)
glBindTexture(texture.target, texture.id)
OpenGL.raw.GL.glGetTexImage(texture.target, 0, texture.gl_imageformat,
texture.gl_dtype, ctypes.c_void_p(0))
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0)
glDisable(texture.target)
变体 2:
def _load_texture(self, texture):
fbo = FrameBufferObject.from_textures([texture])
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
texture.target, texture.id, 0)
glReadBuffer(GL_COLOR_ATTACHMENT0)
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id)
glBindBuffer(GL_PIXEL_PACK_BUFFER, self.id)
OpenGL.raw.GL.glReadPixels(0, 0, self.size[0], self.size[1],
texture.gl_imageformat, texture.gl_dtype,
ctypes.c_void_p(0))
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_RECTANGLE_ARB, 0, 0)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
编辑(添加一些关于我的 pbo 的错误和初始化的信息):
我得到的变体 1 的错误是:
OpenGL.error.GLError: GLError(
err = 1282,
description = 'invalid operation',
baseOperation = glGetTexImage,
cArguments = (
GL_TEXTURE_RECTANGLE_ARB,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
c_void_p(None),
)
我正在像这样初始化我的 pbo:
self.usage = usage
if isinstance(size, tuple):
size = size[0] * size[1] * self.imageformat.planecount
bytesize = self.imageformat.get_bytesize_per_plane() * size
glBindBuffer(self.arraytype, self.id)
glBufferData(self.arraytype, bytesize, None, self.usage)
glBindBuffer(self.arraytype, 0)
'self.arraytype' 是 GL_ARRAY_BUFFER, self.usage 我已经尝试了所有可能性以防万一,但 GL_STREAM_READ 似乎最适合我的使用类型。我通常使用的大小是 1024 x 1024,4 个平面,每个平面 1 个字节,因为它是无符号整数。这在从主机传输像素数据时效果很好。
我也在 Kubuntu 11.10 上,使用 NVIDIA GeForce GTX 580,GPU 上有 3Gb 内存,使用专有驱动程序,版本 295.33
我错过了什么?