после счастливого использования PyOpenGL в течение некоторого времени я серьезно застрял. Я работаю над пакетом Python, который позволяет мне использовать шейдеры GLSL и программы OpenCL для обработки изображений, используя текстуры в качестве стандартизированного способа получения моих данных в шейдерах GLSL и программах OpenCL и из них.
Все работает, за исключением того, что мне не удается скопировать текстуру в pbo (объект пиксельного буфера). Я использую pbo для получения данных текстуры в/из OpenCL, и это хорошо и быстро работает в PyOpenCL: я могу скопировать вывод OpenCL из его pbo в текстуру и отобразить ее, а также я могу загрузить данные из процессора в пбо. Но я безнадежно застрял, пытаясь заполнить свой pbo текстурными данными, уже находящимися в графическом процессоре, что мне нужно сделать, чтобы загрузить мои изображения, созданные шейдерами GLSL, в OpenCL для дальнейшей обработки.
Я читал о двух способах сделать это: вариант 1 связывает pbo, связывает текстуру и использует glGetTexImage() вариант 2 прикрепляет текстуру к объекту кадрового буфера, связывает fbo и pbo и использует glReadPixels()
Я также читал, что версии glReadPixels() и glGetTexImage() для PyOpenGL имеют проблемы с нулевыми указателями, которые следует использовать при наличии связанного pbo, поэтому по этой причине я использую варианты OpenGL.raw.GL.
Но в обоих этих случаях я получаю сообщение об ошибке «Недопустимая операция», и я действительно не вижу, что я делаю неправильно. Ниже приведены две версии метода load_texture() моего класса pixelbuffer Python, надеюсь, я не слишком их урезал...
вариант 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 на 1024, 4 плоскости, 1 байт на плоскость, так как это беззнаковые целые числа. Это отлично работает при передаче данных пикселей с хоста.
Также я использую Kubuntu 11.10, использую NVIDIA GeForce GTX 580 с 3 ГБ памяти на графическом процессоре, использую проприетарный драйвер версии 295.33.
что мне не хватает?