从OpenGL glReadPixels获取数据(使用Pyglet)

时间:2008-12-15 07:30:59

标签: python opengl graphics pyglet glreadpixels

我在应用程序中使用Python中的Pyglet(和OpenGL),我正在尝试使用glReadPixels来获取一组像素的RGBA值。我的理解是OpenGL将数据作为打包整数返回,因为它是如何存储在硬件上的。然而,出于显而易见的原因,我想将其变为正常的工作格式。根据一些阅读,我提出了这个问题:http://dpaste.com/99206/,但是它失败并带有IndexError。我该怎么做呢?

5 个答案:

答案 0 :(得分:4)

首先必须创建一个正确类型的数组,然后将其传递给glReadPixels:

a = (GLuint * 1)(0)
glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)

要测试它,请在Pyglet“opengl.py”示例中插入以下内容:

@window.event
def on_mouse_press(x, y, button, modifiers):
    a = (GLuint * 1)(0)
    glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_INT, a)
    print a[0]

现在,只要点击应用程序窗口中的某个位置,就会看到鼠标光标下像素的颜色代码。

答案 1 :(得分:1)

你可以使用PIL库,这是我用来捕获这样一个图像的代码片段:

    buffer = gl.glReadPixels(0, 0, width, height, gl.GL_RGB, 
                             gl.GL_UNSIGNED_BYTE)
    image = Image.fromstring(mode="RGB", size=(width, height), 
                             data=buffer)
    image = image.transpose(Image.FLIP_TOP_BOTTOM)

我想包括alpha通道应该非常简单(可能只是用RGBA替换RGB,但我没有尝试过)。

编辑:我不知道pyglet OpenGL API与PyOpenGL不同。我想必须改变上面的代码,使用缓冲区作为第七个参数(符合pythonic pyglet风格较少)。

答案 2 :(得分:1)

我能够使用glReadPixels(...)获取整个帧缓冲区,然后使用PIL写出文件:

# Capture image from the OpenGL buffer
buffer = ( GLubyte * (3*window.width*window.height) )(0)
glReadPixels(0, 0, window.width, window.height, GL_RGB, GL_UNSIGNED_BYTE, buffer)

# Use PIL to convert raw RGB buffer and flip the right way up
image = Image.fromstring(mode="RGB", size=(window.width, window.height), data=buffer)     
image = image.transpose(Image.FLIP_TOP_BOTTOM)

# Save image to disk
image.save('jpap.png')

我对alpha不感兴趣,但我确信你可以轻松添加它。

我被迫使用glReadPixels(...)而不是Pyglet代码

pyglet.image.get_buffer_manager().get_color_buffer().save('jpap.png')

因为使用save(...)的输出与我在Window中看到的输出不同。 (错过多重采样缓冲区?)

答案 3 :(得分:0)

如果您阅读了链接到的代码段,您可以理解获取“正常”值的最简单方法就是以正确的顺序访问数组。
该片段看起来应该可以完成这项工作。如果没有,请调试它,看看问题是什么。

答案 4 :(得分:0)

进一步检讨我相信我的原始代码是基于一些特定的C代码,因为数组只是一个指针,所以我使用指针算法可以得到特定的字节,显然不会转换为Python。有没有人如何使用不同的方法提取数据(我假设它只是一点点移位数据)。