Get data from OpenGL glReadPixels (using Pyglet)

I am using Pyglet (and OpenGL) in Python in an application, I am trying to use glReadPixels to get RGBA values ​​for a set of pixels. I understand that OpenGL returns data as packed integers since it is stored in hardware. However, for obvious reasons, I would like to get it in its normal format to work. Based on some readings I came up with the following: http://dpaste.com/99206/ , however it doesn't work with IndexError. How can i do this?

0


source to share


5 answers


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, paste the following into 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]

      

You should now see the color code for the pixel under the mouse cursor when you click anywhere in the application window.

+4


source


You can use the PIL library, here is the code snippet I am using to capture an image like this:

    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 the alpha should be pretty straight forward (maybe just replacing RGB with RGBA, but I haven't tried that).

Edit: I didn't know that the OpenGL API of pyglet is different from PyOpenGL. My guess is that the above code needs to be modified to use a buffer as the seventh argument (to match the less stylish pigment piglet).

+1


source


I was able to get the entire framebuffer with glReadPixels(...)

, then used PIL to write 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 wasn't interested in alpha, but I'm sure you can add it easily.

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 was save(...)

not identical to what I saw in the window. (Missing multisampling buffers?)

+1


source


If you are reading the snippet you are referencing, you can understand that the simplest and most efficient way to get "normal" values ​​is simply to access the array in the correct order.
This snippet looks like it should do the job. If it doesn't, debug it and see what the problem is.

0


source


In a further review, I believe my original code was based on some C code that worked because an array is just a pointer, so I am using pointer arithmetic, which you can get in certain bytes, which obviously doesn't translate to Python. Anyone how to retrieve this data using a different method (I'm guessing it's just a matter of biasing the data).

0


source







All Articles