问题
I've rendered the scene as solid colours to an FBO and stored it in a texture 2D, shown below.
Now I need to access the RGB values of a particular pixel co-ordinate, or texture-co-ordinate, either is helpful.
I understand I need to use GL.ReadPixels
but have only succeeded creating a bitmap first and doing this every frame creates performance issues.
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, FBO);
GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, Texture.GetTextureID("FBOtexture"), 0);
Bitmap b = new Bitmap(Width, Height);
var bits = b.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.ReadPixels(0, 0, Width, Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bits.Scan0);
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);
b.UnlockBits(bits);
How can I access the data directly?
回答1:
For now, this is working
int pixelData = 0;
GL.ReadPixels (fboWidth / 2, fboHeight / 2, 1, 1, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.UnsignedByte, ref pixelData);
int red = Color.FromArgb(pixelData).R;
int green = Color.FromArgb(pixelData).G;
int blue = Color.FromArgb(pixelData).B;
But there are notable drawbacks.
As described in the PBO article linked by j-p, glReadPixels()
blocks the pipeline and waits until all pixel data is transferred, only then returning control to the application. In my program, and on my machine, that stall is noticeable.
The long term solution seems to be the Pixel Buffer Object which reduces the overhead by providing asynchronous data transfer between GL and the client. I'll amend this answer when I have something to show.
来源:https://stackoverflow.com/questions/36687524/opengl-access-rgb-pixel-data-in-a-stored-texture2d