Get Data from OpenGL glReadPixels(using Pyglet)

…衆ロ難τιáo~ 提交于 2019-12-12 05:36:40

问题


I'm using Pyglet(and OpenGL) in Python on an application, I'm trying to use glReadPixels to get the RGBA values for a set of pixels. It's my understanding that OpenGL returns the data as packed integers, since that's how they are stored on the hardware. However for obvious reasons I'd like to get it into a normal format for working with. Based on some reading I've come up with this: http://dpaste.com/99206/ , however it fails with an IndexError. How would I go about doing this?


回答1:


You must first create an array of the correct type, then pass it to glReadPixels:

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

To test this, insert the following in the Pyglet "opengl.py" example:

@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]

Now you should see the color code for the pixel under the mouse cursor whenever you click somewhere in the app window.




回答2:


You can use the PIL library, here is a code snippet which I use to capture such an image:

    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)

I guess including the alpha channel should be pretty straight forward (probably just replacing RGB with RGBA, but I have not tried that).

Edit: I wasn't aware that the pyglet OpenGL API is different from the PyOpenGL one. I guess one has to change the above code to use the buffer as the seventh argument (conforming to the less pythonic pyglet style).




回答3:


I was able to obtain the entire frame buffer using glReadPixels(...), then used the PIL to write out to a file:

# 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')

I was not interested in alpha, but I'm sure you could easily add it in.

I was forced to use glReadPixels(...), instead of the Pyglet code

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

because the output using save(...) was not identical to what I saw in the Window. (Multisampling buffers missed?)




回答4:


If you read the snippet you link to you can understand that the simplest and way to get the "normal" values is just accessing the array in the right order.
That snippet looks like it's supposed to do the job. If it doesn't, debug it and see what's the problem.




回答5:


On further review I believe my original code was based on some C specific code that worked because the array is just a pointer, so my using pointer arithmetic you could get at specific bytes, that obviously doesn't translate to Python. Does anyone how to extract that data using a different method(I assume it's just a matter of bit shifting the data).



来源:https://stackoverflow.com/questions/367684/get-data-from-opengl-glreadpixelsusing-pyglet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!