Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将OpenGL视口复制到C#位图中_C#_Opengl_Opentk - Fatal编程技术网

如何将OpenGL视口复制到C#位图中

如何将OpenGL视口复制到C#位图中,c#,opengl,opentk,C#,Opengl,Opentk,我正在尝试将OpenGL(使用OpenTK)视口的内容复制到C#位图中。我正在使用以下代码: BitmapData data = bmp.LockBits(Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); GL.ReadPixels(0, 0, bmp.Width, bmp.Height, PixelFormat.Bgr, PixelType

我正在尝试将OpenGL(使用OpenTK)视口的内容复制到C#位图中。我正在使用以下代码:

BitmapData data = bmp.LockBits(Rectangle.FromLTRB(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
GL.ReadPixels(0, 0, bmp.Width, bmp.Height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0);
bmp.UnlockBits(data);
我在互联网上看到过类似的代码,在大多数情况下,它运行良好。但在模糊的情况下,当位图的宽度为几个特定值之一时,它不会。数据变量返回的步幅与宽度不匹配,结果是图像严重向左倾斜

还有其他人注意到这种行为吗?这是我正在做的事情,还是我需要知道一些解决方法

编辑: 根据Fiddler的建议,我已将代码修改为:

BitmapData data = bmp.LockBits(dest, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
GL.PushClientAttrib(ClientAttribMask.ClientPixelStoreBit);
GL.PixelStore(PixelStoreParameter.PackAlignment, 4);
GL.ReadPixels(0, 0, bmp.Width, bmp.Height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0);
GL.PopClientAttrib();
bmp.UnlockBits(data);
似乎没有什么不同。已经为PixelStore尝试了1、2、4和8的值,也尝试了使用相同的值进行对齐。这里还有其他设置吗?

请查看OpenGL wiki中的,特别是最后的“像素布局”部分

位图的布局和对齐方式必须与当前OpenGL像素传输参数相匹配。如果位图大小是四的倍数,它将匹配默认的像素传输参数,因此它看起来可以工作。如果调用或使用奇数大小的位图,则传输的数据将无效-导致您观察到的行为


这是OpenGL中的一个应用程序。

您正在使用OpenTK吗?陶?据我所知,这是锁具的正确行为。不能保证返回连续的数据块。ReadPixels要求块是连续的。所以在我看来,所有推荐此代码的地方都是错误的。或者至少,他们提倡的代码只在大部分时间有效。不过,我还没有找到任何人推荐一种不同的技术,或者承认这段代码可能不起作用。让我怀疑我是否遗漏了什么。
LockBits
返回指向内存块的指针,其形状由其参数定义。OpenGL可以处理由
锁位返回的任何形状,但必须对其布局进行说明。谢谢,Fiddler。你说的有道理,除了我能告诉你,OpenGL默认对齐为4字节。C#Bitmap.LockBits也默认为4字节对齐。所以看起来他们应该已经匹配了。此外,添加GL.PixelStore并为PackageAlignment(和UnpackaAlignment,只是为了确保)传递所有可能的值并没有帮助,但只会使问题变得更糟。如果您可以创建一个复制此问题的小测试用例,这将非常有帮助。您提到这只发生在特定的尺寸上-它们有什么共同点?最后,我会尝试使用
PixelFormat.Format32bppArgb
PixelFormat.Bgra
看看这是否有什么不同。我暂时解决了我的问题,强制位图宽度始终是4的倍数。不过,这并不是一个最佳的解决方案,我真的很想知道我做错了什么,所以我将编写一个最小的测试用例。可能需要一两天的时间。谢谢你的帮助和建议。