blg.glReadPixels doesn't work in modal operator in 2.91

As BGL is slowly getting deprecated (https://developer.blender.org/T80730), I thought bgl.glReadPixels was not usable anymore in 2.91 (it only returns black).

x,y = 1000, 1000  # Sample position in pixels
buf = bgl.Buffer(bgl.GL_FLOAT, 3):
bgl.glReadPixels(x, y, 1, 1, bgl.GL_RGB, bgl.GL_FLOAT, buf)

However I noticed that this function works totally fine if added to the draw_handler, but doesn’t work in a modal operator anymore (2.90.1 doesn’t have the issue).

Any idea how to work around that problem?

EDIT: I added the handler through a modal and noticed that x,y = event.mouse_region_x, event.mouse_region_y didn’t update the mouse position, unlike event.mouse_x. Which might be the cause of the glReadPixels issue.

True! I have an application I made over 2.90 using glReadPixels to sample colors and now it doesn’t work anymore in 2.91! I don’t have issue with the mouse region position thought.
We should report this at least so devs have it into consideration in case they skipped it as they are moving things to Vulkan…

EDIT:
However, If I run this code within the script editor inside Blender…

# Reads 1 pixel color.
import bgl
WIDTH =1
HEIGHT  = 1
X = 10
Y = 10
buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
bgl.glReadPixels(X, Y, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
print(buffer.to_list())

It works just fine!

So I guess If it’s an issue using it with modal or draw handler.

So I got it to work with a modal that adds a draw handler. However in 2.90.1 there was no problem to use event.mouse_x and y with bgl.glReadPixels, but in 2.91 I noticed that the sampling location was offset. event.mouse_region_x and y didn’t work (didn’t update as I moved the mouse), so I went for this:

x,y = event.mouse_x, event.mouse_y
        
for area in bpy.context.screen.areas:
    if area.type=='VIEW_3D':
        corner_x = area.x
        corner_y = area.y
        header_height = area.regions[0].height
        lpanel_width = area.regions[2].width

x -= corner_x + lpanel_width
y -= corner_y + header_height

Also, glReadPixels used to work fine in the Image / Node editor, now it just returns black. Seems that before it was properly sampling anything in the UI and now it’s limited to the 3D view.

1 Like