OpenGL PixelBufferObject中的位图填充字节

OpenGL PixelBufferObject中的位图填充字节,opengl,opentk,opengl-4,Opengl,Opentk,Opengl 4,我有一个大小为3750x1407的位图,它作为位图加载到内存中,填充为2字节,因此它在内存中的长度为(3752*1407)字节。当使用像素缓冲区填充纹理时,我是否也需要复制填充字节,还是可以跳过它们 GL.BindTexture(TextureTarget.Texture2D, texId); GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboId[currentIndex]);

我有一个大小为3750x1407的位图,它作为位图加载到内存中,填充为2字节,因此它在内存中的长度为(3752*1407)字节。当使用像素缓冲区填充纹理时,我是否也需要复制填充字节,还是可以跳过它们

            GL.BindTexture(TextureTarget.Texture2D, texId);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboId[currentIndex]);

            GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, bitmap.Width, bitmap.Height, PixelFormat.Luminance,
               PixelType.UnsignedByte, IntPtr.Zero);

            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboId[nextIndex]);
            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
            ImageLockMode.ReadOnly, bitmap.PixelFormat);
            GL.ColorTable(ColorTableTarget.ColorTable, PixelInternalFormat.Luminance, _colorTable.Length, PixelFormat.Luminance, PixelType.Byte, new IntPtr(_colorTable[0]));

            IntPtr buf = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly);
            if (buf != IntPtr.Zero)
            {
              //---------------------------------------- Currently copying padding bytes--------------------------------------------- //
                memcpy(buf, bitmapData.Scan0, new UIntPtr((uint)(bitmapData.Stride * bitmap.Height)));
                GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer);
            }
            bitmap.UnlockBits(bitmapData);
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);

如果您正确地应用了这两个选项,则这两个选项都将起作用。您可以通过使用
glPixelStorei()
设置的一组
GL\u UNPACK.*
参数来控制行填充/大小

从问题和代码中使用的格式来看,您似乎有一个1字节/像素的格式。我的大部分答案也应该适用于其他格式,但我将在计算中使用它

此处关键的
GL\u UNPACK.*
参数有:

  • GL\u UNPACK\u对齐方式
    :以字节定义数据的行对齐方式。默认值为4。这意味着不是4字节倍数的行将填充到下一个4字节倍数
  • GL\u UNPACK\u ROW\u LENGTH
    :以像素为单位定义行大小。默认值为0,这是一个特殊值,指示将使用传递给
    glTex(Sub)Image2D()
    的宽度
填充输入数据 将填充输入数据存储在PBO中,数据的宽度为3752字节,其中前3750字节有效。由于3752是4的倍数,因此
GL\u UNPACK\u校准的默认值将适用于此数据

但是,由于纹理宽度仅为3750像素,而数据的宽度为3752,因此必须将行长度设置为数据的宽度:

glPixelStorei(GL_UNPACK_ROW_LENGTH, 3752);
对于
glTexSubImage2D()
中的宽度,仍将指定3750。之后不要忘记重置行长度

未添加的输入数据 如果在PBO中存储数据之前/同时删除填充,则PBO中的数据宽度现在为3750字节。因为这不是4的倍数,所以必须设置解包对齐,以防止数据被读取为3752字节/行。值
1
将避免任何对齐(
2
也适用于您的情况,因为您的行长度是2字节的倍数):


另一方面,PBO中的数据宽度现在与纹理宽度相同。因此,您不必费心设置
GL\u UNPACK\u ROW\u LENGTH
,因为默认值为0表示纹理宽度用于数据的宽度。

纹理的格式是什么?RGBA,即每像素4字节?@RetoKoradi否,它是每像素1字节。8bpp索引灰度。我尝试了(bitmap.Width*bitmap.Height)(3750*351)它仍然有效。但我没有使用glPixelStorei()。
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);