问题摘要:
我使用OpenGL glReadPixels来获取屏幕截图,但缓冲区保持不变。 如果我使用glGetError从最后一个函数中获取错误,它会返回0,好像一切都很好。
我已经彻底在网上进行了研究,并没有发现任何人面临这样的问题。
详细信息:
我正在使用CsGL.dll,它基本上只是将OpenGL包装到C#中,并且我已经使用GL进行了所需的初始化: 来自hWnd的DC,使用PixelFormatDescriptor选择DC的DC像素并将其设置为格式,为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");
尝试使用简单的小字节[]就像这样:
var bytes = new byte[10 * 10 * 3];
glReadPixels(0, 0, 10, 10, RGB, UNSIGNED_BYTE, bytes);
字节[]全为零。 我也尝试过更大尺寸的阵列(保持0,0,10,10),但仍无济于事。
在这两种情况下,结果都是一样的。 缓冲区根本不会改变,而glGetError调用在每次GL函数调用后返回0。
Back.bmp和Front.bmp都是全黑的。
请告诉我,我做错了什么? 感谢
答案 0 :(得分:3)
您是否正在尝试创建所呈现内容的屏幕截图,或者屏幕截图?
确保glReadPixels 仅适用于OpenGL帧缓冲区的内容。它不适合截取任何其他内容的屏幕截图(曾经有过一段时间,这是可能的,但自从合成窗口管理器出现以来,那些时代已经一去不复返了。)
因此,如果您尝试进行常规屏幕捕获, glReadPixels 是错误的方法。
但是,如果您尝试截取所呈现的内容,则必须确保在调用 glReadPixels 时,您呈现的上下文也处于活动状态。