OpenTK从位图中获取像素字节数组

本文关键字:字节 字节数 数组 像素 获取 位图 OpenTK | 更新日期: 2023-09-27 18:28:53

我需要将一些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中做同样的操作。我的图像数据来自位图的一个实例。我尝试了以下方法:

        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)。

那么,如何从位图中获取字节数组呢?

更新:

与此同时,我得到了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倍的性能提升。

OpenTK从位图中获取像素字节数组

好的,所以解决方案在这里:将数据从IntPtr复制到IntPtr

在linux上测试。