我需要将一些OpenGL代码移植到C#OpenTK。 这是我从C ++中的像素数组更新映射的PBO的块:
GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
if(ptr)
{
memcpy(ptr,imageInfo.Data,IMG_DATA_SIZE);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
我需要在OpenTK中做同样的事情。我的图像数据来自Bitmap的一个实例。 我尝试了以下方法:
IntPtr ptr = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
if(ptr != IntPtr.Zero)
{
BitmapData data = updateColorMap.LockBits(new System.Drawing.Rectangle(0, 0, updateColorMap.Width, updateColorMap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Marshal.Copy(data.Scan0, 0, ptr, IMG_DATA_SIZE);
}
但是Marshal.Copy要求第一个参数是byte []类型。我没有找到如何从BitmapData中检索它。它只返回IntPtr(data.Scan0)。
那么如何从Bitmap中获取字节数组呢?
更新
与此同时,我得到了OpenTK论坛的帮助,他们建议改为:
unsafe
{
GL.BufferData(BufferTarget.PixelUnpackBuffer, new IntPtr(IMG_DATA_SIZE), IntPtr.Zero, BufferUsageHint.StreamDraw);
byte* ptr = (byte*)GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
if (ptr != null)
{
BitmapData data = updateDepthMap.LockBits(new System.Drawing.Rectangle(0, 0, updateDepthMap.Width, updateDepthMap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
byte* scan0 = (byte*)data.Scan0.ToPointer();
for (int i = 0; i < IMG_DATA_SIZE; ++i)
{
*ptr = *scan0;
++ptr;
++scan0;
}
updateDepthMap.UnlockBits(data);
GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
}
}//unsafe
现在,这可行,但可怕的慢!常规纹理更新运行速度比此快2倍 错误的异步PBO传输应该加快纹理上传。在我的C ++版本中,PBO上传导致几乎2倍的性能提升。