问题总结:
我使用 OpenGL glReadPixels 来获取屏幕截图,但缓冲区没有改变。如果我使用 glGetError 从最后一个函数中获取错误,它返回 0,好像一切都很好。
我已经在网上进行了彻底的研究,没有发现任何人面临这样的问题。
详细说明:
我正在使用 CsGL.dll,它基本上只是将 OpenGL 包装到 C#,并且我已经进行了使用 GL 所需的初始化:来自 hWnd 的 DC,ChoosePixelFormat for DC 使用 PixelFormatDescriptor 并将其设置为它的格式,为 DC 创建 RC并调用 wglMakeCurrent(RC, DC)。
请注意,我正在为 Windows API 函数使用简单的包装器。这是我使用的初始化代码:
public unsafe void Init(IntPtr hWnd)
{
this.DC = (IntPtr)User.GetDC(this.HWnd = hWnd);
var pfd = new PIXELFORMATDESCRIPTOR();
var sizeOf = Marshal.SizeOf(pfd);
Kernel.ZeroMemory(new IntPtr(&pfd), sizeOf);
pfd.nSize = (short)sizeOf;
pfd.nVersion = 1;
pfd.dwFlags = (int)(PixelFormatDescriptorFlagsEnum.PFD_DRAW_TO_WINDOW |
PixelFormatDescriptorFlagsEnum.PFD_SUPPORT_OPENGL |
PixelFormatDescriptorFlagsEnum.PFD_DOUBLEBUFFER);
pfd.iPixelType = PIXELFORMATDESCRIPTOR.PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PIXELFORMATDESCRIPTOR.PFD_MAIN_PLANE;
var iFormat = GDI.ChoosePixelFormat(this.DC, ref pfd);
GDI.SetPixelFormat(this.DC, iFormat, ref pfd);
this.RC = wglCreateContext(this.DC);
wglMakeCurrent(this.DC, this.RC);
}
我已将 User.GetForegroundWindow() 作为 hWnd 发送。
在此初始化之后,我尝试将屏幕截图放入图像中(并且我还尝试将其读入一个简单的字节数组)
glReadPixels 用法的简短伪代码:
var area = new Rectangle(0, 0, 100, 100);
var bmp = new Bitmap(area.Width, area.Height);
var data = bmp.LockBits(area, ILM.WriteOnly, PF.24bppRgb);
glReadBuffer(BACK);
glReadPixels(0, 0, area.Width, area.Height, BGR_EXT /*also tried RGB and RGBA*/, UNSIGNED_BYTE, data.Scan0);
bmp.UnlockBits(data);
bmp.Save(@"C:\Back.bmp");
data = bmp.LockBits(area, ILM.WriteOnly, PF.24bppRgb);
glReadBuffer(FRONT);
glReadPixels(0, 0, area.Width, area.Height, BGR_EXT /*also tried RGB and RGBA*/, UNSIGNED_BYTE, data.Scan0);
bmp.UnlockBits(data);
bmp.Save(@"C:\Front.bmp");
用一个简单而小的 byte[] 尝试它是这样完成的:
var bytes = new byte[10 * 10 * 3];
glReadPixels(0, 0, 10, 10, RGB, UNSIGNED_BYTE, bytes);
并且 byte[] 都是零。我也尝试过使用更大尺寸的数组(保持 0、0、10、10),但仍然无济于事。
在这两种情况下,结果是相同的。缓冲区根本没有改变,而 glGetError 调用在每次 GL 函数调用后返回 0。
Back.bmp 和 Front.bmp 都是全黑的。
请告诉我我做错了什么?谢谢