
GL.ReadPixels broken?
Posted Tuesday, 6 October, 2009 - 15:15 by Inertia inI'm toying with an implementation of the picking technique suggested here.
However it appears that this code will always return 4x zero, although the buffer was previously cleared with 4x 1f.
// after bind FBO, draw obj, while FBO is bound and readbuffer set to correct color attachment: Byte4 Pixel = new Byte4(); GL.ReadPixels<Byte4>(Mouse.X, FBO_height-Mouse.Y, 1, 1, PixelFormat.Rgba, PixelType.UnsignedByte, ref Pixel); uint SelectedTriangle = Pixel.ToUInt32();
this code does prove that there's neither a problem with the FBO nor the attachment:
// after bind FBO, draw obj, unbind FBO GL.Enable(EnableCap.Texture2D); GL.BindTexture(Target, ColorAttachment); Byte4[] Tex = new Byte4[FBO_width * FBO_height]; GL.GetTexImage<Byte4>(Target, 0, PixelFormat.Rgba, PixelType.UnsignedByte, Tex); GL.BindTexture(Target, 0); GL.Disable(EnableCap.Texture2D); SelectedTriangle = Tex[(FBO_height-Mouse.Y)*FBO_width+Mouse.X].ToUInt32();
The later is a huge waste of memory (and prone to indexing out of array bounds) but it gives me the correct triangle index. GL.ReadPixels will never return any values besides zeros.
I've taken a look at svn and the ReadPixels pinning looks ok, besides that it should use "out" not "ref". Any ideas what's wrong with this?


Comments
Re: GL.ReadPixels broken?
ReadPixels is implemented pretty much identically to GetTexImage, GetBufferSubData and other functions that are known to work correctly. It's possible that some bug has crept in the implementation (lack of unit tests + haven't used it for a while), but as you said the implementation in SVN looks correct.
Some ideas:
The parameter needs to be
ref- notout- because the user is responsible for allocating memory, rather than OpenGL.Re: GL.ReadPixels broken?
I've looked into GL.PixelTransfer, GL.PixelStore and GL.PixelMap, but none of them appears to be the culprit. Requesting a Vector4 instead of Byte4 did not help either (it is my understanding that OpenGL will convert data to your requested format/type regardless of what internal representation it uses anyways).
Any help with this would be much appreciated, so far the best workaround I can think of is creating a 1x1 texture and copying the texel in question to it, then GL.GetTexImage the 1 texel for analysis. But I'd prefer to simply use GL.ReadPixels and drop FBO from the example application altogether.
Re: GL.ReadPixels broken?
(for completeness) This works:
Re: GL.ReadPixels broken?
Ok, your last post uncovered the cause. This is indeed a bug that was introduced along with the generic wrappers in version 0.9.6. The reason why it went unnoticed for so long is that it does not affect any generic array overloads (which are much more common than the generic ref/out overloads).
Edit: filed as issue #1240: Generic ref and out wrappers do not copy results to the reference parameter.
Re: GL.ReadPixels broken?
Is this issue exist still?